Spaces:
Runtime error
Runtime error
| # init-letsencrypt.sh | |
| # Bootstrap SSL certificate for first deployment. | |
| # Run ONCE. After this, certbot auto-renews every 12 hours. | |
| set -e | |
| ENV_FILE=".env.production" | |
| COMPOSE_FILE="docker-compose.prod.yml" | |
| COMPOSE="docker compose --env-file $ENV_FILE -f $COMPOSE_FILE" | |
| # --------------------------------------------------------------------------- | |
| # Read config from .env.production | |
| # --------------------------------------------------------------------------- | |
| DOMAIN=$(grep '^NGINX_DOMAIN=' "$ENV_FILE" | cut -d= -f2 | tr -d ' ') | |
| EMAIL=$(grep '^CERTBOT_EMAIL=' "$ENV_FILE" | cut -d= -f2 | tr -d ' ') | |
| if [ -z "$DOMAIN" ] || [ -z "$EMAIL" ]; then | |
| echo "ERROR: NGINX_DOMAIN and CERTBOT_EMAIL must be set in $ENV_FILE" | |
| exit 1 | |
| fi | |
| echo "==> Domain : $DOMAIN" | |
| echo "==> Email : $EMAIL" | |
| echo "" | |
| # --------------------------------------------------------------------------- | |
| # Step 0: Skip bootstrap if a real cert already exists | |
| # --------------------------------------------------------------------------- | |
| echo "==> Checking for existing certificates..." | |
| if $COMPOSE run --rm --entrypoint sh certbot \ | |
| -c "test -f /etc/letsencrypt/live/$DOMAIN/fullchain.pem"; then | |
| echo "==> Certificates already exist. Starting nginx..." | |
| $COMPOSE up -d --wait nginx | |
| echo "==> Done. nginx is running with the existing certificate." | |
| exit 0 | |
| fi | |
| echo "==> No certificates found. Starting bootstrap..." | |
| echo "" | |
| # --------------------------------------------------------------------------- | |
| # Step 1: Create a temporary self-signed certificate so nginx can start. | |
| # nginx refuses to start if the ssl_certificate path does not exist. | |
| # --------------------------------------------------------------------------- | |
| echo "==> [1/4] Creating temporary self-signed certificate..." | |
| $COMPOSE run --rm --entrypoint sh certbot -c \ | |
| "mkdir -p /etc/letsencrypt/live/$DOMAIN && \ | |
| openssl req -x509 -nodes -newkey rsa:4096 -days 1 \ | |
| -keyout /etc/letsencrypt/live/$DOMAIN/privkey.pem \ | |
| -out /etc/letsencrypt/live/$DOMAIN/fullchain.pem \ | |
| -subj /CN=localhost \ | |
| -quiet" | |
| # Verify the cert was actually created before continuing | |
| if ! $COMPOSE run --rm --entrypoint sh certbot \ | |
| -c "test -f /etc/letsencrypt/live/$DOMAIN/fullchain.pem"; then | |
| echo "ERROR: Failed to create temporary certificate. Check the certbot image." | |
| exit 1 | |
| fi | |
| echo "==> Temporary certificate created." | |
| # --------------------------------------------------------------------------- | |
| # Step 2: Start nginx (and all backend dependencies). | |
| # --wait blocks until every health check passes. | |
| # --------------------------------------------------------------------------- | |
| echo "==> [2/4] Starting nginx and backend services..." | |
| $COMPOSE up -d --wait nginx | |
| echo "==> nginx is up." | |
| # --------------------------------------------------------------------------- | |
| # Step 3: Request the real certificate from Let's Encrypt. | |
| # The certbot image uses certbot as its entrypoint — pass certonly | |
| # and flags directly as the command. | |
| # --------------------------------------------------------------------------- | |
| echo "==> [3/4] Requesting SSL certificate from Let's Encrypt..." | |
| $COMPOSE run --rm certbot certonly \ | |
| --webroot \ | |
| --webroot-path=/var/www/certbot \ | |
| --email "$EMAIL" \ | |
| --agree-tos \ | |
| --no-eff-email \ | |
| -d "$DOMAIN" | |
| # --------------------------------------------------------------------------- | |
| # Step 4: Reload nginx so it picks up the real certificate. | |
| # --------------------------------------------------------------------------- | |
| echo "==> [4/4] Reloading nginx with the real certificate..." | |
| $COMPOSE exec nginx nginx -s reload | |
| echo "" | |
| echo "====================================================================" | |
| echo " SSL certificate obtained successfully!" | |
| echo " Site is live at: https://$DOMAIN" | |
| echo "" | |
| echo " Next step: run 'make prod-up' to start all remaining services." | |
| echo "====================================================================" | |