- #!/usr/bin/env bash
- set -Eeuo pipefail
-
- # Apply an incremental image update on the target runtime server.
- # Usage:
- # bash apply-update.sh
- # bash apply-update.sh emp-admin emp-monitor
- # DEPLOY_ENV=emp-uat ENV_FILE=.env COMPOSE_FILE=docker-compose.yml bash apply-update.sh
- # COMPOSE_FILES="/path/docker-compose.yml:/path/docker-compose.logs.yml" bash apply-update.sh
-
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
- cd "$SCRIPT_DIR"
-
- DEPLOY_ENV="${DEPLOY_ENV:-emp-test}"
- PROJECT_NAME="${PROJECT_NAME:-$DEPLOY_ENV}"
- DEPLOY_HOME="${DEPLOY_HOME:-/home/admin-x99/$DEPLOY_ENV}"
- ENV_FILE="${ENV_FILE:-.env}"
- COMPOSE_FILE="${COMPOSE_FILE:-docker-compose.yml}"
- COMPOSE_FILES="${COMPOSE_FILES:-}"
- IMAGE_TAR="${IMAGE_TAR:-images.tar}"
- SERVICE_FILE="${SERVICE_FILE:-services.txt}"
-
- log() {
- echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
- }
-
- die() {
- echo "ERROR: $*" >&2
- exit 1
- }
-
- need_cmd() {
- command -v "$1" >/dev/null 2>&1 || die "Missing command: $1"
- }
-
- normalize_service() {
- case "$1" in
- gateway|emp-gateway) echo "emp-gateway" ;;
- auth|emp-auth) echo "emp-auth" ;;
- monitor|emp-monitor) echo "emp-monitor" ;;
- data|emp-data) echo "emp-data" ;;
- pdf|emp-pdf) echo "emp-pdf" ;;
- ws|emp-ws) echo "emp-ws" ;;
- admin|emp-admin) echo "emp-admin" ;;
- *) die "Unknown service: $1. Allowed: gateway auth monitor data pdf ws admin" ;;
- esac
- }
-
- resolve_compose_cmd() {
- if docker compose version >/dev/null 2>&1; then
- echo "docker compose"
- elif command -v docker-compose >/dev/null 2>&1; then
- echo "docker-compose"
- else
- die "Missing docker compose"
- fi
- }
-
- resolve_runtime_file() {
- local requested="$1"
- local default_name="$2"
- if [[ -f "$requested" ]]; then
- echo "$requested"
- return
- fi
- if [[ "$requested" != "$default_name" ]]; then
- echo "$requested"
- return
- fi
-
- local candidates=(
- "../runtime/$default_name"
- "$DEPLOY_HOME/runtime/$default_name"
- "$DEPLOY_HOME/$default_name"
- "/opt/$DEPLOY_ENV/$default_name"
- )
- local candidate
- for candidate in "${candidates[@]}"; do
- if [[ -f "$candidate" ]]; then
- echo "$candidate"
- return
- fi
- done
-
- echo "$requested"
- }
-
- resolve_compose_files() {
- local raw_files=()
- local file resolved
- if [[ -n "$COMPOSE_FILES" ]]; then
- IFS=':' read -r -a raw_files <<< "$COMPOSE_FILES"
- else
- raw_files=("$COMPOSE_FILE")
- fi
-
- COMPOSE_ARGS=()
- RESOLVED_COMPOSE_FILES=()
- for file in "${raw_files[@]}"; do
- [[ -n "$file" ]] || continue
- resolved="$(resolve_runtime_file "$file" "docker-compose.yml")"
- [[ -f "$resolved" ]] || die "Missing compose file: $resolved"
- RESOLVED_COMPOSE_FILES+=("$resolved")
- COMPOSE_ARGS+=("-f" "$resolved")
- done
-
- [[ "${#COMPOSE_ARGS[@]}" -gt 0 ]] || die "No compose files resolved."
- }
-
- read_services() {
- local raw_services=()
- if [[ "$#" -gt 0 ]]; then
- raw_services=("$@")
- elif [[ -f "$SERVICE_FILE" ]]; then
- mapfile -t raw_services < "$SERVICE_FILE"
- else
- die "No services specified. Pass services as args or provide $SERVICE_FILE."
- fi
-
- local service
- for service in "${raw_services[@]}"; do
- [[ -n "$service" ]] || continue
- normalize_service "$service"
- done
- }
-
- need_cmd docker
- ENV_FILE="$(resolve_runtime_file "$ENV_FILE" ".env")"
- resolve_compose_files
- [[ -f "$ENV_FILE" ]] || die "Missing env file: $ENV_FILE"
- [[ -f "$IMAGE_TAR" ]] || die "Missing image tar: $IMAGE_TAR"
-
- mapfile -t UPDATE_SERVICES < <(read_services "$@")
- [[ "${#UPDATE_SERVICES[@]}" -gt 0 ]] || die "No services to update."
-
- COMPOSE_CMD="$(resolve_compose_cmd)"
-
- log "Compose files: ${RESOLVED_COMPOSE_FILES[*]}"
- log "Load images: $IMAGE_TAR"
- docker load -i "$IMAGE_TAR"
-
- log "Recreate services: ${UPDATE_SERVICES[*]}"
- # shellcheck disable=SC2086
- $COMPOSE_CMD \
- --env-file "$ENV_FILE" \
- "${COMPOSE_ARGS[@]}" \
- -p "$PROJECT_NAME" \
- up -d --no-deps --force-recreate "${UPDATE_SERVICES[@]}"
-
- log "Current service status"
- # shellcheck disable=SC2086
- $COMPOSE_CMD \
- --env-file "$ENV_FILE" \
- "${COMPOSE_ARGS[@]}" \
- -p "$PROJECT_NAME" \
- ps "${UPDATE_SERVICES[@]}"
|