From 76d01c66d67e8f257fc53972905dbf5edbe69184 Mon Sep 17 00:00:00 2001 From: Timothy Kim Date: Thu, 19 Mar 2026 12:28:49 -0400 Subject: [PATCH] fix deploy: use compose up instead of down+up, fetch secrets individually - docker compose up -d --remove-orphans instead of down then up - configure.sh delegates all service deployment to deploy.sh - deploy.sh generates .env from bws before starting services - remove 2>/dev/null from bws calls so errors are visible --- scripts/configure.sh | 76 +++++--------------------------------------- scripts/deploy.sh | 27 ++++++++++++++-- tools/new-app.sh | 2 +- tools/remove-app.sh | 2 +- 4 files changed, 35 insertions(+), 72 deletions(-) diff --git a/scripts/configure.sh b/scripts/configure.sh index e8fd5e3..464ae35 100755 --- a/scripts/configure.sh +++ b/scripts/configure.sh @@ -2,7 +2,7 @@ set -euo pipefail # Idempotent server configuration. Safe to run from CI or manually. -# Uses bws to generate .env files for services that need secrets. +# Delegates service deployment (including .env generation) to deploy.sh. REPO_DIR="/opt/hantim" @@ -34,75 +34,15 @@ else echo "0 3 * * * root certbot renew --quiet" > /etc/cron.d/certbot-renew fi -echo "==> Issuing SSL certificates..." -# Stop nginx if running so certbot can bind to port 80 -docker stop nginx 2>/dev/null || true -for conf in "$REPO_DIR"/docker/nginx/conf.d/*.conf; do - # Derive cert name from config filename (e.g. example.com.conf -> example.com) - cert_name=$(basename "$conf" .conf) - domains=$(grep -oP 'server_name\s+\K[^;]+' "$conf" | tr ' ' '\n' | sort -u) - if [ -z "$domains" ]; then - continue - fi - if [ -d "/etc/letsencrypt/live/$cert_name" ]; then - echo " Cert for $cert_name already exists, skipping." - continue - fi - domain_args="" - for d in $domains; do - domain_args="$domain_args -d $d" - done - echo " Issuing cert for: $cert_name ($domains)" - certbot certonly --standalone --non-interactive --agree-tos --register-unsafely-without-email --cert-name "$cert_name" $domain_args -done - -echo "==> Generating .env files from Bitwarden Secrets Manager..." -BWS_TOKEN_FILE="/etc/bws-token" -if [ -f "$BWS_TOKEN_FILE" ]; then - export BWS_ACCESS_TOKEN - BWS_ACCESS_TOKEN=$(cat "$BWS_TOKEN_FILE") - ALL_SECRETS=$(bws secret list) - for keys_file in "$REPO_DIR"/docker/*/.env.keys; do - [ -f "$keys_file" ] || continue - app_dir=$(dirname "$keys_file") - app_name=$(basename "$app_dir") - env_content="" - while IFS= read -r line || [ -n "$line" ]; do - [ -z "$line" ] && continue - var_name="${line%%=*}" - secret_key="${line#*=}" - value=$(echo "$ALL_SECRETS" | jq -r --arg key "$secret_key" '.[] | select(.key == $key) | .value') - if [ -z "$value" ]; then - echo " WARNING: Secret '$secret_key' not found in bws, skipping." - continue - fi - env_content="${env_content}${var_name}=${value}"$'\n' - done < "$keys_file" - if [ -n "$env_content" ]; then - echo " Writing .env for $app_name" - printf "%s" "$env_content" > "$app_dir/.env" - chmod 600 "$app_dir/.env" - fi - done -else - echo " No bws token found, skipping .env generation." -fi - -echo "==> Starting services..." -# Start nginx first (creates the shared network) -cd "$REPO_DIR/docker/nginx" -docker compose up -d -# Start all other apps +echo "==> Deploying services..." +# Deploy nginx first (creates the shared network) +bash "$REPO_DIR/scripts/deploy.sh" deploy-nginx +# Deploy all other apps for app in "$REPO_DIR"/docker/*/; do - if [ "$(basename "$app")" = "nginx" ]; then - continue - fi app_name=$(basename "$app") - echo " Starting $app_name..." - cd "$app" - if ! docker compose up -d; then - echo " WARNING: Failed to start $app_name (image may not exist yet). It will start on first deploy." - fi + [ "$app_name" = "nginx" ] && continue + echo " Deploying $app_name..." + bash "$REPO_DIR/scripts/deploy.sh" "deploy-$app_name" done echo "==> Done." diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 27b4c86..f6ef89b 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -47,6 +47,30 @@ fi APP="${CMD#deploy-}" cd /opt/hantim git pull + +# Generate .env from bws if this service declares .env.keys +if [ -f "docker/$APP/.env.keys" ] && [ -f /etc/bws-token ]; then + export BWS_ACCESS_TOKEN + BWS_ACCESS_TOKEN=$(cat /etc/bws-token) + env_content="" + while IFS= read -r line || [ -n "$line" ]; do + [ -z "$line" ] && continue + var_name="${line%%=*}" + secret_key="${line#*=}" + value=$(bws secret list | jq -r --arg key "$secret_key" '.[] | select(.key == $key) | .value') + if [ -z "$value" ]; then + echo "WARNING: Secret '$secret_key' not found in bws, skipping." + continue + fi + env_content="${env_content}${var_name}=${value}"$'\n' + done < "docker/$APP/.env.keys" + if [ -n "$env_content" ]; then + echo "Writing .env for $APP" + printf "%s" "$env_content" > "docker/$APP/.env" + chmod 600 "docker/$APP/.env" + fi +fi + cd "docker/$APP" if grep -q '^\s*build:' compose.yml 2>/dev/null; then docker compose build @@ -89,8 +113,7 @@ if [ "$APP" = "nginx" ]; then docker compose run --rm -T nginx nginx -t fi -docker compose down --remove-orphans -docker compose up -d +docker compose up -d --remove-orphans if [ "$APP" = "nginx" ]; then docker exec nginx nginx -s reload diff --git a/tools/new-app.sh b/tools/new-app.sh index d09c760..7968c6e 100755 --- a/tools/new-app.sh +++ b/tools/new-app.sh @@ -93,7 +93,7 @@ export BWS_ACCESS_TOKEN bws_get() { local name="$1" local value - value=$(bws secret list 2>/dev/null | jq -r --arg name "$name" '.[] | select(.key == $name) | .value') + value=$(bws secret list | jq -r --arg name "$name" '.[] | select(.key == $name) | .value') if [ -z "$value" ]; then echo "ERROR: Secret '$name' not found in Bitwarden Secrets Manager." >&2 exit 1 diff --git a/tools/remove-app.sh b/tools/remove-app.sh index 70992b1..dbd4861 100755 --- a/tools/remove-app.sh +++ b/tools/remove-app.sh @@ -55,7 +55,7 @@ export BWS_ACCESS_TOKEN # --- Fetch secrets from Bitwarden Secrets Manager --- echo "==> Fetching secrets from Bitwarden Secrets Manager..." -GITEA_TOKEN=$(bws secret list 2>/dev/null | jq -r '.[] | select(.key == "hantim-new-app-script") | .value') +GITEA_TOKEN=$(bws secret list | jq -r '.[] | select(.key == "hantim-new-app-script") | .value') if [ -z "$GITEA_TOKEN" ]; then echo "ERROR: Secret 'hantim-new-app-script' not found in Bitwarden Secrets Manager." exit 1