diff --git a/package.json b/package.json index 622656a..c1a4882 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "docker:prod:start:registry": "bash scripts/docker-prod-up-registry.sh", "docker:registry:local:start": "bash scripts/docker-registry-local-up.sh", "docker:prod:deploy": "bash scripts/docker-prod-deploy.sh", + "docker:prod:run:pulled": "bash scripts/docker-prod-run-pulled-image.sh", "docker:prod:up": "bash scripts/docker-prod-up-all.sh", "docker:prod:down": "docker compose -p rentaldrivego-prod --env-file .env.docker.production -f docker-compose.production.yml down", "docker:prod:backup": "bash scripts/docker-prod-backup.sh", diff --git a/scripts/docker-prod-run-pulled-image.sh b/scripts/docker-prod-run-pulled-image.sh new file mode 100644 index 0000000..b2fe81e --- /dev/null +++ b/scripts/docker-prod-run-pulled-image.sh @@ -0,0 +1,102 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +source "${ROOT_DIR}/scripts/docker-prod-common.sh" + +APP_IMAGE="${APP_IMAGE:-registry.rentaldrivego.ma/rentaldrivego/car_management_system}" +APP_VERSION="${APP_VERSION:-${1:-}}" +REGISTRY_USER="${REGISTRY_USER:-rentaldrivego_registry}" +INCLUDE_PGMANAGE="${INCLUDE_PGMANAGE:-0}" +POSTGRES_CONTAINER="${PROJECT_NAME}-postgres-1" +REDIS_CONTAINER="${PROJECT_NAME}-redis-1" + +require_release_image +ensure_env_file +ensure_api_uploads_volume + +container_health_status() { + local container_name="$1" + docker inspect --format='{{if .State.Health}}{{.State.Health.Status}}{{else}}{{.State.Status}}{{end}}' "${container_name}" 2>/dev/null || echo "missing" +} + +ensure_postgres_ready() { + local status + status="$(container_health_status "${POSTGRES_CONTAINER}")" + + if [[ "${status}" == "healthy" ]]; then + echo "Postgres is already healthy; reusing existing database container." + return 0 + fi + + echo "Starting Postgres" + prod_compose up -d postgres + wait_for_healthy postgres 120 +} + +ensure_redis_ready() { + local status + status="$(container_health_status "${REDIS_CONTAINER}")" + + if [[ "${status}" == "running" || "${status}" == "healthy" ]]; then + echo "Redis is already running; leaving it in place." + return 0 + fi + + echo "Starting Redis" + prod_compose up -d redis +} + +prompt_registry_password_if_needed() { + if [[ -z "${REGISTRY_HOST:-}" ]]; then + return 0 + fi + + if [[ -n "${REGISTRY_PASSWORD:-}" ]]; then + return 0 + fi + + if [[ ! -t 0 ]]; then + echo "REGISTRY_PASSWORD is not set and no interactive terminal is available for a prompt." >&2 + exit 1 + fi + + printf 'Registry password for %s@%s: ' "${REGISTRY_USER}" "${REGISTRY_HOST}" >&2 + read -r -s REGISTRY_PASSWORD + printf '\n' >&2 + export REGISTRY_PASSWORD +} + +echo "Starting production services from pulled image ${APP_IMAGE}:${APP_VERSION}" + +prompt_registry_password_if_needed + +echo "Logging into registry if configured" +login_registry_if_configured + +echo "Pulling release images" +pull_prod_release_images + +ensure_postgres_ready +ensure_redis_ready + +echo "Migration status" +prod_compose run --rm --entrypoint sh migrate -lc 'npx prisma migrate status --schema packages/database/prisma/schema.prisma' + +echo "Applying migrations" +prod_compose run --rm migrate + +echo "Starting application services" +app_services=(api marketplace dashboard admin) +if [[ "${INCLUDE_PGMANAGE}" == "1" ]]; then + app_services+=(pgmanage) +fi + +prod_compose up -d "${app_services[@]}" +wait_for_healthy api 180 +wait_for_healthy marketplace 180 +wait_for_healthy dashboard 180 +wait_for_healthy admin 180 + +echo "Production services are up from ${APP_IMAGE}:${APP_VERSION}"