feat(docker): prepare portable images with runtime hotel configuration
This commit is contained in:
1 parent
745d0b7247
commit
c4496e710b
28 files changed
+622
-104
No files matched your search
@@ -10,6 +10,7 @@ mkdir -p "$(dirname "$LOG_FILE")"
|
||||
log() { printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" | tee -a "$LOG_FILE"; }
|
||||
die() { log "ERROR: $*"; exit 1; }
|
||||
migration_image=""
|
||||
remote_migration_image=""
|
||||
previous_image=""
|
||||
previous_release=""
|
||||
rollback_tag=""
|
||||
@@ -45,6 +46,7 @@ finish() {
|
||||
fi
|
||||
fi
|
||||
if [[ -n "$migration_image" ]]; then docker image rm "$migration_image" >>"$LOG_FILE" 2>&1 || true; fi
|
||||
if [[ -n "$remote_migration_image" ]]; then docker image rm "$remote_migration_image" >>"$LOG_FILE" 2>&1 || true; fi
|
||||
# Keep the recovery tag on failure for manual recovery, including same-commit rebuilds.
|
||||
if [[ ( "$status" = 0 || "$cutover" = 0 ) && -n "$rollback_tag" ]]; then docker image rm "epicnext-cms:$rollback_tag" >>"$LOG_FILE" 2>&1 || true; fi
|
||||
exit "$status"
|
||||
@@ -81,15 +83,27 @@ if [[ -n "$previous_container" ]]; then
|
||||
docker image tag "$previous_image" "epicnext-cms:$rollback_tag"
|
||||
fi
|
||||
log "Building release $CMS_RELEASE from $DIR"
|
||||
# The builder contains the matching migration source and locked dependencies.
|
||||
# The migrations stage contains matching source and locked dependencies.
|
||||
# No Node/package manager installation on the host is required.
|
||||
migration_image="epicnext-cms-migrations:$CMS_RELEASE"
|
||||
docker build --network=host --target builder --build-arg NEXT_DEPLOYMENT_ID="$CMS_RELEASE" -t "$migration_image" . >>"$LOG_FILE" 2>&1
|
||||
docker compose build --build-arg NEXT_DEPLOYMENT_ID="$CMS_RELEASE" cms >>"$LOG_FILE" 2>&1
|
||||
if [[ -n "${CMS_IMAGE_REPOSITORY:-}" ]]; then
|
||||
[[ "$CMS_IMAGE_REPOSITORY" =~ ^[a-z0-9.-]+(:[0-9]+)?/[a-z0-9._/-]+$ ]] || die "Invalid CMS_IMAGE_REPOSITORY; use registry/owner/image without a tag."
|
||||
log "Pulling prebuilt application and matching migrations for $CMS_RELEASE"
|
||||
docker pull "$CMS_IMAGE_REPOSITORY:$CMS_RELEASE" >>"$LOG_FILE" 2>&1
|
||||
remote_migration_image="$CMS_IMAGE_REPOSITORY:$CMS_RELEASE-migrations"
|
||||
docker pull "$remote_migration_image" >>"$LOG_FILE" 2>&1
|
||||
docker tag "$CMS_IMAGE_REPOSITORY:$CMS_RELEASE" "epicnext-cms:$CMS_RELEASE"
|
||||
docker tag "$CMS_IMAGE_REPOSITORY:$CMS_RELEASE-migrations" "$migration_image"
|
||||
else
|
||||
docker build --network=host --target migrations --build-arg NEXT_DEPLOYMENT_ID="$CMS_RELEASE" -t "$migration_image" . >>"$LOG_FILE" 2>&1
|
||||
docker compose build --build-arg NEXT_DEPLOYMENT_ID="$CMS_RELEASE" cms >>"$LOG_FILE" 2>&1
|
||||
fi
|
||||
expected_image="$(docker image inspect --format '{{.Id}}' "epicnext-cms:$CMS_RELEASE")"
|
||||
revision="$(docker image inspect --format '{{index .Config.Labels "org.opencontainers.image.revision"}}' "$expected_image")"
|
||||
[[ "$revision" = "$CMS_RELEASE" ]] || die "Built image has revision $revision, expected $CMS_RELEASE."
|
||||
docker run --rm --network host --entrypoint pnpm "$migration_image" db:migrate >>"$LOG_FILE" 2>&1
|
||||
migration_mounts=(--mount "type=bind,source=$DIR/.env,target=/app/.env,readonly")
|
||||
if [[ -f "$DIR/.env.local" ]]; then migration_mounts+=(--mount "type=bind,source=$DIR/.env.local,target=/app/.env.local,readonly"); fi
|
||||
docker run --rm --network host "${migration_mounts[@]}" --entrypoint pnpm "$migration_image" db:migrate >>"$LOG_FILE" 2>&1
|
||||
log "Build and migrations completed; recreating only the CMS service."
|
||||
cutover=1
|
||||
docker compose up -d --no-deps --no-build --force-recreate cms >>"$LOG_FILE" 2>&1
|
||||
@@ -120,6 +134,11 @@ for release in "${releases[@]}"; do
|
||||
if [[ "${#kept[@]}" -lt 2 ]]; then kept+=("$release"); continue; fi
|
||||
# Even stopped containers belonging to other deployments protect an image.
|
||||
if users="$(docker ps -aq --filter "ancestor=epicnext-cms:$release")" && [[ -z "$users" ]] && docker image rm "epicnext-cms:$release" >>"$LOG_FILE" 2>&1; then
|
||||
if [[ -n "${CMS_IMAGE_REPOSITORY:-}" ]]; then
|
||||
if remote_users="$(docker ps -aq --filter "ancestor=$CMS_IMAGE_REPOSITORY:$release")" && [[ -z "$remote_users" ]]; then
|
||||
docker image rm "$CMS_IMAGE_REPOSITORY:$release" >>"$LOG_FILE" 2>&1 || true
|
||||
fi
|
||||
fi
|
||||
log "Removed superseded release tag $release"
|
||||
else
|
||||
pending+=("$release")
|
||||
|
||||
Reference in new issue
Block a user