refactor(ops): standardize image-based production delivery
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
# Runtime settings consumed by the app and by docker-compose.cicd.yml on the target host.
|
||||
# Runtime settings consumed by the app and by docker-compose.prod.yml on the target host.
|
||||
|
||||
POSTGRES_PASSWORD=replace-with-a-long-random-password
|
||||
NEXTAUTH_URL=https://capakraken.example.com
|
||||
NEXTAUTH_SECRET=replace-with-a-long-random-secret
|
||||
RATE_LIMIT_BACKEND=redis
|
||||
|
||||
# Optional but commonly needed application settings.
|
||||
SENTRY_DSN=
|
||||
|
||||
+15
-10
@@ -1,11 +1,12 @@
|
||||
# Deploy Tooling
|
||||
|
||||
This directory contains the additive deployment scaffold for the image-based CI/CD target path.
|
||||
This directory contains the canonical host-side tooling for the image-based staging and production path.
|
||||
|
||||
## Files
|
||||
|
||||
- `deploy-compose.sh`: pulls images, runs migrations, starts the app, and waits for readiness
|
||||
- `deploy-compose.sh`: validates compose input, pulls images, runs migrations, starts the app, and waits for readiness
|
||||
- `.env.production.example`: example host-side runtime configuration
|
||||
- `deploy.env.example`: example short-lived deployment manifest written by GitHub Actions
|
||||
|
||||
## Host Layout
|
||||
|
||||
@@ -13,7 +14,7 @@ On the target host, the deploy directory should contain:
|
||||
|
||||
```text
|
||||
<deploy-path>/
|
||||
docker-compose.cicd.yml
|
||||
docker-compose.prod.yml
|
||||
deploy.env
|
||||
.env.production
|
||||
tooling/deploy/deploy-compose.sh
|
||||
@@ -25,16 +26,20 @@ On the target host, the deploy directory should contain:
|
||||
|
||||
1. Copy `tooling/deploy/.env.production.example` to the target host as `.env.production`.
|
||||
2. Fill in the required secrets and URLs.
|
||||
3. Provision runtime AI/SMTP/anonymization secrets on the host through `.env.production` or the platform's secret facility.
|
||||
4. Keep admin settings for status/verification only; do not use them to enter or rotate operational secrets.
|
||||
5. After migration, use the admin cleanup action to remove any legacy database-stored runtime secrets.
|
||||
6. Ensure Docker Engine and Docker Compose v2 are installed.
|
||||
7. Ensure the target host can pull from `ghcr.io`.
|
||||
8. Run the image release workflow, then the staging or production deploy workflow with the same image tag.
|
||||
3. Keep `RATE_LIMIT_BACKEND=redis` so production uses the shared counter path intentionally.
|
||||
4. Copy `tooling/deploy/deploy.env.example` to the host only if you want to dry-run the deploy script manually.
|
||||
5. Replace the placeholder images in `deploy.env.example` with a real `sha-<commit>` tag and save it as `deploy.env` for a manual dry run.
|
||||
6. Provision runtime AI/SMTP/anonymization secrets on the host through `.env.production` or the platform's secret facility.
|
||||
7. Keep admin settings for status/verification only; do not use them to enter or rotate operational secrets.
|
||||
8. After migration, use the admin cleanup action to remove any legacy database-stored runtime secrets.
|
||||
9. Ensure Docker Engine and Docker Compose v2 are installed.
|
||||
10. Ensure the target host can pull from `ghcr.io`.
|
||||
11. A normal release no longer needs a Git checkout on the host. The host only needs the deploy bundle plus the two env files.
|
||||
12. Merge to `main`, let `release-image.yml` publish the immutable images, then run the staging or production deploy workflow with the same image tag.
|
||||
|
||||
## Manual Host Test
|
||||
|
||||
After the files are present on the host, the flow can be tested manually:
|
||||
After the files are present on the host, the canonical flow can be tested manually:
|
||||
|
||||
```bash
|
||||
set -a
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
DEPLOY_ENV="${1:-unknown}"
|
||||
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.cicd.yml}"
|
||||
COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.prod.yml}"
|
||||
APP_ENV_FILE="${APP_ENV_FILE:-.env.production}"
|
||||
DEPLOY_ENV_FILE="${DEPLOY_ENV_FILE:-deploy.env}"
|
||||
READY_URL="${READY_URL:-http://127.0.0.1:${APP_HOST_PORT:-3000}/api/ready}"
|
||||
@@ -36,6 +36,7 @@ if [ -n "${GHCR_USERNAME:-}" ] && [ -n "${GHCR_TOKEN:-}" ]; then
|
||||
printf '%s\n' "${GHCR_TOKEN}" | docker login ghcr.io -u "${GHCR_USERNAME}" --password-stdin
|
||||
fi
|
||||
|
||||
docker compose -f "${COMPOSE_FILE}" config -q
|
||||
docker compose -f "${COMPOSE_FILE}" pull app migrator
|
||||
docker compose -f "${COMPOSE_FILE}" up -d postgres redis
|
||||
docker compose -f "${COMPOSE_FILE}" run --rm migrator
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
APP_IMAGE=ghcr.io/example/capakraken-app:sha-abc123
|
||||
MIGRATOR_IMAGE=ghcr.io/example/capakraken-migrator:sha-abc123
|
||||
APP_HOST_PORT=3000
|
||||
GHCR_USERNAME=
|
||||
GHCR_TOKEN=
|
||||
Reference in New Issue
Block a user