admin/scripts/ci-build-image.sh
alisaza 8d2e19ac7d fix(deploy): reject loopback API_PROXY_TARGET in production builds
Prevents baking self-proxy /api and /chat rewrites that pin a CPU core inside Docker.
2026-09-08 14:06:20 +03:30

70 lines
2.5 KiB
Bash
Executable File

#!/usr/bin/env bash
# Build and publish the production admin image in GitHub Actions.
# Build-time public variables are read from the VPS .env file and never logged.
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
ADMIN_ENV_FILE="${ADMIN_ENV_FILE:?ADMIN_ENV_FILE is required}"
IMAGE_REPO="${IMAGE_REPO:?IMAGE_REPO is required}"
IMAGE_TAG="${IMAGE_TAG:?IMAGE_TAG is required}"
[[ -s "$ADMIN_ENV_FILE" ]] || {
echo "Error: ADMIN_ENV_FILE is missing or empty: $ADMIN_ENV_FILE" >&2
exit 1
}
# shellcheck disable=SC1090
set -a
source "$ADMIN_ENV_FILE"
set +a
env_or_empty() {
local key="$1"
printf '%s' "${!key-}"
}
# Loopback targets bake self-proxy rewrites into the image and peg a CPU core in Docker.
sanitize_api_proxy_target() {
local target
target="$(env_or_empty API_PROXY_TARGET)"
case "$target" in
*127.0.0.1*|*localhost*|*'::1'*)
echo "Warning: refusing loopback API_PROXY_TARGET for production image build" >&2
printf ''
;;
*)
printf '%s' "$target"
;;
esac
}
BUILD_ARGS=(
--build-arg "NEXT_PUBLIC_API_URL=$(env_or_empty NEXT_PUBLIC_API_URL)"
--build-arg "NEXT_PUBLIC_FILE_SERVER_URL=$(env_or_empty NEXT_PUBLIC_FILE_SERVER_URL)"
--build-arg "MAP_API_KEY=$(env_or_empty MAP_API_KEY)"
--build-arg "NEXT_PUBLIC_MAP_API_KEY=$(env_or_empty NEXT_PUBLIC_MAP_API_KEY)"
--build-arg "NEXT_PUBLIC_VAPID_PUBLIC_KEY=$(env_or_empty NEXT_PUBLIC_VAPID_PUBLIC_KEY)"
--build-arg "NEXT_PUBLIC_BASE_PATH=$(env_or_empty NEXT_PUBLIC_BASE_PATH)"
--build-arg "NEXT_PUBLIC_SITE_URL=$(env_or_empty NEXT_PUBLIC_SITE_URL)"
--build-arg "NEXT_PUBLIC_OBSERVABILITY_ENDPOINT=$(env_or_empty NEXT_PUBLIC_OBSERVABILITY_ENDPOINT)"
--build-arg "NEXT_PUBLIC_SENTRY_DSN=$(env_or_empty NEXT_PUBLIC_SENTRY_DSN)"
--build-arg "NEXT_PUBLIC_SENTRY_ENVIRONMENT=$(env_or_empty NEXT_PUBLIC_SENTRY_ENVIRONMENT)"
--build-arg "NEXT_PUBLIC_SENTRY_TRACES_SAMPLE_RATE=$(env_or_empty NEXT_PUBLIC_SENTRY_TRACES_SAMPLE_RATE)"
--build-arg "NEXT_PUBLIC_ARCAPTCHA_SITE_KEY=$(env_or_empty NEXT_PUBLIC_ARCAPTCHA_SITE_KEY)"
--build-arg "SENTRY_AUTH_TOKEN=$(env_or_empty SENTRY_AUTH_TOKEN)"
--build-arg "SENTRY_ORG=$(env_or_empty SENTRY_ORG)"
--build-arg "SENTRY_PROJECT=$(env_or_empty SENTRY_PROJECT)"
--build-arg "API_PROXY_TARGET=$(sanitize_api_proxy_target)"
)
echo "Building ${IMAGE_REPO}:${IMAGE_TAG} (build arguments redacted)"
docker buildx build \
--platform linux/amd64 \
--push \
-t "${IMAGE_REPO}:${IMAGE_TAG}" \
-t "${IMAGE_REPO}:main" \
"${BUILD_ARGS[@]}" \
.