Compare commits
4 Commits
0606b71890
...
v1.0.10
| Author | SHA1 | Date | |
|---|---|---|---|
| 9936cfd544 | |||
| b42c36ebdd | |||
| 395199f9b2 | |||
| a37b259f47 |
@@ -261,17 +261,20 @@ jobs:
|
|||||||
PREV_DIGEST_TOKEN_SECRET=""
|
PREV_DIGEST_TOKEN_SECRET=""
|
||||||
PREV_VAPID_PUBLIC_KEY=""
|
PREV_VAPID_PUBLIC_KEY=""
|
||||||
PREV_VAPID_PRIVATE_KEY=""
|
PREV_VAPID_PRIVATE_KEY=""
|
||||||
|
PREV_REFRESH_TOKEN_EXPIRY_DAYS=""
|
||||||
if [ -f .env ]; then
|
if [ -f .env ]; then
|
||||||
PREV_SECRET_KEY=$(grep '^SECRET_KEY=' .env | head -n1 | cut -d '=' -f2- || true)
|
PREV_SECRET_KEY=$(grep '^SECRET_KEY=' .env | head -n1 | cut -d '=' -f2- || true)
|
||||||
PREV_DIGEST_TOKEN_SECRET=$(grep '^DIGEST_TOKEN_SECRET=' .env | head -n1 | cut -d '=' -f2- || true)
|
PREV_DIGEST_TOKEN_SECRET=$(grep '^DIGEST_TOKEN_SECRET=' .env | head -n1 | cut -d '=' -f2- || true)
|
||||||
PREV_VAPID_PUBLIC_KEY=$(grep '^VAPID_PUBLIC_KEY=' .env | head -n1 | cut -d '=' -f2- || true)
|
PREV_VAPID_PUBLIC_KEY=$(grep '^VAPID_PUBLIC_KEY=' .env | head -n1 | cut -d '=' -f2- || true)
|
||||||
PREV_VAPID_PRIVATE_KEY=$(grep '^VAPID_PRIVATE_KEY=' .env | head -n1 | cut -d '=' -f2- || true)
|
PREV_VAPID_PRIVATE_KEY=$(grep '^VAPID_PRIVATE_KEY=' .env | head -n1 | cut -d '=' -f2- || true)
|
||||||
|
PREV_REFRESH_TOKEN_EXPIRY_DAYS=$(grep '^REFRESH_TOKEN_EXPIRY_DAYS=' .env | head -n1 | cut -d '=' -f2- || true)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
SECRET_KEY_VALUE="${{ secrets.PROD_SECRET_KEY }}"
|
SECRET_KEY_VALUE="${{ secrets.PROD_SECRET_KEY }}"
|
||||||
DIGEST_TOKEN_SECRET_VALUE="${{ secrets.PROD_DIGEST_TOKEN_SECRET }}"
|
DIGEST_TOKEN_SECRET_VALUE="${{ secrets.PROD_DIGEST_TOKEN_SECRET }}"
|
||||||
VAPID_PUBLIC_KEY_VALUE="${{ secrets.PROD_VAPID_PUBLIC_KEY }}"
|
VAPID_PUBLIC_KEY_VALUE="${{ secrets.PROD_VAPID_PUBLIC_KEY }}"
|
||||||
VAPID_PRIVATE_KEY_VALUE="${{ secrets.PROD_VAPID_PRIVATE_KEY }}"
|
VAPID_PRIVATE_KEY_VALUE="${{ secrets.PROD_VAPID_PRIVATE_KEY }}"
|
||||||
|
REFRESH_TOKEN_EXPIRY_DAYS_VALUE="${{ secrets.PROD_REFRESH_TOKEN_EXPIRY_DAYS }}"
|
||||||
|
|
||||||
if [ -z "$SECRET_KEY_VALUE" ]; then
|
if [ -z "$SECRET_KEY_VALUE" ]; then
|
||||||
if [ -n "$PREV_SECRET_KEY" ]; then
|
if [ -n "$PREV_SECRET_KEY" ]; then
|
||||||
@@ -301,10 +304,25 @@ jobs:
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ -z "$REFRESH_TOKEN_EXPIRY_DAYS_VALUE" ]; then
|
||||||
|
if [ -n "$PREV_REFRESH_TOKEN_EXPIRY_DAYS" ]; then
|
||||||
|
REFRESH_TOKEN_EXPIRY_DAYS_VALUE="$PREV_REFRESH_TOKEN_EXPIRY_DAYS"
|
||||||
|
else
|
||||||
|
REFRESH_TOKEN_EXPIRY_DAYS_VALUE="90"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! printf '%s' "$REFRESH_TOKEN_EXPIRY_DAYS_VALUE" | grep -Eq '^[0-9]+$'; then
|
||||||
|
echo "REFRESH_TOKEN_EXPIRY_DAYS must be a positive integer, got: $REFRESH_TOKEN_EXPIRY_DAYS_VALUE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
cat > .env << EOF
|
cat > .env << EOF
|
||||||
FRONTEND_URL=${{ secrets.PROD_FRONTEND_URL }}
|
FRONTEND_URL=${{ secrets.PROD_FRONTEND_URL }}
|
||||||
|
BACKEND_HOST_PORT=${{ secrets.PROD_BACKEND_HOST_PORT }}
|
||||||
|
FRONTEND_HOST_PORT=${{ secrets.PROD_FRONTEND_HOST_PORT }}
|
||||||
SECRET_KEY=${SECRET_KEY_VALUE}
|
SECRET_KEY=${SECRET_KEY_VALUE}
|
||||||
REFRESH_TOKEN_EXPIRY_DAYS=${{ secrets.PROD_REFRESH_TOKEN_EXPIRY_DAYS }}
|
REFRESH_TOKEN_EXPIRY_DAYS=${REFRESH_TOKEN_EXPIRY_DAYS_VALUE}
|
||||||
DIGEST_TOKEN_SECRET=${DIGEST_TOKEN_SECRET_VALUE}
|
DIGEST_TOKEN_SECRET=${DIGEST_TOKEN_SECRET_VALUE}
|
||||||
VAPID_PUBLIC_KEY=${VAPID_PUBLIC_KEY_VALUE}
|
VAPID_PUBLIC_KEY=${VAPID_PUBLIC_KEY_VALUE}
|
||||||
VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY_VALUE}
|
VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY_VALUE}
|
||||||
@@ -316,7 +334,52 @@ jobs:
|
|||||||
|
|
||||||
chmod 600 .env .rollback-meta
|
chmod 600 .env .rollback-meta
|
||||||
|
|
||||||
|
backend_host_port=$(grep '^BACKEND_HOST_PORT=' .env | head -n1 | cut -d '=' -f2- || true)
|
||||||
|
frontend_host_port=$(grep '^FRONTEND_HOST_PORT=' .env | head -n1 | cut -d '=' -f2- || true)
|
||||||
|
if [ -z "$backend_host_port" ]; then
|
||||||
|
backend_host_port="5001"
|
||||||
|
fi
|
||||||
|
if [ -z "$frontend_host_port" ]; then
|
||||||
|
frontend_host_port="4601"
|
||||||
|
fi
|
||||||
|
|
||||||
docker-compose down
|
docker-compose down
|
||||||
|
|
||||||
|
wait_for_container_removal() {
|
||||||
|
container_name="$1"
|
||||||
|
attempts=0
|
||||||
|
while docker ps -a --format '{{.Names}}' | grep -qx "$container_name"; do
|
||||||
|
attempts=$((attempts + 1))
|
||||||
|
if [ "$attempts" -ge 12 ]; then
|
||||||
|
echo "Container ${container_name} still exists after waiting for teardown."
|
||||||
|
docker ps -a --filter "name=^${container_name}$"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "Waiting for ${container_name} to be removed..."
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_port_release() {
|
||||||
|
port="$1"
|
||||||
|
attempts=0
|
||||||
|
while docker ps -a --format '{{.ID}} {{.Names}} {{.Ports}} {{.Status}}' | grep -E "(^|[[:space:]])0\.0\.0\.0:${port}->|:::${port}->" >/dev/null 2>&1; do
|
||||||
|
attempts=$((attempts + 1))
|
||||||
|
if [ "$attempts" -ge 12 ]; then
|
||||||
|
echo "Port ${port} is still allocated after teardown. Blocking container(s):"
|
||||||
|
docker ps -a --format '{{.ID}} {{.Names}} {{.Ports}} {{.Status}}' | grep -E "(^|[[:space:]])0\.0\.0\.0:${port}->|:::${port}->" || true
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo "Waiting for port ${port} to be released..."
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
wait_for_container_removal chores-app-frontend-prod
|
||||||
|
wait_for_container_removal chores-app-backend-prod
|
||||||
|
wait_for_port_release "$frontend_host_port"
|
||||||
|
wait_for_port_release "$backend_host_port"
|
||||||
|
|
||||||
docker-compose pull
|
docker-compose pull
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
|
|
||||||
@@ -326,18 +389,22 @@ jobs:
|
|||||||
frontend_running=$(docker inspect -f '{{.State.Running}}' chores-app-frontend-prod 2>/dev/null || echo false)
|
frontend_running=$(docker inspect -f '{{.State.Running}}' chores-app-frontend-prod 2>/dev/null || echo false)
|
||||||
|
|
||||||
backend_ok=false
|
backend_ok=false
|
||||||
if curl -fsS http://localhost:5001/version >/dev/null 2>&1; then
|
if curl -fsS "http://localhost:${backend_host_port}/version" >/dev/null 2>&1; then
|
||||||
backend_ok=true
|
backend_ok=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
frontend_ok=false
|
frontend_ok=false
|
||||||
if curl -kfsS https://localhost/ >/dev/null 2>&1; then
|
if curl -kfsS "https://localhost:${frontend_host_port}/" >/dev/null 2>&1; then
|
||||||
frontend_ok=true
|
frontend_ok=true
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$backend_running" != "true" ] || [ "$frontend_running" != "true" ] || [ "$backend_ok" != "true" ] || [ "$frontend_ok" != "true" ]; then
|
if [ "$backend_running" != "true" ] || [ "$frontend_running" != "true" ] || [ "$backend_ok" != "true" ] || [ "$frontend_ok" != "true" ]; then
|
||||||
echo "Post-deploy health check failed."
|
echo "Post-deploy health check failed."
|
||||||
docker-compose ps
|
docker-compose ps
|
||||||
|
echo "--- Backend logs (last 200 lines) ---"
|
||||||
|
docker logs --tail 200 chores-app-backend-prod || true
|
||||||
|
echo "--- Frontend logs (last 120 lines) ---"
|
||||||
|
docker logs --tail 120 chores-app-frontend-prod || true
|
||||||
|
|
||||||
if [ "${{ github.event.inputs.rollback_on_failed_healthcheck }}" = "true" ]; then
|
if [ "${{ github.event.inputs.rollback_on_failed_healthcheck }}" = "true" ]; then
|
||||||
echo "Attempting rollback using predeploy-backup image tags..."
|
echo "Attempting rollback using predeploy-backup image tags..."
|
||||||
@@ -345,7 +412,7 @@ jobs:
|
|||||||
docker tag git.ryankegel.com:3000/kegel/chores/frontend:predeploy-backup git.ryankegel.com:3000/kegel/chores/frontend:latest || true
|
docker tag git.ryankegel.com:3000/kegel/chores/frontend:predeploy-backup git.ryankegel.com:3000/kegel/chores/frontend:latest || true
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
sleep 20
|
sleep 20
|
||||||
curl -fsS http://localhost:5001/version >/dev/null
|
curl -fsS "http://localhost:${backend_host_port}/version" >/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -6,10 +6,15 @@ services:
|
|||||||
image: git.ryankegel.com:3000/kegel/chores/backend:latest # Or specific version tag
|
image: git.ryankegel.com:3000/kegel/chores/backend:latest # Or specific version tag
|
||||||
container_name: chores-app-backend-prod # Added for easy identification
|
container_name: chores-app-backend-prod # Added for easy identification
|
||||||
ports:
|
ports:
|
||||||
- "5001:5000" # Host 5001 -> Container 5000
|
- "${BACKEND_HOST_PORT:-5001}:5000" # Host port -> Container 5000
|
||||||
environment:
|
environment:
|
||||||
- FLASK_ENV=production
|
- FLASK_ENV=production
|
||||||
- FRONTEND_URL=${FRONTEND_URL}
|
- FRONTEND_URL=${FRONTEND_URL}
|
||||||
|
- SECRET_KEY=${SECRET_KEY}
|
||||||
|
- REFRESH_TOKEN_EXPIRY_DAYS=${REFRESH_TOKEN_EXPIRY_DAYS}
|
||||||
|
- DIGEST_TOKEN_SECRET=${DIGEST_TOKEN_SECRET}
|
||||||
|
- VAPID_PUBLIC_KEY=${VAPID_PUBLIC_KEY}
|
||||||
|
- VAPID_PRIVATE_KEY=${VAPID_PRIVATE_KEY}
|
||||||
volumes:
|
volumes:
|
||||||
- chores-app-backend-data:/app/data # Assuming backend data storage; adjust path as needed
|
- chores-app-backend-data:/app/data # Assuming backend data storage; adjust path as needed
|
||||||
networks:
|
networks:
|
||||||
@@ -20,7 +25,7 @@ services:
|
|||||||
image: git.ryankegel.com:3000/kegel/chores/frontend:latest # Or specific version tag
|
image: git.ryankegel.com:3000/kegel/chores/frontend:latest # Or specific version tag
|
||||||
container_name: chores-app-frontend-prod # Added for easy identification
|
container_name: chores-app-frontend-prod # Added for easy identification
|
||||||
ports:
|
ports:
|
||||||
- "443:443" # Host 443 -> Container 443 (HTTPS)
|
- "${FRONTEND_HOST_PORT:-4601}:443" # Host port -> Container 443 (HTTPS)
|
||||||
environment:
|
environment:
|
||||||
- BACKEND_HOST=chores-app-backend # Points to internal backend service
|
- BACKEND_HOST=chores-app-backend # Points to internal backend service
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
Reference in New Issue
Block a user