updated logic with two stage approach

This commit is contained in:
2025-06-24 21:28:58 +01:00
parent 74fec08104
commit ac367a148a

View File

@@ -1,24 +1,24 @@
#!/bin/bash #!/bin/bash
# ============================================================================== # ==============================================================================
# NGINX CONFIG & SSL DEPLOYMENT SCRIPT (v7) # NGINX CONFIG & SSL DEPLOYMENT SCRIPT (v10)
# #
# This script securely copies NGINX configuration files, automatically # This script handles the "chicken-and-egg" problem of deploying a new site
# creates symbolic links to enable the sites, tests the config, reloads Nginx, # with SSL. It first deploys a temporary HTTP-only version of the site by
# and then automates running Certbot to issue/expand SSL certificates. # commenting out the ENTIRE SSL server block, runs Certbot to acquire the
# certificate (which then automatically re-enables HTTPS), and reloads Nginx.
# #
# INSTRUCTIONS: # INSTRUCTIONS:
# 1. Ensure Certbot is installed on the remote server. # 1. Ensure Certbot is installed on the remote server.
# (e.g., `sudo apt install certbot python3-certbot-nginx`) # (e.g., `sudo apt install certbot python3-certbot-nginx`)
# 2. !! IMPORTANT !! Update the CERTBOT_EMAIL variable below. # 2. Make the script executable: chmod +x <script_name>.sh
# 3. Make the script executable: chmod +x <script_name>.sh # 3. Run the script: ./<script_name>.sh
# 4. Run the script: ./<script_name>.sh
# ============================================================================== # ==============================================================================
# --- Configuration --- # --- Configuration ---
REMOTE_USER="ubuntu" # The user you SSH in with (e.g., ubuntu, ec2-user) 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 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 --- # --- File & Path Definitions ---
KEY_FILE="~/repos/azeem-macbookair.pem" KEY_FILE="~/repos/azeem-macbookair.pem"
@@ -29,7 +29,7 @@ SOURCE_SITES_DIR="sites-available"
DEST_NGINX_PATH="/etc/nginx/" DEST_NGINX_PATH="/etc/nginx/"
DEST_SITES_PATH="/etc/nginx/sites-available/" 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" REMOTE_TEMP_DIR="nginx_deploy_temp"
# --- Script Logic --- # --- Script Logic ---
@@ -41,10 +41,6 @@ echo "--------------------------------------------------------"
EVAL_KEY_FILE=$(eval echo "$KEY_FILE") EVAL_KEY_FILE=$(eval echo "$KEY_FILE")
# --- Pre-flight Checks --- # --- 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 if [ ! -f "$EVAL_KEY_FILE" ]; then
echo "❌ ERROR: SSH key not found at $EVAL_KEY_FILE" echo "❌ ERROR: SSH key not found at $EVAL_KEY_FILE"
exit 1 exit 1
@@ -59,14 +55,9 @@ if [ ! -d "$SOURCE_SITES_DIR" ]; then
fi fi
# --- Local Operations --- # --- 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' ' ') CONFIG_FILES=$(ls "$SOURCE_SITES_DIR" | tr '\n' ' ')
echo "-> Found site config files to process: $CONFIG_FILES" echo "-> Found site config files to process: $CONFIG_FILES"
# Find all unique domains for Certbot.
echo "-> Scanning local 'sites-available' for unique domain names..." 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/ *$//') 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 --- # --- Remote Operations ---
# Step 1: Create the temporary directory on the remote server. # Step 1: Transfer files to a temporary directory
echo "-> Creating temporary directory on remote server..." echo "-> Creating temporary directory and transferring files..."
ssh -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" "mkdir -p $REMOTE_TEMP_DIR" 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}/" scp -i "$EVAL_KEY_FILE" -r "$SOURCE_NGINX_CONF" "$SOURCE_SITES_DIR" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_TEMP_DIR}/"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
echo "❌ ERROR: File transfer failed. Aborting." echo "❌ ERROR: File transfer failed. Aborting."
@@ -99,16 +81,23 @@ fi
echo " ✅ All files successfully transferred to temporary location." echo " ✅ All files successfully transferred to temporary location."
echo echo
# Step 3: Move files, create symbolic links, clean up, and test config. # Step 2: Move files, TEMPORARILY disable SSL blocks, enable sites, and reload Nginx
echo "- Moving files, enabling sites, and cleaning up..." echo "- Moving files and enabling HTTP-only sites for Certbot validation..."
ssh -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" << EOF 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" 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" 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..." echo " -> Checking and creating symbolic links in sites-enabled..."
for CONFIG_FILE in $CONFIG_FILES for CONFIG_FILE in $CONFIG_FILES
do do
@@ -118,61 +107,50 @@ ssh -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" << EOF
if [ -f "\$SOURCE_FILE" ]; then if [ -f "\$SOURCE_FILE" ]; then
echo " -> Creating link for \$CONFIG_FILE..." echo " -> Creating link for \$CONFIG_FILE..."
sudo ln -s "\$SOURCE_FILE" "\$LINK_FILE" sudo ln -s "\$SOURCE_FILE" "\$LINK_FILE"
else
echo " -> Source file \$SOURCE_FILE not found, skipping link."
fi fi
else else
echo " -> Link for \$CONFIG_FILE already exists." echo " -> Link for \$CONFIG_FILE already exists."
fi fi
done done
# --- END NEW ---
# Remove the temporary directory echo " -> Verifying and reloading Nginx for initial validation..."
rm -rf "$REMOTE_TEMP_DIR" sudo nginx -t && sudo systemctl reload nginx
echo " -> Verifying Nginx configuration..."
sudo nginx -t
EOF EOF
if [ $? -ne 0 ]; then 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 exit 1
fi fi
echo " ✅ Files moved, sites enabled, and configuration test passed." echo " ✅ Initial Nginx config loaded successfully."
echo echo
# Step 4: Reload Nginx to apply new configs before running Certbot # Step 3: Run Certbot to acquire certificates and update configs to HTTPS
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
if [ -n "$ALL_DOMAINS" ]; then if [ -n "$ALL_DOMAINS" ]; then
read -p "Run Certbot for the discovered domains? (y/n) " -n 1 -r read -p "Run Certbot for the discovered domains? (y/n) " -n 1 -r
echo echo
if [[ $REPLY =~ ^[Yy]$ ]]; then 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 /') 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}" \ ssh -t -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" \
"sudo certbot --nginx --non-interactive --agree-tos --email $CERTBOT_EMAIL --redirect --expand $CERTBOT_DOMAINS" "sudo certbot --nginx --non-interactive --agree-tos --email $CERTBOT_EMAIL --redirect --expand $CERTBOT_DOMAINS"
if [ $? -eq 0 ]; then if [ $? -eq 0 ]; then
echo " ✅ Certbot process completed." echo " ✅ Certbot process completed successfully."
else else
echo "⚠️ WARNING: Certbot process finished with errors." echo "⚠️ WARNING: Certbot process finished with errors. Please check the logs on the server."
fi fi
fi fi
else else
echo "-> Skipping Certbot step as no domains were found." echo "-> Skipping Certbot step as no domains were found."
fi fi
# Final cleanup
ssh -i "$EVAL_KEY_FILE" "${REMOTE_USER}@${REMOTE_HOST}" "rm -rf $REMOTE_TEMP_DIR"
# --- Completion --- # --- Completion ---
echo "--------------------------------------------------------" echo "--------------------------------------------------------"
echo "🎉 Deployment complete!" echo "🎉 Deployment complete!"