ci: Auto-deploy on push via SSH
- Gitea Actions workflow now syncs repo to server, builds images, restarts containers, and runs health checks - Removed all hardcoded secrets from scripts/deploy.sh - Added CI/CD documentation and ignored .env.deploy NOTE: Existing secrets previously committed must be rotated.
This commit is contained in:
@ -1,22 +1,194 @@
|
|||||||
name: Pounce CI
|
name: Deploy Pounce (Auto)
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main]
|
branches: [main]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
info:
|
deploy:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Build Info
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install deploy tooling
|
||||||
|
run: |
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y --no-install-recommends openssh-client rsync ca-certificates
|
||||||
|
|
||||||
|
- name: Setup SSH key
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "${{ secrets.DEPLOY_SSH_KEY }}" > ~/.ssh/deploy_key
|
||||||
|
chmod 600 ~/.ssh/deploy_key
|
||||||
|
ssh-keyscan -H "${{ secrets.DEPLOY_HOST }}" >> ~/.ssh/known_hosts 2>/dev/null
|
||||||
|
|
||||||
|
- name: Sync repository to server
|
||||||
|
run: |
|
||||||
|
rsync -az --delete \
|
||||||
|
-e "ssh -i ~/.ssh/deploy_key -o StrictHostKeyChecking=yes" \
|
||||||
|
--exclude ".git" \
|
||||||
|
--exclude "frontend/node_modules" \
|
||||||
|
--exclude "frontend/.next" \
|
||||||
|
--exclude "**/__pycache__" \
|
||||||
|
--exclude "**/*.pyc" \
|
||||||
|
./ \
|
||||||
|
"${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}:${{ secrets.DEPLOY_PATH }}/"
|
||||||
|
|
||||||
|
- name: Deploy (build + restart + health check)
|
||||||
|
env:
|
||||||
|
DEPLOY_SUDO_PASSWORD: ${{ secrets.DEPLOY_SUDO_PASSWORD }}
|
||||||
|
# App secrets (used to generate backend env file on server)
|
||||||
|
DATABASE_URL: ${{ secrets.DATABASE_URL }}
|
||||||
|
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||||
|
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
|
||||||
|
STRIPE_SECRET_KEY: ${{ secrets.STRIPE_SECRET_KEY }}
|
||||||
|
STRIPE_WEBHOOK_SECRET: ${{ secrets.STRIPE_WEBHOOK_SECRET }}
|
||||||
|
GOOGLE_CLIENT_SECRET: ${{ secrets.GOOGLE_CLIENT_SECRET }}
|
||||||
|
GH_OAUTH_SECRET: ${{ secrets.GH_OAUTH_SECRET }}
|
||||||
|
CZDS_USERNAME: ${{ secrets.CZDS_USERNAME }}
|
||||||
|
CZDS_PASSWORD: ${{ secrets.CZDS_PASSWORD }}
|
||||||
|
run: |
|
||||||
|
ssh -i ~/.ssh/deploy_key "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" << 'DEPLOY_EOF'
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Use sudo non-interactively (password supplied via env)
|
||||||
|
sudo_cmd() {
|
||||||
|
printf '%s\n' "$DEPLOY_SUDO_PASSWORD" | sudo -S "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Ensure dirs
|
||||||
|
sudo_cmd mkdir -p /data/pounce/env /data/pounce/zones
|
||||||
|
sudo_cmd chmod -R 755 /data/pounce || true
|
||||||
|
|
||||||
|
# Generate backend env file from pipeline-provided secrets (never echo values)
|
||||||
|
sudo_cmd python3 - <<'PY'
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
env = {
|
||||||
|
# Core
|
||||||
|
"ENVIRONMENT": "production",
|
||||||
|
"ENABLE_SCHEDULER": "true",
|
||||||
|
"COOKIE_SECURE": "true",
|
||||||
|
"CORS_ORIGINS": "https://pounce.ch,https://www.pounce.ch",
|
||||||
|
"SITE_URL": "https://pounce.ch",
|
||||||
|
"FRONTEND_URL": "https://pounce.ch",
|
||||||
|
|
||||||
|
# Data dirs
|
||||||
|
"CZDS_DATA_DIR": "/data/czds",
|
||||||
|
"SWITCH_DATA_DIR": "/data/switch",
|
||||||
|
"ZONE_RETENTION_DAYS": "3",
|
||||||
|
|
||||||
|
# DB/Redis
|
||||||
|
"DATABASE_URL": os.environ["DATABASE_URL"],
|
||||||
|
"REDIS_URL": "redis://pounce-redis:6379/0",
|
||||||
|
|
||||||
|
# Auth
|
||||||
|
"SECRET_KEY": os.environ["SECRET_KEY"],
|
||||||
|
"JWT_SECRET": os.environ["SECRET_KEY"],
|
||||||
|
|
||||||
|
# SMTP
|
||||||
|
"SMTP_HOST": "smtp.zoho.eu",
|
||||||
|
"SMTP_PORT": "465",
|
||||||
|
"SMTP_USER": "hello@pounce.ch",
|
||||||
|
"SMTP_PASSWORD": os.environ["SMTP_PASSWORD"],
|
||||||
|
"SMTP_FROM_EMAIL": "hello@pounce.ch",
|
||||||
|
"SMTP_FROM_NAME": "pounce",
|
||||||
|
"SMTP_USE_TLS": "false",
|
||||||
|
"SMTP_USE_SSL": "true",
|
||||||
|
|
||||||
|
# Stripe
|
||||||
|
"STRIPE_SECRET_KEY": os.environ["STRIPE_SECRET_KEY"],
|
||||||
|
"STRIPE_PUBLISHABLE_KEY": "pk_live_51ScLbjCtFUamNRpNeFugrlTIYhszbo8GovSGiMnPwHpZX9p3SGtgG8iRHYRIlAtg9M9sl3mvT5r8pwXP3mOsPALG00Wk3j0wH4",
|
||||||
|
"STRIPE_PRICE_TRADER": "price_1ScRlzCtFUamNRpNQdMpMzxV",
|
||||||
|
"STRIPE_PRICE_TYCOON": "price_1SdwhSCtFUamNRpNEXTSuGUc",
|
||||||
|
"STRIPE_WEBHOOK_SECRET": os.environ["STRIPE_WEBHOOK_SECRET"],
|
||||||
|
|
||||||
|
# OAuth
|
||||||
|
"GOOGLE_CLIENT_ID": "865146315769-vi7vcu91d3i7huv8ikjun52jo9ob7spk.apps.googleusercontent.com",
|
||||||
|
"GOOGLE_CLIENT_SECRET": os.environ["GOOGLE_CLIENT_SECRET"],
|
||||||
|
"GOOGLE_REDIRECT_URI": "https://pounce.ch/api/v1/oauth/google/callback",
|
||||||
|
|
||||||
|
"GITHUB_CLIENT_ID": "Ov23liBjROk39vYXi3G5",
|
||||||
|
"GITHUB_CLIENT_SECRET": os.environ["GH_OAUTH_SECRET"],
|
||||||
|
"GITHUB_REDIRECT_URI": "https://pounce.ch/api/v1/oauth/github/callback",
|
||||||
|
|
||||||
|
# CZDS
|
||||||
|
"CZDS_USERNAME": os.environ["CZDS_USERNAME"],
|
||||||
|
"CZDS_PASSWORD": os.environ["CZDS_PASSWORD"],
|
||||||
|
}
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
for k, v in env.items():
|
||||||
|
if v is None:
|
||||||
|
continue
|
||||||
|
lines.append(f"{k}={v}")
|
||||||
|
|
||||||
|
path = Path("/data/pounce/env/backend.env")
|
||||||
|
path.write_text("\n".join(lines) + "\n")
|
||||||
|
PY
|
||||||
|
|
||||||
|
# Build images from synced repo
|
||||||
|
cd "${{ secrets.DEPLOY_PATH }}"
|
||||||
|
sudo_cmd docker build -t pounce-backend:latest backend
|
||||||
|
sudo_cmd docker build \
|
||||||
|
--build-arg NEXT_PUBLIC_API_URL=https://api.pounce.ch \
|
||||||
|
--build-arg BACKEND_URL=http://pounce-backend:8000 \
|
||||||
|
-t pounce-frontend:latest \
|
||||||
|
frontend
|
||||||
|
|
||||||
|
# Deploy backend
|
||||||
|
sudo_cmd docker stop pounce-backend 2>/dev/null || true
|
||||||
|
sudo_cmd docker rm pounce-backend 2>/dev/null || true
|
||||||
|
sudo_cmd docker run -d \
|
||||||
|
--name pounce-backend \
|
||||||
|
--network coolify \
|
||||||
|
--restart unless-stopped \
|
||||||
|
--shm-size=8g \
|
||||||
|
--env-file /data/pounce/env/backend.env \
|
||||||
|
-v /data/pounce/zones:/data \
|
||||||
|
-l "traefik.enable=true" \
|
||||||
|
-l "traefik.http.routers.pounce-api.rule=Host(\`api.pounce.ch\`)" \
|
||||||
|
-l "traefik.http.routers.pounce-api.entryPoints=https" \
|
||||||
|
-l "traefik.http.routers.pounce-api.tls=true" \
|
||||||
|
-l "traefik.http.routers.pounce-api.tls.certresolver=letsencrypt" \
|
||||||
|
-l "traefik.http.services.pounce-api.loadbalancer.server.port=8000" \
|
||||||
|
pounce-backend:latest
|
||||||
|
sudo_cmd docker network connect n0488s44osgoow4wgo04ogg0 pounce-backend 2>/dev/null || true
|
||||||
|
|
||||||
|
# Deploy frontend
|
||||||
|
sudo_cmd docker stop pounce-frontend 2>/dev/null || true
|
||||||
|
sudo_cmd docker rm pounce-frontend 2>/dev/null || true
|
||||||
|
sudo_cmd docker run -d \
|
||||||
|
--name pounce-frontend \
|
||||||
|
--network coolify \
|
||||||
|
--restart unless-stopped \
|
||||||
|
-l "traefik.enable=true" \
|
||||||
|
-l "traefik.http.routers.pounce-web.rule=Host(\`pounce.ch\`) || Host(\`www.pounce.ch\`)" \
|
||||||
|
-l "traefik.http.routers.pounce-web.entryPoints=https" \
|
||||||
|
-l "traefik.http.routers.pounce-web.tls=true" \
|
||||||
|
-l "traefik.http.routers.pounce-web.tls.certresolver=letsencrypt" \
|
||||||
|
-l "traefik.http.services.pounce-web.loadbalancer.server.port=3000" \
|
||||||
|
pounce-frontend:latest
|
||||||
|
sudo_cmd docker network connect n0488s44osgoow4wgo04ogg0 pounce-frontend 2>/dev/null || true
|
||||||
|
|
||||||
|
# Health check
|
||||||
|
sleep 15
|
||||||
|
curl -sf https://api.pounce.ch/api/v1/health >/dev/null
|
||||||
|
curl -sf https://pounce.ch >/dev/null
|
||||||
|
|
||||||
|
# Cleanup
|
||||||
|
sudo_cmd docker image prune -f >/dev/null 2>&1 || true
|
||||||
|
echo "✅ Deploy finished"
|
||||||
|
DEPLOY_EOF
|
||||||
|
|
||||||
|
- name: Summary
|
||||||
run: |
|
run: |
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
echo "POUNCE BUILD INFO"
|
echo "🎉 AUTO DEPLOY COMPLETED"
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
echo "Commit: ${{ github.sha }}"
|
echo "Commit: ${{ github.sha }}"
|
||||||
echo "Branch: ${{ github.ref_name }}"
|
echo "Backend: https://api.pounce.ch"
|
||||||
echo "Time: $(date)"
|
echo "Web: https://pounce.ch"
|
||||||
echo ""
|
|
||||||
echo "To deploy, run locally:"
|
|
||||||
echo " ./scripts/deploy.sh"
|
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -26,6 +26,7 @@ dist/
|
|||||||
.env
|
.env
|
||||||
.env.local
|
.env.local
|
||||||
.env.*.local
|
.env.*.local
|
||||||
|
.env.deploy
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
# Deployment env files (MUST NOT be committed)
|
# Deployment env files (MUST NOT be committed)
|
||||||
|
|||||||
42
ops/CI_CD.md
Normal file
42
ops/CI_CD.md
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# CI/CD (Gitea Actions) – Auto Deploy
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
Every push to `main` should:
|
||||||
|
- sync the repo to the production server
|
||||||
|
- build Docker images on the server
|
||||||
|
- restart containers
|
||||||
|
- run health checks
|
||||||
|
|
||||||
|
This repository uses a **remote SSH deployment** from Gitea Actions.
|
||||||
|
|
||||||
|
## Required Gitea Actions Secrets
|
||||||
|
Configure these in Gitea: **Repo → Settings → Actions → Secrets**
|
||||||
|
|
||||||
|
### Deployment (SSH)
|
||||||
|
- `DEPLOY_HOST` – production server IP/hostname
|
||||||
|
- `DEPLOY_USER` – SSH user (e.g. `administrator`)
|
||||||
|
- `DEPLOY_PATH` – absolute path where the repo is synced on the server (e.g. `/home/administrator/pounce`)
|
||||||
|
- `DEPLOY_SSH_KEY` – private key for SSH access
|
||||||
|
- `DEPLOY_SUDO_PASSWORD` – sudo password for `DEPLOY_USER` (used non-interactively)
|
||||||
|
|
||||||
|
### App Secrets (Backend)
|
||||||
|
Used to generate `/data/pounce/env/backend.env` on the server.
|
||||||
|
- `DATABASE_URL`
|
||||||
|
- `SECRET_KEY`
|
||||||
|
- `SMTP_PASSWORD`
|
||||||
|
- `STRIPE_SECRET_KEY`
|
||||||
|
- `STRIPE_WEBHOOK_SECRET`
|
||||||
|
- `GOOGLE_CLIENT_SECRET`
|
||||||
|
- `GH_OAUTH_SECRET`
|
||||||
|
- `CZDS_USERNAME`
|
||||||
|
- `CZDS_PASSWORD`
|
||||||
|
|
||||||
|
## Server Requirements
|
||||||
|
- `sudo` installed
|
||||||
|
- `docker` installed
|
||||||
|
- `DEPLOY_USER` must be able to run docker via `sudo` (pipeline uses `sudo -S docker ...`)
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- Secrets are written to `/data/pounce/env/backend.env` on the server with restricted permissions.
|
||||||
|
- Frontend build args are supplied in the workflow (`NEXT_PUBLIC_API_URL`, `BACKEND_URL`).
|
||||||
|
|
||||||
@ -17,6 +17,8 @@ SERVER="185.142.213.170"
|
|||||||
SSH_KEY="${SSH_KEY:-$HOME/.ssh/pounce_server}"
|
SSH_KEY="${SSH_KEY:-$HOME/.ssh/pounce_server}"
|
||||||
SSH_USER="administrator"
|
SSH_USER="administrator"
|
||||||
REMOTE_TMP="/tmp/pounce"
|
REMOTE_TMP="/tmp/pounce"
|
||||||
|
REMOTE_REPO="/home/administrator/pounce"
|
||||||
|
REMOTE_ENV_DIR="/data/pounce/env"
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
RED='\033[0;31m'
|
RED='\033[0;31m'
|
||||||
@ -33,6 +35,10 @@ if [ ! -f "$SSH_KEY" ]; then
|
|||||||
error "SSH key not found: $SSH_KEY"
|
error "SSH key not found: $SSH_KEY"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -z "${DEPLOY_SUDO_PASSWORD:-}" ]; then
|
||||||
|
error "DEPLOY_SUDO_PASSWORD is required (export it locally, do not commit it)."
|
||||||
|
fi
|
||||||
|
|
||||||
# What to deploy
|
# What to deploy
|
||||||
DEPLOY_BACKEND=true
|
DEPLOY_BACKEND=true
|
||||||
DEPLOY_FRONTEND=true
|
DEPLOY_FRONTEND=true
|
||||||
@ -57,15 +63,26 @@ if [ "$DEPLOY_BACKEND" = true ]; then
|
|||||||
--exclude '.git' \
|
--exclude '.git' \
|
||||||
--exclude 'venv' \
|
--exclude 'venv' \
|
||||||
backend/ \
|
backend/ \
|
||||||
${SSH_USER}@${SERVER}:${REMOTE_TMP}-backend/
|
${SSH_USER}@${SERVER}:${REMOTE_REPO}/backend/
|
||||||
|
|
||||||
log "Building backend image..."
|
log "Building backend image..."
|
||||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ${SSH_USER}@${SERVER} \
|
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ${SSH_USER}@${SERVER} \
|
||||||
"echo 'u4R6tgCv*c8Fyc1ee' | sudo -S docker build -t pounce-backend:latest ${REMOTE_TMP}-backend/" || error "Backend build failed"
|
"printf '%s\n' \"${DEPLOY_SUDO_PASSWORD}\" | sudo -S docker build -t pounce-backend:latest ${REMOTE_REPO}/backend/" || error "Backend build failed"
|
||||||
|
|
||||||
log "Deploying backend container..."
|
log "Deploying backend container..."
|
||||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ${SSH_USER}@${SERVER} << 'BACKEND_DEPLOY'
|
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ${SSH_USER}@${SERVER} << BACKEND_DEPLOY
|
||||||
echo 'u4R6tgCv*c8Fyc1ee' | sudo -S bash -c '
|
printf '%s\n' "${DEPLOY_SUDO_PASSWORD}" | sudo -S bash -c '
|
||||||
|
set -e
|
||||||
|
|
||||||
|
mkdir -p "${REMOTE_ENV_DIR}" /data/pounce/zones
|
||||||
|
chmod -R 755 /data/pounce || true
|
||||||
|
|
||||||
|
# Backend env must exist on server (created by CI or manually)
|
||||||
|
if [ ! -f "${REMOTE_ENV_DIR}/backend.env" ]; then
|
||||||
|
echo "Missing ${REMOTE_ENV_DIR}/backend.env"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
docker stop pounce-backend 2>/dev/null || true
|
docker stop pounce-backend 2>/dev/null || true
|
||||||
docker rm pounce-backend 2>/dev/null || true
|
docker rm pounce-backend 2>/dev/null || true
|
||||||
|
|
||||||
@ -73,33 +90,7 @@ docker run -d \
|
|||||||
--name pounce-backend \
|
--name pounce-backend \
|
||||||
--network coolify \
|
--network coolify \
|
||||||
--shm-size=8g \
|
--shm-size=8g \
|
||||||
-e DATABASE_URL="postgresql+asyncpg://pounce:PounceDB2024!@supabase-db-n0488s44osgoow4wgo04ogg0:5432/pounce" \
|
--env-file "${REMOTE_ENV_DIR}/backend.env" \
|
||||||
-e REDIS_URL="redis://pounce-redis:6379" \
|
|
||||||
-e ENABLE_SCHEDULER="true" \
|
|
||||||
-e SECRET_KEY="super-secret-key-change-me-in-production-please" \
|
|
||||||
-e ENVIRONMENT="production" \
|
|
||||||
-e CORS_ORIGINS="https://pounce.ch,https://www.pounce.ch" \
|
|
||||||
-e COOKIE_SECURE="true" \
|
|
||||||
-e SITE_URL="https://pounce.ch" \
|
|
||||||
-e CZDS_DATA_DIR="/data/czds" \
|
|
||||||
-e CZDS_USERNAME="Gugger99@gmx.ch" \
|
|
||||||
-e CZDS_PASSWORD="Icann@2024!" \
|
|
||||||
-e SMTP_HOST="mail.infomaniak.com" \
|
|
||||||
-e SMTP_PORT="587" \
|
|
||||||
-e SMTP_USER="hello@pounce.ch" \
|
|
||||||
-e SMTP_PASSWORD="xVP4x#q1s78C" \
|
|
||||||
-e SMTP_FROM_EMAIL="hello@pounce.ch" \
|
|
||||||
-e STRIPE_SECRET_KEY="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" \
|
|
||||||
-e STRIPE_PUBLISHABLE_KEY="pk_live_51ScLbjCtFUamNRpNeFugrlTIYhszbo8GovSGiMnPwHpZX9p3SGtgG8iRHYRIlAtg9M9sl3mvT5r8pwXP3mOsPALG00Wk3j0wH4" \
|
|
||||||
-e STRIPE_PRICE_TRADER="price_1ScRlzCtFUamNRpNQdMpMzxV" \
|
|
||||||
-e STRIPE_PRICE_TYCOON="price_1SdwhSCtFUamNRpNEXTSuGUc" \
|
|
||||||
-e STRIPE_WEBHOOK_SECRET="whsec_DlWSVkIJDDDkjfj29fjJFkdj2Ksldk" \
|
|
||||||
-e GOOGLE_CLIENT_ID="865146315769-vi7vcu91d3i7huv8ikjun52jo9ob7spk.apps.googleusercontent.com" \
|
|
||||||
-e GOOGLE_CLIENT_SECRET="" \
|
|
||||||
-e GOOGLE_REDIRECT_URI="https://pounce.ch/api/v1/oauth/google/callback" \
|
|
||||||
-e GITHUB_CLIENT_ID="Ov23liBjROk39vYXi3G5" \
|
|
||||||
-e GITHUB_CLIENT_SECRET="" \
|
|
||||||
-e GITHUB_REDIRECT_URI="https://pounce.ch/api/v1/oauth/github/callback" \
|
|
||||||
-v /data/pounce/zones:/data \
|
-v /data/pounce/zones:/data \
|
||||||
--label "traefik.enable=true" \
|
--label "traefik.enable=true" \
|
||||||
--label "traefik.http.routers.pounce-backend.rule=Host(\`api.pounce.ch\`)" \
|
--label "traefik.http.routers.pounce-backend.rule=Host(\`api.pounce.ch\`)" \
|
||||||
@ -127,15 +118,16 @@ if [ "$DEPLOY_FRONTEND" = true ]; then
|
|||||||
--exclude '.next' \
|
--exclude '.next' \
|
||||||
--exclude '.git' \
|
--exclude '.git' \
|
||||||
frontend/ \
|
frontend/ \
|
||||||
${SSH_USER}@${SERVER}:${REMOTE_TMP}-frontend/
|
${SSH_USER}@${SERVER}:${REMOTE_REPO}/frontend/
|
||||||
|
|
||||||
log "Building frontend image..."
|
log "Building frontend image..."
|
||||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ${SSH_USER}@${SERVER} \
|
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ${SSH_USER}@${SERVER} \
|
||||||
"echo 'u4R6tgCv*c8Fyc1ee' | sudo -S docker build --build-arg NEXT_PUBLIC_API_URL=https://api.pounce.ch --build-arg BACKEND_URL=http://pounce-backend:8000 -t pounce-frontend:latest ${REMOTE_TMP}-frontend/" || error "Frontend build failed"
|
"printf '%s\n' \"${DEPLOY_SUDO_PASSWORD}\" | sudo -S docker build --build-arg NEXT_PUBLIC_API_URL=https://api.pounce.ch --build-arg BACKEND_URL=http://pounce-backend:8000 -t pounce-frontend:latest ${REMOTE_REPO}/frontend/" || error "Frontend build failed"
|
||||||
|
|
||||||
log "Deploying frontend container..."
|
log "Deploying frontend container..."
|
||||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ${SSH_USER}@${SERVER} << 'FRONTEND_DEPLOY'
|
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ${SSH_USER}@${SERVER} << FRONTEND_DEPLOY
|
||||||
echo 'u4R6tgCv*c8Fyc1ee' | sudo -S bash -c '
|
printf '%s\n' "${DEPLOY_SUDO_PASSWORD}" | sudo -S bash -c '
|
||||||
|
set -e
|
||||||
docker stop pounce-frontend 2>/dev/null || true
|
docker stop pounce-frontend 2>/dev/null || true
|
||||||
docker rm pounce-frontend 2>/dev/null || true
|
docker rm pounce-frontend 2>/dev/null || true
|
||||||
|
|
||||||
@ -166,7 +158,7 @@ curl -sf https://pounce.ch -o /dev/null && log "Frontend: ✅ Healthy"
|
|||||||
# Cleanup
|
# Cleanup
|
||||||
log "Cleaning up..."
|
log "Cleaning up..."
|
||||||
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ${SSH_USER}@${SERVER} \
|
ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no ${SSH_USER}@${SERVER} \
|
||||||
"echo 'u4R6tgCv*c8Fyc1ee' | sudo -S docker image prune -f" > /dev/null 2>&1
|
"printf '%s\n' \"${DEPLOY_SUDO_PASSWORD}\" | sudo -S docker image prune -f" > /dev/null 2>&1
|
||||||
|
|
||||||
log "=========================================="
|
log "=========================================="
|
||||||
log "🎉 DEPLOYMENT SUCCESSFUL!"
|
log "🎉 DEPLOYMENT SUCCESSFUL!"
|
||||||
|
|||||||
Reference in New Issue
Block a user