diff --git a/deploy.sh b/deploy.sh index 466cf0f..5c56bd1 100755 --- a/deploy.sh +++ b/deploy.sh @@ -1,24 +1,24 @@ #!/bin/bash # ============================================================================== -# NGINX CONFIG & SSL DEPLOYMENT SCRIPT (v7) +# NGINX CONFIG & SSL DEPLOYMENT SCRIPT (v10) # -# This script securely copies NGINX configuration files, automatically -# creates symbolic links to enable the sites, tests the config, reloads Nginx, -# and then automates running Certbot to issue/expand SSL certificates. +# This script handles the "chicken-and-egg" problem of deploying a new site +# with SSL. It first deploys a temporary HTTP-only version of the site by +# commenting out the ENTIRE SSL server block, runs Certbot to acquire the +# certificate (which then automatically re-enables HTTPS), and reloads Nginx. # # INSTRUCTIONS: # 1. Ensure Certbot is installed on the remote server. # (e.g., `sudo apt install certbot python3-certbot-nginx`) -# 2. !! IMPORTANT !! Update the CERTBOT_EMAIL variable below. -# 3. Make the script executable: chmod +x .sh -# 4. Run the script: ./.sh +# 2. Make the script executable: chmod +x .sh +# 3. Run the script: ./.sh # ============================================================================== # --- Configuration --- REMOTE_USER="ubuntu" # The user you SSH in with (e.g., ubuntu, ec2-user) REMOTE_HOST="3.9.182.122" # The IP address or domain of your server -CERTBOT_EMAIL="azeem.fidahusein@gmail.com" # !! IMPORTANT: CHANGE THIS !! Email for Let's Encrypt account +CERTBOT_EMAIL="azeem.fidahusein@gmail.com" # Email for Let's Encrypt account # --- File & Path Definitions --- KEY_FILE="~/repos/azeem-macbookair.pem" @@ -29,7 +29,7 @@ SOURCE_SITES_DIR="sites-available" DEST_NGINX_PATH="/etc/nginx/" DEST_SITES_PATH="/etc/nginx/sites-available/" -# Temporary directory on the remote server (relative to the user's home dir) +# Temporary directory on the remote server REMOTE_TEMP_DIR="nginx_deploy_temp" # --- Script Logic --- @@ -41,10 +41,6 @@ echo "--------------------------------------------------------" EVAL_KEY_FILE=$(eval echo "$KEY_FILE") # --- Pre-flight Checks --- -if [ "$CERTBOT_EMAIL" == "your-email@example.com" ]; then - echo "❌ ERROR: Please update the CERTBOT_EMAIL variable in this script before running." - exit 1 -fi if [ ! -f "$EVAL_KEY_FILE" ]; then echo "❌ ERROR: SSH key not found at $EVAL_KEY_FILE" exit 1 @@ -59,14 +55,9 @@ if [ ! -d "$SOURCE_SITES_DIR" ]; then fi # --- Local Operations --- - -# Get a space-separated list of the config filenames. -# This will be used on the remote server to create symlinks. -# The `tr` command ensures the list is on a single line, preventing syntax errors. CONFIG_FILES=$(ls "$SOURCE_SITES_DIR" | tr '\n' ' ') echo "-> Found site config files to process: $CONFIG_FILES" -# Find all unique domains for Certbot. echo "-> Scanning local 'sites-available' for unique domain names..." ALL_DOMAINS=$(grep -h -r "server_name" "$SOURCE_SITES_DIR" | sed 's/.*server_name\s*//' | sed 's/;//' | xargs -n1 | sort -u | tr '\n' ' ' | sed 's/ *$//') @@ -79,18 +70,9 @@ echo # --- Remote Operations --- -# Step 1: Create the temporary directory on the remote server. -echo "-> Creating temporary directory on remote server..." +# Step 1: Transfer files to a temporary directory +echo "-> Creating temporary directory and transferring files..." ssh -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" "mkdir -p $REMOTE_TEMP_DIR" -if [ $? -ne 0 ]; then - echo "❌ ERROR: Failed to create temporary directory. Aborting." - exit 1 -fi -echo " ✅ Remote temporary directory is ready." -echo - -# Step 2: Transfer all files to the temporary directory. -echo "- Transferring configuration files to temporary location..." scp -i "$EVAL_KEY_FILE" -r "$SOURCE_NGINX_CONF" "$SOURCE_SITES_DIR" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_TEMP_DIR}/" if [ $? -ne 0 ]; then echo "❌ ERROR: File transfer failed. Aborting." @@ -99,16 +81,23 @@ fi echo " ✅ All files successfully transferred to temporary location." echo -# Step 3: Move files, create symbolic links, clean up, and test config. -echo "- Moving files, enabling sites, and cleaning up..." +# Step 2: Move files, TEMPORARILY disable SSL blocks, enable sites, and reload Nginx +echo "- Moving files and enabling HTTP-only sites for Certbot validation..." ssh -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" << EOF - # Move the main config file + # Move the main config file and site configs sudo mv "$REMOTE_TEMP_DIR/nginx.conf" "${DEST_NGINX_PATH}nginx.conf" - - # Move the sites-available files sudo mv "$REMOTE_TEMP_DIR/sites-available/"* "$DEST_SITES_PATH" - # --- NEW: Enable sites by creating symbolic links --- + # --- NEW: Temporarily disable the entire SSL server block --- + echo " -> Temporarily commenting out SSL server blocks in configs..." + for CONFIG_FILE in $CONFIG_FILES + do + # Use awk to comment out the entire server block containing 'listen 443' + sudo awk '/server\s*{/{f=1} f && /listen\s+443/{p=1} f{b=b\$0"\\n"} /\s*}/ && f{f=0; if(!p){printf "%s", b} p=0; b=""}' "$DEST_SITES_PATH\$CONFIG_FILE" > "\$CONFIG_FILE.tmp" && sudo mv "\$CONFIG_FILE.tmp" "$DEST_SITES_PATH\$CONFIG_FILE" + done + # --- END NEW --- + + # Enable sites by creating symbolic links echo " -> Checking and creating symbolic links in sites-enabled..." for CONFIG_FILE in $CONFIG_FILES do @@ -118,61 +107,50 @@ ssh -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" << EOF if [ -f "\$SOURCE_FILE" ]; then echo " -> Creating link for \$CONFIG_FILE..." sudo ln -s "\$SOURCE_FILE" "\$LINK_FILE" - else - echo " -> Source file \$SOURCE_FILE not found, skipping link." fi else echo " -> Link for \$CONFIG_FILE already exists." fi done - # --- END NEW --- - # Remove the temporary directory - rm -rf "$REMOTE_TEMP_DIR" - - echo " -> Verifying Nginx configuration..." - sudo nginx -t + echo " -> Verifying and reloading Nginx for initial validation..." + sudo nginx -t && sudo systemctl reload nginx EOF if [ $? -ne 0 ]; then - echo "⚠️ WARNING: An error occurred on the remote server during the move or config test." + echo "⚠️ WARNING: An error occurred on the remote server during initial setup." + echo "This might happen if your base HTTP config is invalid. Please check manually." exit 1 fi -echo " ✅ Files moved, sites enabled, and configuration test passed." +echo " ✅ Initial Nginx config loaded successfully." echo -# Step 4: Reload Nginx to apply new configs before running Certbot -echo "- Reloading Nginx to apply new configurations..." -ssh -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" "sudo systemctl reload nginx" -if [ $? -ne 0 ]; then - echo "⚠️ WARNING: Nginx reload failed. Check the server status." -else - echo " ✅ Nginx reloaded successfully." -fi -echo - -# Step 5: Ask to run Certbot if domains were found +# Step 3: Run Certbot to acquire certificates and update configs to HTTPS if [ -n "$ALL_DOMAINS" ]; then read -p "Run Certbot for the discovered domains? (y/n) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then - # Format domains for the certbot command (-d domain1 -d domain2 etc.) CERTBOT_DOMAINS=$(echo "$ALL_DOMAINS" | sed 's/ / -d /g' | sed 's/^/-d /') - echo "- Running Certbot on the server..." + echo "- Running Certbot to acquire certificates and enable SSL..." + echo " Certbot will now automatically update your Nginx configs for HTTPS." + ssh -t -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" \ "sudo certbot --nginx --non-interactive --agree-tos --email $CERTBOT_EMAIL --redirect --expand $CERTBOT_DOMAINS" if [ $? -eq 0 ]; then - echo " ✅ Certbot process completed." + echo " ✅ Certbot process completed successfully." else - echo "⚠️ WARNING: Certbot process finished with errors." + echo "⚠️ WARNING: Certbot process finished with errors. Please check the logs on the server." fi fi else echo "-> Skipping Certbot step as no domains were found." fi +# Final cleanup +ssh -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" "rm -rf $REMOTE_TEMP_DIR" + # --- Completion --- echo "--------------------------------------------------------" echo "🎉 Deployment complete!"