#!/usr/bin/env bash set -euo pipefail IMAGE="${1:-}" ENV_FILE="${2:-}" HOST_PORT="${3:-}" CONTAINER_NAME="${4:-}" PROJECT_NAME="${5:-}" SERVER_RETAIN_COUNT="${6:-0}" if [ -z "$IMAGE" ] || [ -z "$ENV_FILE" ] || [ -z "$HOST_PORT" ] || [ -z "$CONTAINER_NAME" ] || [ -z "$PROJECT_NAME" ]; then echo "Usage: $0 [server-retain-count]" >&2 exit 64 fi if [ ! -f "docker-compose.yml" ]; then echo "Missing docker-compose.yml in $(pwd)" >&2 exit 66 fi if [ ! -f "$ENV_FILE" ]; then echo "Missing env file: $ENV_FILE" >&2 exit 66 fi if docker compose version >/dev/null 2>&1; then COMPOSE=(docker compose) elif command -v docker-compose >/dev/null 2>&1; then COMPOSE=(docker-compose) else echo "docker compose command not found" >&2 exit 127 fi export COZSWEET_IMAGE="$IMAGE" export COZSWEET_ENV_FILE="$ENV_FILE" export COZSWEET_HOST_PORT="$HOST_PORT" export COZSWEET_CONTAINER_NAME="$CONTAINER_NAME" export COMPOSE_PROJECT_NAME="$PROJECT_NAME" echo "=== deploy image: $COZSWEET_IMAGE ===" echo "=== env file: $COZSWEET_ENV_FILE ===" echo "=== host port: $COZSWEET_HOST_PORT ===" echo "=== container: $COZSWEET_CONTAINER_NAME ===" echo "=== compose project: $COMPOSE_PROJECT_NAME ===" "${COMPOSE[@]}" pull web "${COMPOSE[@]}" up -d --remove-orphans --no-build web "${COMPOSE[@]}" ps docker image prune -f prune_project_images() { local retain_count="$1" if ! [[ "$retain_count" =~ ^[0-9]+$ ]] || [ "$retain_count" -le 0 ]; then return 0 fi local image_repo="${IMAGE%%:*}" local image_tag="${IMAGE##*:}" local tag_prefix="${image_tag%%-*}-" if [ -z "$image_repo" ] || [ "$image_repo" = "$IMAGE" ] || [ -z "$tag_prefix" ]; then echo "Skip project image prune: could not parse image repo/tag from $IMAGE" return 0 fi echo "=== prune local project images: keep $retain_count for $tag_prefix ===" docker image ls "$image_repo" \ --format '{{.Repository}}:{{.Tag}} {{.CreatedAt}}' \ | awk -v prefix="$tag_prefix" '$1 ~ ":" prefix && $1 !~ /-latest$/ { print }' \ | sort -k2,3r \ | awk -v keep="$retain_count" 'NR > keep { print $1 }' \ | while IFS= read -r old_image; do [ -n "$old_image" ] || continue if [ "$old_image" = "$IMAGE" ]; then continue fi echo "Removing local image: $old_image" docker image rm "$old_image" || true done } prune_project_images "$SERVER_RETAIN_COUNT" echo "=== deploy done ==="