feat: add multi-environment deployment with Gitea Actions & Dokploy
- Update Gitea workflow to build dev/staging/main branches
- Create environment-specific docker-compose files
- docker-compose.dev.yml (pulls dev image)
- docker-compose.staging.yml (pulls staging image)
- docker-compose.prod.yml (pulls latest image)
- docker-compose.local.yml (builds locally for development)
- Remove generic docker-compose.yml (replaced by env-specific files)
- Update .dockerignore to exclude docs/ and .gitea/ from production images
- Add comprehensive deployment guide (docs/DOKPLOY_DEPLOYMENT.md)
Image Tags:
- dev branch → :dev
- staging branch → :staging
- main branch → :latest
- All branches → :{branch}-{sha}
Benefits:
- Separate deployments for dev/staging/prod
- Automated CI/CD via Gitea Actions + Dokploy webhooks
- Leaner production images (excludes dev tools/docs)
- Local development support (docker-compose.local.yml)
- Rollback support via SHA-tagged images
This commit is contained in:
@@ -13,6 +13,7 @@ node_modules
|
|||||||
# Documentation
|
# Documentation
|
||||||
*.md
|
*.md
|
||||||
!README.md
|
!README.md
|
||||||
|
docs
|
||||||
|
|
||||||
# IDE
|
# IDE
|
||||||
.vscode
|
.vscode
|
||||||
@@ -49,6 +50,7 @@ docker-compose*.yml
|
|||||||
# CI/CD
|
# CI/CD
|
||||||
.github
|
.github
|
||||||
.gitlab-ci.yml
|
.gitlab-ci.yml
|
||||||
|
.gitea
|
||||||
|
|
||||||
# Scripts
|
# Scripts
|
||||||
scripts
|
scripts
|
||||||
|
|||||||
@@ -3,10 +3,14 @@ name: Build and Push Docker Image
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
|
- dev
|
||||||
|
- staging
|
||||||
- main
|
- main
|
||||||
paths:
|
paths:
|
||||||
- 'src/**'
|
- 'src/**'
|
||||||
|
- 'client/**'
|
||||||
- 'Dockerfile'
|
- 'Dockerfile'
|
||||||
|
- 'package.json'
|
||||||
- '.gitea/workflows/**'
|
- '.gitea/workflows/**'
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
@@ -41,8 +45,10 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
tags: |
|
tags: |
|
||||||
type=raw,value=latest,enable={{is_default_branch}}
|
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
|
||||||
type=sha,prefix=
|
type=raw,value=dev,enable=${{ github.ref == 'refs/heads/dev' }}
|
||||||
|
type=raw,value=staging,enable=${{ github.ref == 'refs/heads/staging' }}
|
||||||
|
type=sha,prefix={{branch}}-
|
||||||
|
|
||||||
- name: Build and push Docker image
|
- name: Build and push Docker image
|
||||||
uses: docker/build-push-action@v5
|
uses: docker/build-push-action@v5
|
||||||
|
|||||||
38
docker-compose.dev.yml
Normal file
38
docker-compose.dev.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
ai-stack-deployer:
|
||||||
|
image: git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:dev
|
||||||
|
container_name: ai-stack-deployer-dev
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=development
|
||||||
|
- PORT=3000
|
||||||
|
- HOST=0.0.0.0
|
||||||
|
- DOKPLOY_URL=${DOKPLOY_URL}
|
||||||
|
- DOKPLOY_API_TOKEN=${DOKPLOY_API_TOKEN}
|
||||||
|
- STACK_DOMAIN_SUFFIX=${STACK_DOMAIN_SUFFIX:-ai.flexinit.nl}
|
||||||
|
- STACK_IMAGE=${STACK_IMAGE:-git.app.flexinit.nl/flexinit/agent-stack:latest}
|
||||||
|
- RESERVED_NAMES=${RESERVED_NAMES:-admin,api,www,root,system,test,demo,portal}
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD",
|
||||||
|
"bun",
|
||||||
|
"--eval",
|
||||||
|
"fetch('http://localhost:3000/health').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))",
|
||||||
|
]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
start_period: 5s
|
||||||
|
networks:
|
||||||
|
- ai-stack-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ai-stack-network:
|
||||||
|
driver: bridge
|
||||||
43
docker-compose.local.yml
Normal file
43
docker-compose.local.yml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
ai-stack-deployer:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: ai-stack-deployer-local
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=development
|
||||||
|
- PORT=3000
|
||||||
|
- HOST=0.0.0.0
|
||||||
|
- DOKPLOY_URL=${DOKPLOY_URL}
|
||||||
|
- DOKPLOY_API_TOKEN=${DOKPLOY_API_TOKEN}
|
||||||
|
- STACK_DOMAIN_SUFFIX=${STACK_DOMAIN_SUFFIX:-ai.flexinit.nl}
|
||||||
|
- STACK_IMAGE=${STACK_IMAGE:-git.app.flexinit.nl/flexinit/agent-stack:latest}
|
||||||
|
- RESERVED_NAMES=${RESERVED_NAMES:-admin,api,www,root,system,test,demo,portal}
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD",
|
||||||
|
"bun",
|
||||||
|
"--eval",
|
||||||
|
"fetch('http://localhost:3000/health').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))",
|
||||||
|
]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
start_period: 5s
|
||||||
|
networks:
|
||||||
|
- ai-stack-network
|
||||||
|
volumes:
|
||||||
|
- ./src:/app/src:ro
|
||||||
|
- ./client:/app/client:ro
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ai-stack-network:
|
||||||
|
driver: bridge
|
||||||
@@ -1,11 +1,8 @@
|
|||||||
version: "3.8"
|
version: "3.8"
|
||||||
|
|
||||||
# ***NEVER FORGET THE PRINCIPLES***
|
|
||||||
services:
|
services:
|
||||||
ai-stack-deployer:
|
ai-stack-deployer:
|
||||||
build:
|
image: git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:latest
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
container_name: ai-stack-deployer
|
container_name: ai-stack-deployer
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
38
docker-compose.staging.yml
Normal file
38
docker-compose.staging.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
ai-stack-deployer:
|
||||||
|
image: git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:staging
|
||||||
|
container_name: ai-stack-deployer-staging
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=staging
|
||||||
|
- PORT=3000
|
||||||
|
- HOST=0.0.0.0
|
||||||
|
- DOKPLOY_URL=${DOKPLOY_URL}
|
||||||
|
- DOKPLOY_API_TOKEN=${DOKPLOY_API_TOKEN}
|
||||||
|
- STACK_DOMAIN_SUFFIX=${STACK_DOMAIN_SUFFIX:-ai.flexinit.nl}
|
||||||
|
- STACK_IMAGE=${STACK_IMAGE:-git.app.flexinit.nl/flexinit/agent-stack:latest}
|
||||||
|
- RESERVED_NAMES=${RESERVED_NAMES:-admin,api,www,root,system,test,demo,portal}
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test:
|
||||||
|
[
|
||||||
|
"CMD",
|
||||||
|
"bun",
|
||||||
|
"--eval",
|
||||||
|
"fetch('http://localhost:3000/health').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))",
|
||||||
|
]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
start_period: 5s
|
||||||
|
networks:
|
||||||
|
- ai-stack-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ai-stack-network:
|
||||||
|
driver: bridge
|
||||||
401
docs/DOKPLOY_DEPLOYMENT.md
Normal file
401
docs/DOKPLOY_DEPLOYMENT.md
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
# Dokploy Deployment Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This project uses **Gitea Actions** to build Docker images and **Dokploy** to deploy them. Each branch (dev, staging, main) has its own:
|
||||||
|
- Docker image tag
|
||||||
|
- Docker Compose file
|
||||||
|
- Dokploy application
|
||||||
|
- Domain
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────┐
|
||||||
|
│ Gitea │
|
||||||
|
│ (Source) │
|
||||||
|
└──────┬──────┘
|
||||||
|
│ push event
|
||||||
|
↓
|
||||||
|
┌─────────────┐
|
||||||
|
│ Gitea │
|
||||||
|
│ Actions │ Builds Docker images
|
||||||
|
│ (CI/CD) │ Tags: dev, staging, latest
|
||||||
|
└──────┬──────┘
|
||||||
|
│
|
||||||
|
↓
|
||||||
|
┌─────────────┐
|
||||||
|
│ Gitea │
|
||||||
|
│ Registry │ git.app.flexinit.nl/oussamadouhou/ai-stack-deployer
|
||||||
|
└──────┬──────┘
|
||||||
|
│ webhook (push event)
|
||||||
|
↓
|
||||||
|
┌─────────────┐
|
||||||
|
│ Dokploy │ Pulls & deploys image
|
||||||
|
│ (Deploy) │ Uses docker-compose.{env}.yml
|
||||||
|
└─────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Branch Strategy
|
||||||
|
|
||||||
|
| Branch | Image Tag | Compose File | Domain (suggested) |
|
||||||
|
|-----------|-----------|----------------------------|------------------------------|
|
||||||
|
| `dev` | `dev` | `docker-compose.dev.yml` | portal-dev.ai.flexinit.nl |
|
||||||
|
| `staging` | `staging` | `docker-compose.staging.yml` | portal-staging.ai.flexinit.nl |
|
||||||
|
| `main` | `latest` | `docker-compose.prod.yml` | portal.ai.flexinit.nl |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gitea Actions Workflow
|
||||||
|
|
||||||
|
**File**: `.gitea/workflows/docker-publish.yaml`
|
||||||
|
|
||||||
|
**Triggers**: Push to `dev`, `staging`, or `main` branches
|
||||||
|
|
||||||
|
**Builds**:
|
||||||
|
```yaml
|
||||||
|
dev branch → git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:dev
|
||||||
|
staging branch → git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:staging
|
||||||
|
main branch → git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
**Also creates SHA tags**: `{branch}-{short-sha}`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Docker Compose Files
|
||||||
|
|
||||||
|
### `docker-compose.dev.yml`
|
||||||
|
- Pulls: `git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:dev`
|
||||||
|
- Environment: `NODE_ENV=development`
|
||||||
|
- Container name: `ai-stack-deployer-dev`
|
||||||
|
|
||||||
|
### `docker-compose.staging.yml`
|
||||||
|
- Pulls: `git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:staging`
|
||||||
|
- Environment: `NODE_ENV=staging`
|
||||||
|
- Container name: `ai-stack-deployer-staging`
|
||||||
|
|
||||||
|
### `docker-compose.prod.yml`
|
||||||
|
- Pulls: `git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:latest`
|
||||||
|
- Environment: `NODE_ENV=production`
|
||||||
|
- Container name: `ai-stack-deployer`
|
||||||
|
|
||||||
|
### `docker-compose.local.yml`
|
||||||
|
- **Builds locally** (doesn't pull from registry)
|
||||||
|
- For local development only
|
||||||
|
- Includes volume mounts for hot reload
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Setting Up Dokploy
|
||||||
|
|
||||||
|
### Step 1: Create Dev Application
|
||||||
|
|
||||||
|
1. **In Dokploy UI**, create new application:
|
||||||
|
- **Name**: `ai-stack-deployer-dev`
|
||||||
|
- **Type**: Docker Compose
|
||||||
|
- **Repository**: `ssh://git@git.app.flexinit.nl:22222/oussamadouhou/ai-stack-deployer.git`
|
||||||
|
- **Branch**: `dev`
|
||||||
|
- **Compose File**: `docker-compose.dev.yml`
|
||||||
|
|
||||||
|
2. **Configure Domain**:
|
||||||
|
- Add domain: `portal-dev.ai.flexinit.nl`
|
||||||
|
- Enable SSL (via Traefik wildcard cert)
|
||||||
|
|
||||||
|
3. **Set Environment Variables**:
|
||||||
|
```env
|
||||||
|
DOKPLOY_URL=http://10.100.0.20:3000
|
||||||
|
DOKPLOY_API_TOKEN=<your-token>
|
||||||
|
STACK_DOMAIN_SUFFIX=ai.flexinit.nl
|
||||||
|
STACK_IMAGE=git.app.flexinit.nl/flexinit/agent-stack:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Configure Webhook**:
|
||||||
|
- Event: **Push**
|
||||||
|
- Branch: `dev`
|
||||||
|
- This will auto-deploy when you push to dev branch
|
||||||
|
|
||||||
|
5. **Deploy**
|
||||||
|
|
||||||
|
### Step 2: Create Staging Application
|
||||||
|
|
||||||
|
Repeat Step 1 with these changes:
|
||||||
|
- **Name**: `ai-stack-deployer-staging`
|
||||||
|
- **Branch**: `staging`
|
||||||
|
- **Compose File**: `docker-compose.staging.yml`
|
||||||
|
- **Domain**: `portal-staging.ai.flexinit.nl`
|
||||||
|
- **Webhook Branch**: `staging`
|
||||||
|
|
||||||
|
### Step 3: Create Production Application
|
||||||
|
|
||||||
|
Repeat Step 1 with these changes:
|
||||||
|
- **Name**: `ai-stack-deployer-prod`
|
||||||
|
- **Branch**: `main`
|
||||||
|
- **Compose File**: `docker-compose.prod.yml`
|
||||||
|
- **Domain**: `portal.ai.flexinit.nl`
|
||||||
|
- **Webhook Branch**: `main`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Deployment Workflow
|
||||||
|
|
||||||
|
### Development Cycle
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Make changes on dev branch
|
||||||
|
git checkout dev
|
||||||
|
# ... make changes ...
|
||||||
|
git commit -m "feat: add new feature"
|
||||||
|
git push origin dev
|
||||||
|
|
||||||
|
# 2. Gitea Actions automatically builds dev image
|
||||||
|
# 3. Dokploy webhook triggers and deploys to portal-dev.ai.flexinit.nl
|
||||||
|
|
||||||
|
# 4. Test on dev environment
|
||||||
|
curl https://portal-dev.ai.flexinit.nl/health
|
||||||
|
|
||||||
|
# 5. When ready, merge to staging
|
||||||
|
git checkout staging
|
||||||
|
git merge dev
|
||||||
|
git push origin staging
|
||||||
|
|
||||||
|
# 6. Gitea Actions builds staging image
|
||||||
|
# 7. Dokploy deploys to portal-staging.ai.flexinit.nl
|
||||||
|
|
||||||
|
# 8. Final testing on staging, then merge to main
|
||||||
|
git checkout main
|
||||||
|
git merge staging
|
||||||
|
git push origin main
|
||||||
|
|
||||||
|
# 9. Gitea Actions builds production image (latest)
|
||||||
|
# 10. Dokploy deploys to portal.ai.flexinit.nl
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Image Tags Explained
|
||||||
|
|
||||||
|
Each push creates multiple tags:
|
||||||
|
|
||||||
|
### Example: Push to `dev` branch (commit `abc1234`)
|
||||||
|
|
||||||
|
Gitea Actions creates:
|
||||||
|
```
|
||||||
|
git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:dev ← Latest dev
|
||||||
|
git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:dev-abc1234 ← Specific commit
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example: Push to `main` branch (commit `xyz5678`)
|
||||||
|
|
||||||
|
Gitea Actions creates:
|
||||||
|
```
|
||||||
|
git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:latest ← Latest production
|
||||||
|
git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:main-xyz5678 ← Specific commit
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why?**
|
||||||
|
- Branch tags (`dev`, `staging`, `latest`) always point to latest build
|
||||||
|
- SHA tags allow you to rollback to specific commits if needed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Rollback Strategy
|
||||||
|
|
||||||
|
### Quick Rollback in Dokploy
|
||||||
|
|
||||||
|
If a deployment breaks, you can quickly rollback:
|
||||||
|
|
||||||
|
1. **In Dokploy UI**, go to the application
|
||||||
|
2. **Edit** the docker-compose file
|
||||||
|
3. Change the image tag to a previous SHA:
|
||||||
|
```yaml
|
||||||
|
image: git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:main-abc1234
|
||||||
|
```
|
||||||
|
4. **Redeploy**
|
||||||
|
|
||||||
|
### Manual Rollback via Git
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Find the last working commit
|
||||||
|
git log --oneline
|
||||||
|
|
||||||
|
# Revert to that commit
|
||||||
|
git revert HEAD # or git reset --hard <commit-sha>
|
||||||
|
|
||||||
|
# Push to trigger rebuild
|
||||||
|
git push origin main
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Local Development
|
||||||
|
|
||||||
|
### Using docker-compose.local.yml
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build and run locally
|
||||||
|
docker-compose -f docker-compose.local.yml up -d
|
||||||
|
|
||||||
|
# View logs
|
||||||
|
docker-compose -f docker-compose.local.yml logs -f
|
||||||
|
|
||||||
|
# Stop
|
||||||
|
docker-compose -f docker-compose.local.yml down
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Bun directly (without Docker)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
bun install
|
||||||
|
|
||||||
|
# Run dev server (API + Vite)
|
||||||
|
bun run dev
|
||||||
|
|
||||||
|
# Run API only
|
||||||
|
bun run dev:api
|
||||||
|
|
||||||
|
# Run client only
|
||||||
|
bun run dev:client
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
### Required in Dokploy
|
||||||
|
|
||||||
|
```env
|
||||||
|
DOKPLOY_URL=http://10.100.0.20:3000
|
||||||
|
DOKPLOY_API_TOKEN=<your-token>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optional (with defaults)
|
||||||
|
|
||||||
|
```env
|
||||||
|
PORT=3000
|
||||||
|
HOST=0.0.0.0
|
||||||
|
STACK_DOMAIN_SUFFIX=ai.flexinit.nl
|
||||||
|
STACK_IMAGE=git.app.flexinit.nl/flexinit/agent-stack:latest
|
||||||
|
RESERVED_NAMES=admin,api,www,root,system,test,demo,portal
|
||||||
|
```
|
||||||
|
|
||||||
|
### Per-Environment Overrides
|
||||||
|
|
||||||
|
If dev/staging/prod need different configs, set them in Dokploy:
|
||||||
|
|
||||||
|
**Dev**:
|
||||||
|
```env
|
||||||
|
STACK_DOMAIN_SUFFIX=dev-ai.flexinit.nl
|
||||||
|
```
|
||||||
|
|
||||||
|
**Staging**:
|
||||||
|
```env
|
||||||
|
STACK_DOMAIN_SUFFIX=staging-ai.flexinit.nl
|
||||||
|
```
|
||||||
|
|
||||||
|
**Prod**:
|
||||||
|
```env
|
||||||
|
STACK_DOMAIN_SUFFIX=ai.flexinit.nl
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Build Fails in Gitea Actions
|
||||||
|
|
||||||
|
Check the workflow logs in Gitea:
|
||||||
|
```
|
||||||
|
https://git.app.flexinit.nl/oussamadouhou/ai-stack-deployer/actions
|
||||||
|
```
|
||||||
|
|
||||||
|
Common issues:
|
||||||
|
- **AVX error**: Fixed in Dockerfile (uses Node.js for build)
|
||||||
|
- **Registry auth**: Check `REGISTRY_TOKEN` secret in Gitea
|
||||||
|
|
||||||
|
### Deployment Fails in Dokploy
|
||||||
|
|
||||||
|
1. **Check Dokploy logs**: Application → Logs
|
||||||
|
2. **Verify image exists**:
|
||||||
|
```bash
|
||||||
|
docker pull git.app.flexinit.nl/oussamadouhou/ai-stack-deployer:dev
|
||||||
|
```
|
||||||
|
3. **Check environment variables**: Make sure all required vars are set
|
||||||
|
|
||||||
|
### Health Check Failing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# SSH into Dokploy host
|
||||||
|
ssh user@10.100.0.20
|
||||||
|
|
||||||
|
# Check container logs
|
||||||
|
docker logs ai-stack-deployer-dev
|
||||||
|
|
||||||
|
# Test health endpoint
|
||||||
|
curl http://localhost:3000/health
|
||||||
|
```
|
||||||
|
|
||||||
|
### Webhook Not Triggering
|
||||||
|
|
||||||
|
1. **In Dokploy**, check webhook configuration
|
||||||
|
2. **In Gitea**, go to repo Settings → Webhooks
|
||||||
|
3. Verify webhook URL and secret match
|
||||||
|
4. Check recent deliveries for errors
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Production Considerations
|
||||||
|
|
||||||
|
### 1. Image Size Optimization
|
||||||
|
|
||||||
|
The Docker image excludes dev files via `.dockerignore`:
|
||||||
|
- ✅ `docs/` - excluded
|
||||||
|
- ✅ `scripts/` - excluded
|
||||||
|
- ✅ `.gitea/` - excluded
|
||||||
|
- ✅ `*.md` (except README.md) - excluded
|
||||||
|
|
||||||
|
Current image size: ~150MB
|
||||||
|
|
||||||
|
### 2. Security
|
||||||
|
|
||||||
|
- Container runs as non-root user (`nodejs:1001`)
|
||||||
|
- No secrets in source code (uses `.env`)
|
||||||
|
- Dokploy API accessible only on internal network
|
||||||
|
|
||||||
|
### 3. Monitoring
|
||||||
|
|
||||||
|
Set up alerts for:
|
||||||
|
- Container health check failures
|
||||||
|
- Memory/CPU usage spikes
|
||||||
|
- Deployment failures
|
||||||
|
|
||||||
|
### 4. Backup Strategy
|
||||||
|
|
||||||
|
- **Database**: This app has no database (stateless)
|
||||||
|
- **Configuration**: Environment variables stored in Dokploy (backed up)
|
||||||
|
- **Code**: Stored in Gitea (backed up)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
| Environment | Domain | Image Tag | Auto-Deploy? |
|
||||||
|
|-------------|------------------------------|-----------|--------------|
|
||||||
|
| Dev | portal-dev.ai.flexinit.nl | `dev` | ✅ On push |
|
||||||
|
| Staging | portal-staging.ai.flexinit.nl | `staging` | ✅ On push |
|
||||||
|
| Production | portal.ai.flexinit.nl | `latest` | ✅ On push |
|
||||||
|
|
||||||
|
**Next Steps**:
|
||||||
|
1. ✅ Push changes to `dev` branch
|
||||||
|
2. ⏳ Create 3 Dokploy applications (dev, staging, prod)
|
||||||
|
3. ⏳ Configure webhooks for each branch
|
||||||
|
4. ⏳ Deploy and test each environment
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Questions?** Check the main README.md or CLAUDE.md for more details.
|
||||||
Reference in New Issue
Block a user