#!/bin/bash set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DEPLOYMENT_DIR="$(dirname "$SCRIPT_DIR")" echo -e "${GREEN}=== SSL Certificate Setup ===${NC}" # Load environment variables if [ ! -f "$DEPLOYMENT_DIR/.env" ]; then echo -e "${RED}Error: .env file not found!${NC}" exit 1 fi source "$DEPLOYMENT_DIR/.env" # Validate required variables if [ -z "$DOMAIN" ] || [ -z "$EMAIL" ]; then echo -e "${RED}Error: DOMAIN and EMAIL must be set in .env${NC}" exit 1 fi echo -e "${YELLOW}Domain: $DOMAIN${NC}" echo -e "${YELLOW}Email: $EMAIL${NC}" cd "$DEPLOYMENT_DIR/docker" # Create a temporary nginx config for initial certificate request echo -e "${GREEN}Creating temporary nginx config for certificate request...${NC}" # Create temp config directory if it doesn't exist mkdir -p "$DEPLOYMENT_DIR/nginx/conf.d" # Create temporary HTTP-only config cat > "$DEPLOYMENT_DIR/nginx/conf.d/default.conf" << EOF server { listen 80; listen [::]:80; server_name $DOMAIN; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 200 'Waiting for SSL certificate...'; add_header Content-Type text/plain; } } EOF # Restart nginx with temporary config echo -e "${GREEN}Restarting nginx with temporary config...${NC}" docker compose up -d nginx # Wait for nginx to start sleep 5 # Request certificate echo -e "${GREEN}Requesting SSL certificate from Let's Encrypt...${NC}" docker compose run --rm certbot certonly \ --webroot \ --webroot-path=/var/www/certbot \ --email "$EMAIL" \ --agree-tos \ --no-eff-email \ -d "$DOMAIN" # Check if certificate was created if docker compose run --rm certbot certificates | grep -q "$DOMAIN"; then echo -e "${GREEN}Certificate obtained successfully!${NC}" else echo -e "${RED}Failed to obtain certificate!${NC}" echo "Please check:" echo "1. DNS is pointing to this server" echo "2. Port 80 is accessible from the internet" exit 1 fi # Restore the full nginx config with SSL echo -e "${GREEN}Restoring full nginx config with SSL...${NC}" cat > "$DEPLOYMENT_DIR/nginx/conf.d/default.conf" << EOF # HTTP redirect to HTTPS server { listen 80; listen [::]:80; server_name $DOMAIN; location /.well-known/acme-challenge/ { root /var/www/certbot; } location / { return 301 https://\$host\$request_uri; } } # HTTPS server server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name $DOMAIN; ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem; ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; add_header Strict-Transport-Security "max-age=63072000" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; location ~ ^/auth/(login|register)\$ { limit_req zone=auth_limit burst=10 nodelay; proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_set_header Connection ""; } location / { limit_req zone=api_limit burst=20 nodelay; proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Host \$host; proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto \$scheme; proxy_set_header Connection ""; proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } location /health { proxy_pass http://backend/docs; proxy_http_version 1.1; proxy_set_header Connection ""; } } EOF # Reload nginx echo -e "${GREEN}Reloading nginx with SSL config...${NC}" docker compose exec nginx nginx -s reload echo -e "${GREEN}=== SSL setup complete! ===${NC}" echo "" echo "Your API is now available at: https://$DOMAIN" echo "" echo "Certificate will auto-renew via the certbot container."