diff --git a/.github/DEPLOYMENT.md b/.github/DEPLOYMENT.md index f68269d..b6b4709 100644 --- a/.github/DEPLOYMENT.md +++ b/.github/DEPLOYMENT.md @@ -49,9 +49,10 @@ Your production server should have: 3. **Environment file configured** ```bash + # Create and configure .env.docker with your production values + # The docker-compose.yml already references this file cp .env.docker.example .env.docker nano .env.docker - # Set your domain and email ``` ## Workflow Features @@ -85,7 +86,7 @@ Your production server should have: # On server cd /opt/quixotic git pull origin main - docker-compose --env-file .env.docker up -d --build + docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --pull always ``` ## Monitoring diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1f9602c..436aea4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,36 +105,13 @@ jobs: cd /opt/quixotic git pull origin main - # Create production environment file from secrets - cat > .env.docker << EOF - NODE_ENV=production - PORT=3000 - POSTGRES_DB=${{ secrets.POSTGRES_DB }} - POSTGRES_USER=${{ secrets.POSTGRES_USER }} - POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} - DOMAIN=${{ secrets.DOMAIN }} - ACME_EMAIL=${{ secrets.ACME_EMAIL }} - TRAEFIK_AUTH=${{ secrets.TRAEFIK_AUTH }} - TELEGRAM_BOT_TOKEN=${{ secrets.TELEGRAM_BOT_TOKEN }} - WEB_APP_URL=https://${{ secrets.DOMAIN }} - DATABASE_URL=postgresql://${{ secrets.POSTGRES_USER }}:${{ secrets.POSTGRES_PASSWORD }}@postgres:5432/${{ secrets.POSTGRES_DB }} - EOF - # Login to GitHub Container Registry echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin - # Pull latest image - docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - - # Deploy with zero downtime using production override - docker-compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env.docker pull - - # Stop existing containers if they exist - if docker-compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env.docker ps -q | grep -q .; then - docker-compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env.docker down --remove-orphans - fi - - docker-compose -f docker-compose.yml -f docker-compose.prod.yml --env-file .env.docker up -d + # Deploy using production compose + docker-compose -f docker-compose.yml -f docker-compose.prod.yml pull + docker-compose -f docker-compose.yml -f docker-compose.prod.yml down --remove-orphans + docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d # Cleanup old images docker image prune -f diff --git a/.gitignore b/.gitignore index daa9117..c930e70 100644 --- a/.gitignore +++ b/.gitignore @@ -75,11 +75,6 @@ build/ out/ coverage/ -# Docker -.dockerignore.local -docker-compose.override.yml -docker-compose.local.yml - # Backup files *.bak *.backup diff --git a/.serena/memories/ci_cd_simplification_complete.md b/.serena/memories/ci_cd_simplification_complete.md new file mode 100644 index 0000000..59e3917 --- /dev/null +++ b/.serena/memories/ci_cd_simplification_complete.md @@ -0,0 +1,45 @@ +# CI/CD Simplification Complete + +## Changes Made + +### 1. Simplified docker-compose.prod.yml +- Removed complex environment variable substitution +- Now simply uses `ghcr.io/andrewkozin/quixotic:latest` image +- Only sets `NODE_ENV: production` + +### 2. Simplified CI/CD Pipeline (.github/workflows/ci.yml) +- Removed complex `.env.docker` file creation with secrets substitution +- Deploy step now simply: + - Pulls latest code + - Logs into GHCR + - Uses standard docker-compose commands + - No more environment variable manipulation + +### 3. Updated package.json Scripts +- Removed `--env-file .env.docker` from all docker commands +- Added production-specific commands: + - `docker:prod` - Run production setup + - `docker:prod:down` - Stop production setup +- Simplified existing commands to use default docker-compose behavior + +### 4. Updated Documentation +- Updated DEPLOYMENT.md with new simple approach +- Manual deployment now uses: `docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d --pull always` + +## Benefits +- Much simpler deployment process +- No complex environment variable manipulation in CI +- Environment variables are loaded from `.env.docker` file on server (as configured in docker-compose.yml) +- Cleaner separation between development and production configs +- Easier to debug and maintain + +## Usage +For production deployment: +```bash +docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d +``` + +For development: +```bash +docker-compose up -d +``` \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index c7ff262..cf8731d 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,4 +1,5 @@ services: quixotic-app: - build: null - image: ${APP_IMAGE} + image: ghcr.io/andrewkozin/quixotic:latest + environment: + NODE_ENV: production diff --git a/package.json b/package.json index 60976d7..7919f81 100644 --- a/package.json +++ b/package.json @@ -18,12 +18,14 @@ "validate": "yarn lint && yarn build && echo '✅ All checks passed!'", "pretest": "yarn validate", "docker:build": "docker-compose build", - "docker:up": "docker-compose --env-file .env.docker up -d", + "docker:up": "docker-compose up -d", "docker:down": "docker-compose down", "docker:logs": "docker-compose logs -f", "docker:restart": "docker-compose restart", - "docker:rebuild": "docker-compose down && docker-compose build --no-cache && docker-compose --env-file .env.docker up -d", - "docker:dev": "docker-compose --env-file .env.docker up --build" + "docker:rebuild": "docker-compose down && docker-compose build --no-cache && docker-compose up -d", + "docker:dev": "docker-compose up --build", + "docker:prod": "docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d", + "docker:prod:down": "docker-compose -f docker-compose.yml -f docker-compose.prod.yml down" }, "packageManager": "yarn@1.22.19", "dependencies": {