Some checks failed
Dev Deployment (Zero Downtime) / deploy-dev (push) Has been cancelled
- Created separate workflows for production and dev deployments - Production branch → dk0.dev (port 3000) - Dev branch → dev.dk0.dev (port 3002) - Zero-downtime deployment pattern (start new, wait for health, remove old) - Complete isolation between environments (separate containers, databases, networks) - Cleaned up unused code and files: - Removed unused GhostEditor and ResizableGhostEditor components - Removed old/unused workflows and markdown files - Fixed docker-compose references - Upgraded dependencies to latest compatible versions - Fixed TypeScript errors in editor page - Updated staging to use dev.dk0.dev domain
5.2 KiB
5.2 KiB
🚀 Deployment Setup Guide
Overview
This project uses a dual-branch deployment strategy with zero-downtime deployments:
- Production Branch (
production) → Serveshttps://dk0.devon port 3000 - Dev Branch (
dev) → Serveshttps://dev.dk0.devon port 3002
Both environments are completely isolated with separate:
- Docker containers
- Databases (PostgreSQL)
- Redis instances
- Networks
- Volumes
Branch Strategy
Production Branch
- Branch:
production - Domain:
https://dk0.dev - Port:
3000 - Container:
portfolio-app - Database:
portfolio_db(port 5432) - Redis:
portfolio-redis(port 6379) - Image Tag:
portfolio-app:production/portfolio-app:latest
Dev Branch
- Branch:
dev - Domain:
https://dev.dk0.dev - Port:
3002 - Container:
portfolio-app-staging - Database:
portfolio_staging_db(port 5434) - Redis:
portfolio-redis-staging(port 6381) - Image Tag:
portfolio-app:staging
Automatic Deployment
How It Works
-
Push to
productionbranch:- Triggers
.gitea/workflows/production-deploy.yml - Runs tests, builds, and deploys to production
- Zero-downtime deployment (starts new container, waits for health, removes old)
- Triggers
-
Push to
devbranch:- Triggers
.gitea/workflows/dev-deploy.yml - Runs tests, builds, and deploys to dev/staging
- Zero-downtime deployment
- Triggers
Zero-Downtime Process
- Build new Docker image
- Start new container with updated image
- Wait for new container to be healthy (health checks)
- Verify HTTP endpoints respond correctly
- Remove old container (if different)
- Cleanup old images
Manual Deployment
Production
# Build and deploy production
docker build -t portfolio-app:latest .
docker compose -f docker-compose.production.yml up -d --build
Dev/Staging
# Build and deploy dev
docker build -t portfolio-app:staging .
docker compose -f docker-compose.staging.yml up -d --build
Environment Variables
Required Gitea Variables
NEXT_PUBLIC_BASE_URL- Base URL for the applicationMY_EMAIL- Email address for contactMY_INFO_EMAIL- Info email addressLOG_LEVEL- Logging level (info/debug)
Required Gitea Secrets
MY_PASSWORD- Email passwordMY_INFO_PASSWORD- Info email passwordADMIN_BASIC_AUTH- Admin basic auth credentialsN8N_SECRET_TOKEN- Optional: n8n webhook secret
Optional Variables
N8N_WEBHOOK_URL- n8n webhook URL for automation
Health Checks
Both environments have health check endpoints:
- Production:
http://localhost:3000/api/health - Dev:
http://localhost:3002/api/health
Monitoring
Check Container Status
# Production
docker compose -f docker-compose.production.yml ps
# Dev
docker compose -f docker-compose.staging.yml ps
View Logs
# Production
docker logs portfolio-app --tail=100 -f
# Dev
docker logs portfolio-app-staging --tail=100 -f
Health Check
# Production
curl http://localhost:3000/api/health
# Dev
curl http://localhost:3002/api/health
Troubleshooting
Container Won't Start
- Check logs:
docker logs <container-name> - Verify environment variables are set
- Check database/redis connectivity
- Verify ports aren't already in use
Deployment Fails
- Check Gitea Actions logs
- Verify all required secrets/variables are set
- Check if old containers are blocking ports
- Verify Docker image builds successfully
Zero-Downtime Issues
- Old container might still be running - check with
docker ps - Health checks might be failing - check container logs
- Port conflicts - verify ports 3000 and 3002 are available
Rollback
If a deployment fails or causes issues:
# Production rollback
docker compose -f docker-compose.production.yml down
docker tag portfolio-app:previous portfolio-app:latest
docker compose -f docker-compose.production.yml up -d
# Dev rollback
docker compose -f docker-compose.staging.yml down
docker tag portfolio-app:staging-previous portfolio-app:staging
docker compose -f docker-compose.staging.yml up -d
Best Practices
- Always test on dev branch first before pushing to production
- Monitor health checks after deployment
- Keep old images for quick rollback (last 3 versions)
- Use feature flags for new features
- Document breaking changes before deploying
- Run tests locally before pushing
Network Configuration
- Production Network:
portfolio_net+proxy(external) - Dev Network:
portfolio_staging_net - Isolation: Complete separation ensures no interference
Database Management
Production Database
- Container:
portfolio-postgres - Port:
5432(internal only) - Database:
portfolio_db - User:
portfolio_user
Dev Database
- Container:
portfolio-postgres-staging - Port:
5434(external),5432(internal) - Database:
portfolio_staging_db - User:
portfolio_user
Redis Configuration
Production Redis
- Container:
portfolio-redis - Port:
6379(internal only)
Dev Redis
- Container:
portfolio-redis-staging - Port:
6381(external),6379(internal)