120 lines
3.1 KiB
Bash
Executable File
120 lines
3.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$SCRIPT_DIR"
|
|
|
|
BACKEND_ENV_FILE="$SCRIPT_DIR/backend/.env"
|
|
|
|
PROFILE="${1:-current}"
|
|
|
|
case "$PROFILE" in
|
|
master)
|
|
PROFILE_ENV_FILE="$SCRIPT_DIR/.env.master"
|
|
PROJECT_NAME="ss-tools-master"
|
|
;;
|
|
current)
|
|
PROFILE_ENV_FILE="$SCRIPT_DIR/.env.current"
|
|
PROJECT_NAME="ss-tools-current"
|
|
;;
|
|
*)
|
|
echo "Error: unknown profile '$PROFILE'. Use one of: master, current."
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
if ! command -v docker >/dev/null 2>&1; then
|
|
echo "Error: docker is not installed or not in PATH."
|
|
exit 1
|
|
fi
|
|
|
|
if docker compose version >/dev/null 2>&1; then
|
|
COMPOSE_CMD=(docker compose)
|
|
elif command -v docker-compose >/dev/null 2>&1; then
|
|
COMPOSE_CMD=(docker-compose)
|
|
else
|
|
echo "Error: docker compose is not available."
|
|
exit 1
|
|
fi
|
|
|
|
ensure_backend_encryption_key() {
|
|
if command -v python3 >/dev/null 2>&1; then
|
|
python3 - "$BACKEND_ENV_FILE" <<'PY'
|
|
import base64
|
|
import os
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
|
|
def is_valid_fernet_key(raw_value: str) -> bool:
|
|
value = raw_value.strip()
|
|
if not value:
|
|
return False
|
|
|
|
try:
|
|
decoded = base64.urlsafe_b64decode(value.encode())
|
|
except Exception:
|
|
return False
|
|
|
|
return len(decoded) == 32
|
|
|
|
|
|
def generate_fernet_key() -> str:
|
|
return base64.urlsafe_b64encode(os.urandom(32)).decode()
|
|
|
|
|
|
env_path = Path(sys.argv[1])
|
|
env_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
existing_lines: list[str] = []
|
|
existing_key: str | None = None
|
|
|
|
if env_path.exists():
|
|
existing_lines = env_path.read_text(encoding="utf-8").splitlines()
|
|
for line in existing_lines:
|
|
if line.startswith("ENCRYPTION_KEY="):
|
|
candidate = line.partition("=")[2].strip()
|
|
if is_valid_fernet_key(candidate):
|
|
existing_key = candidate
|
|
break
|
|
|
|
if existing_key is None:
|
|
generated_key = generate_fernet_key()
|
|
filtered_lines = [line for line in existing_lines if not line.startswith("ENCRYPTION_KEY=")]
|
|
filtered_lines.append(f"ENCRYPTION_KEY={generated_key}")
|
|
env_path.write_text("\n".join(filtered_lines) + "\n", encoding="utf-8")
|
|
print(f"[build] ENCRYPTION_KEY ensured in {env_path}")
|
|
else:
|
|
print(f"[build] Existing ENCRYPTION_KEY reused from {env_path}")
|
|
PY
|
|
return
|
|
fi
|
|
|
|
echo "Error: python3 is required to generate backend/.env with ENCRYPTION_KEY."
|
|
exit 1
|
|
}
|
|
|
|
ensure_backend_encryption_key
|
|
|
|
COMPOSE_ARGS=(-p "$PROJECT_NAME")
|
|
if [[ -f "$PROFILE_ENV_FILE" ]]; then
|
|
COMPOSE_ARGS+=(--env-file "$PROFILE_ENV_FILE")
|
|
else
|
|
echo "[build] Warning: profile env file not found at $PROFILE_ENV_FILE, using compose defaults."
|
|
fi
|
|
|
|
echo "[build] Profile: $PROFILE (project: $PROJECT_NAME)"
|
|
if [[ -f "$PROFILE_ENV_FILE" ]]; then
|
|
echo "[build] Env file: $PROFILE_ENV_FILE"
|
|
fi
|
|
|
|
echo "[1/2] Building project images..."
|
|
"${COMPOSE_CMD[@]}" "${COMPOSE_ARGS[@]}" build
|
|
|
|
echo "[2/2] Starting Docker services..."
|
|
"${COMPOSE_CMD[@]}" "${COMPOSE_ARGS[@]}" up -d
|
|
|
|
echo "Done. Services are running."
|
|
echo "Use '${COMPOSE_CMD[*]} ${COMPOSE_ARGS[*]} ps' to check status and '${COMPOSE_CMD[*]} ${COMPOSE_ARGS[*]} logs -f' to stream logs."
|