#!/bin/bash # Simple fix: Update service file to use $HOST and $PORT from .env # No wrapper script, just fix the variable expansion set -e echo "=== Fix: Update service to use \$HOST and \$PORT from .env ===" echo APP_DIR="/opt/mockapi" ENV_FILE="${APP_DIR}/.env" SERVICE_FILE="/etc/systemd/system/mockapi.service" # Colors GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' print_status() { echo -e "${GREEN}[+]${NC} $1" } print_warning() { echo -e "${YELLOW}[!]${NC} $1" } print_error() { echo -e "${RED}[!]${NC} $1" } # Check if running as root if [[ $EUID -ne 0 ]]; then print_error "This script requires sudo privileges." exit 1 fi # Step 1: Check files if [[ ! -f "$ENV_FILE" ]]; then print_error ".env file not found: $ENV_FILE" exit 1 fi if [[ ! -f "$SERVICE_FILE" ]]; then print_error "Service file not found: $SERVICE_FILE" exit 1 fi # Step 2: Ensure PORT exists in .env print_status "Checking .env file..." if ! grep -q "^PORT=" "$ENV_FILE"; then print_warning "PORT not found in .env. Adding PORT=8000..." echo "PORT=8000" >> "$ENV_FILE" print_status "Added PORT=8000" fi if ! grep -q "^HOST=" "$ENV_FILE"; then print_warning "HOST not found in .env. Adding HOST=0.0.0.0..." echo "HOST=0.0.0.0" >> "$ENV_FILE" fi # Validate PORT is numeric PORT_VALUE=$(grep "^PORT=" "$ENV_FILE" | cut -d'=' -f2) if [[ ! "$PORT_VALUE" =~ ^[0-9]+$ ]]; then print_error "PORT is not numeric: '$PORT_VALUE'. Fixing to 8000." sed -i "s/^PORT=.*/PORT=8000/" "$ENV_FILE" PORT_VALUE="8000" fi # Step 3: Backup service file print_status "Backing up service file..." BACKUP_FILE="${SERVICE_FILE}.backup.$(date +%s)" cp "$SERVICE_FILE" "$BACKUP_FILE" print_status "Backup created: $BACKUP_FILE" # Step 4: Check current ExecStart print_status "Checking current ExecStart line..." CURRENT_EXEC=$(grep "^ExecStart=" "$SERVICE_FILE") echo "Current: $CURRENT_EXEC" # Step 5: Update ExecStart to use $HOST and $PORT print_status "Updating ExecStart to use variables from .env..." # We need to replace the ExecStart line with one that uses $HOST and $PORT # But we need to be careful about escaping for sed # First, get the current venv path from the existing ExecStart or Environment line VENV_PATH=$(grep 'Environment="PATH=' "$SERVICE_FILE" | cut -d'=' -f2 | cut -d':' -f1 | sed 's/"//g') if [[ -z "$VENV_PATH" ]]; then # Try to extract from ExecStart VENV_PATH=$(echo "$CURRENT_EXEC" | sed -n "s|^ExecStart=\(.*\)/waitress-serve.*|\1|p") if [[ -z "$VENV_PATH" ]]; then VENV_PATH="/opt/mockapi/venv" print_warning "Could not detect venv path, using default: $VENV_PATH" fi fi print_status "Detected venv path: $VENV_PATH" # Create a temporary file with the updated service configuration TMP_FILE=$(mktemp) # Read the current service file and update ExecStart while IFS= read -r line; do if [[ "$line" =~ ^ExecStart= ]]; then # Replace with new ExecStart using variables echo "ExecStart=$VENV_PATH/bin/waitress-serve --host=\$HOST --port=\$PORT wsgi:wsgi_app" print_status "Updated ExecStart line" else echo "$line" fi done < "$SERVICE_FILE" > "$TMP_FILE" # Replace the service file mv "$TMP_FILE" "$SERVICE_FILE" # Step 6: Verify the change print_status "Verifying update..." UPDATED_EXEC=$(grep "^ExecStart=" "$SERVICE_FILE") echo "Updated: $UPDATED_EXEC" # Check if we have the escaped \$HOST and \$PORT if echo "$UPDATED_EXEC" | grep -q "\\\\\$HOST\|\\\\\$PORT"; then print_warning "Found escaped variables (\\\$HOST/\\\$PORT). This might still cause issues." print_status "Trying alternative: unescaped variables..." # Create alternative without backslashes TMP_FILE2=$(mktemp) while IFS= read -r line; do if [[ "$line" =~ ^ExecStart= ]]; then # Use unescaped variables echo "ExecStart=$VENV_PATH/bin/waitress-serve --host=\$HOST --port=\$PORT wsgi:wsgi_app" else echo "$line" fi done < "$SERVICE_FILE" > "$TMP_FILE2" # The issue: $HOST and $PORT in the HERE-document above will expand # We need to write literal $HOST and $PORT. Let's use sed instead. sed -i 's/--host=\\\$HOST --port=\\\$PORT/--host=$HOST --port=$PORT/' "$TMP_FILE2" mv "$TMP_FILE2" "$SERVICE_FILE" print_status "Updated with unescaped variables" fi # Final check FINAL_EXEC=$(grep "^ExecStart=" "$SERVICE_FILE") echo "Final ExecStart: $FINAL_EXEC" # Step 7: Test if it looks correct if echo "$FINAL_EXEC" | grep -q "--host=\$HOST --port=\$PORT"; then print_status "✓ ExecStart looks correct (uses \$HOST and \$PORT)" elif echo "$FINAL_EXEC" | grep -q "--host=\\\$HOST --port=\\\$PORT"; then print_warning "ExecStart has escaped variables (\\\$HOST/\\\$PORT)" print_warning "This might still cause the original error." else print_warning "ExecStart format unexpected: $FINAL_EXEC" fi # Step 8: Reload and restart print_status "Reloading systemd..." systemctl daemon-reload print_status "Restarting service..." if systemctl restart mockapi; then print_status "Service restart initiated..." sleep 3 if systemctl is-active --quiet mockapi; then print_status "✓ Service is running!" # Test health endpoint print_status "Testing health endpoint on port $PORT_VALUE..." if curl -f -s --max-time 10 http://localhost:$PORT_VALUE/health > /dev/null 2>&1; then print_status "✓ Health check passed!" echo echo "=== SUCCESS ===" echo "MockAPI service now uses PORT from .env file." echo echo "To change port:" echo " 1. Edit $ENV_FILE" echo " 2. Update the PORT value" echo " 3. Run: sudo systemctl restart mockapi" echo echo "Current port: $PORT_VALUE" echo "Access: http://localhost:$PORT_VALUE" else print_warning "Service running but health check failed." journalctl -u mockapi -n 10 --no-pager fi else print_error "Service failed to start." echo "Checking logs..." journalctl -u mockapi -n 20 --no-pager # Try one more approach: use a simple hardcoded port as fallback print_status "Trying fallback: hardcoding port $PORT_VALUE..." sed -i "s|--host=\$HOST --port=\$PORT|--host=0.0.0.0 --port=$PORT_VALUE|" "$SERVICE_FILE" systemctl daemon-reload systemctl restart mockapi sleep 3 if systemctl is-active --quiet mockapi; then print_status "✓ Service running with hardcoded port $PORT_VALUE" print_warning "Note: Port is now hardcoded. To change port, update service file." else print_error "All attempts failed. Restoring backup..." cp "$BACKUP_FILE" "$SERVICE_FILE" systemctl daemon-reload systemctl restart mockapi fi fi else print_error "Failed to restart service." systemctl status mockapi --no-pager -l fi echo print_status "=== Fix completed ===" echo "Backup: $BACKUP_FILE" echo "To manually change port in the future:" echo " 1. Edit $ENV_FILE (update PORT)" echo " 2. Edit $SERVICE_FILE (update --port value in ExecStart)" echo " 3. sudo systemctl daemon-reload" echo " 4. sudo systemctl restart mockapi"