#!/usr/bin/env bash # First run only: get a certificate for EXT_HOST, then hand off to deploy.sh. # # This uses the autotrader stack's certbot container and its Let's Encrypt # account, so it agrees to the Subscriber Agreement the same way that stack's # own bootstrap did (certbot --agree-tos): # https://letsencrypt.org/repository/ set -euo pipefail cd "$(dirname "$0")" log() { printf '\n\033[1;34m==> %s\033[0m\n' "$1"; } fail() { printf '\n\033[1;31mERROR: %s\033[0m\n' "$1" >&2; exit 1; } [ -f .env ] || fail "no .env — copy .env.example to .env and fill it in" set -a; . ./.env; set +a : "${EXT_HOST:?set EXT_HOST in .env}" SHARED_STACK="${SHARED_STACK:-/opt/autotrader/deploy}" # ACME_EMAIL is not duplicated here: it belongs to the account that already # holds the other certificates on this box. [ -f "$SHARED_STACK/.env" ] || fail "no .env under $SHARED_STACK" ACME_EMAIL=$(grep -E '^ACME_EMAIL=' "$SHARED_STACK/.env" | cut -d= -f2-) [ -n "$ACME_EMAIL" ] || fail "ACME_EMAIL is not set in $SHARED_STACK/.env" # Let's Encrypt rate-limits failures, so check DNS before spending an attempt. log "Checking DNS" ip=$(curl -fsS --max-time 5 http://169.254.169.254/metadata/v1/interfaces/public/0/ipv4/address 2>/dev/null \ || curl -fsS --max-time 5 https://api.ipify.org 2>/dev/null) \ || fail "could not determine this droplet's public IP" got=$(getent ahostsv4 "$EXT_HOST" 2>/dev/null | awk 'NR==1{print $1}') || true echo " droplet: $ip" echo " $EXT_HOST -> ${got:-}" [ "$got" = "$ip" ] || fail "$EXT_HOST does not resolve to $ip — fix DNS and wait for it to propagate" # The challenge is served over plain HTTP by the shared nginx, which needs a # server block for this name before it will answer for it. log "Rendering the HTTP-only config so the challenge can be served" envsubst '${EXT_HOST}' < nginx/ext-acme.conf.template > "$SHARED_STACK/nginx/conf.d/ext.conf" docker exec nginx nginx -t docker exec nginx nginx -s reload log "Requesting a certificate for $EXT_HOST" docker compose --project-directory "$SHARED_STACK" -f "$SHARED_STACK/docker-compose.yml" \ run --rm --entrypoint certbot certbot \ certonly --webroot -w /var/www/certbot \ --email "$ACME_EMAIL" --agree-tos --no-eff-email \ --non-interactive -d "$EXT_HOST" \ || fail "certbot failed — check DNS and that port 80 reaches this droplet" log "Switching to the TLS config" exec ./deploy.sh