Improve deployment scripts with better error handling and SSL setup

This commit is contained in:
hex
2025-05-19 21:53:30 -07:00
parent 79bbf99b94
commit 83d6bcb905
2 changed files with 184 additions and 46 deletions

101
deploy.sh
View File

@@ -1,27 +1,61 @@
#!/bin/bash #!/bin/bash
# Game Tracker Deployment Script # Game Tracker Deployment Script with improved error handling
echo "=== Game Tracker Deployment ===" set -e # Exit on error
# Bold text function
bold() {
echo -e "\033[1m$1\033[0m"
}
# Print section header
header() {
echo
bold "=== $1 ==="
}
# Print error message and exit
error() {
echo -e "\033[31mERROR: $1\033[0m" >&2
exit 1
}
# Check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
header "Game Tracker Deployment"
# Check requirements
echo "Checking requirements..."
if ! command_exists docker; then
error "Docker is not installed. Please install Docker first."
fi
if ! command_exists docker-compose; then
error "Docker Compose is not installed. Please install Docker Compose first."
fi
# Default settings # Default settings
DEPLOY_MODE=${DEPLOY_MODE:-local} DEPLOY_MODE=${DEPLOY_MODE:-local}
# Check if .env file exists # Check if .env file exists
echo "Checking environment..."
if [ ! -f .env ]; then if [ ! -f .env ]; then
echo "ERROR: .env file not found!" error "'.env' file not found! Please create a .env file with your IGDB credentials:\nIGDB_CLIENT_ID=your_client_id_here\nIGDB_CLIENT_SECRET=your_client_secret_here"
echo "Please create a .env file with your IGDB credentials:"
echo "IGDB_CLIENT_ID=your_client_id_here"
echo "IGDB_CLIENT_SECRET=your_client_secret_here"
exit 1
fi fi
# Make sure database directory exists # Make sure necessary directories exist
echo "Creating required directories..."
mkdir -p instance mkdir -p instance
mkdir -p nginx
# Check deployment mode # Check deployment mode
if [ "$1" = "--ssl" ] || [ "$DEPLOY_MODE" = "ssl" ]; then if [ "$1" = "--ssl" ] || [ "$DEPLOY_MODE" = "ssl" ]; then
echo "Deploying with SSL (for production use)..." header "SSL Deployment (Production Mode)"
# Check for domain name # Check for domain name
if [ -z "$DOMAIN" ]; then if [ -z "$DOMAIN" ]; then
@@ -35,10 +69,25 @@ if [ "$1" = "--ssl" ] || [ "$DEPLOY_MODE" = "ssl" ]; then
export EMAIL export EMAIL
fi fi
# Verify domain
echo "Verifying domain '$DOMAIN' is properly configured..."
host_ip=$(dig +short "$DOMAIN" 2>/dev/null || echo "")
if [ -z "$host_ip" ]; then
echo "WARNING: Could not resolve domain '$DOMAIN'. DNS might not be configured correctly."
read -p "Continue anyway? (y/n): " answer
if [[ "$answer" != [Yy]* ]]; then
error "Deployment cancelled. Please configure DNS correctly and try again."
fi
else
echo "Domain '$DOMAIN' resolves to IP: $host_ip"
fi
# Run the SSL setup script # Run the SSL setup script
echo "Running SSL setup script..."
./init-letsencrypt.sh ./init-letsencrypt.sh
echo "=== SSL Deployment Complete ===" header "SSL Deployment Complete"
echo "Your Game Tracker is now running at: https://$DOMAIN" echo "Your Game Tracker is now running at: https://$DOMAIN"
echo "" echo ""
echo "SSL certificates will auto-renew every 90 days" echo "SSL certificates will auto-renew every 90 days"
@@ -46,28 +95,36 @@ if [ "$1" = "--ssl" ] || [ "$DEPLOY_MODE" = "ssl" ]; then
echo "To stop the server: docker-compose down" echo "To stop the server: docker-compose down"
else else
echo "Deploying locally (for development/testing)..." header "Local Deployment (Development Mode)"
# Create a simpler nginx config for local deployment # Create a simpler nginx config for local deployment
mkdir -p nginx echo "Generating local nginx configuration..."
cat > nginx/app.conf << EOF cat > nginx/app.conf << EOF
server { server {
listen 80; listen 80;
server_name localhost; server_name localhost;
location / { location / {
proxy_pass http://web:8000; proxy_pass http://web:8000;
proxy_set_header Host \$host; proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr; 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;
}
}
EOF EOF
# Build and start Docker containers # Build and start Docker containers
echo "Building and starting Docker containers..." echo "Building and starting Docker containers..."
docker-compose down 2>/dev/null || true # Ignore errors if no containers are running
docker-compose up --build -d docker-compose up --build -d
echo "=== Local Deployment Complete ===" # Check if containers started successfully
if ! docker-compose ps | grep -q "Up"; then
error "Failed to start containers. Check logs with 'docker-compose logs'."
fi
header "Local Deployment Complete"
echo "Your Game Tracker is now running at: http://localhost" echo "Your Game Tracker is now running at: http://localhost"
echo "" echo ""
echo "To view logs: docker-compose logs -f" echo "To view logs: docker-compose logs -f"

View File

@@ -1,6 +1,23 @@
#!/bin/bash #!/bin/bash
# Initialize Let's Encrypt SSL certificates with Certbot # Initialize Let's Encrypt SSL certificates with Certbot
# This improved version handles the chicken-and-egg problem with SSL files
set -e
# Bold text function
bold() {
echo -e "\033[1m$1\033[0m"
}
# Print section header
header() {
echo
bold "=== $1 ==="
}
# Check requirements
header "Checking requirements"
if ! [ -x "$(command -v docker-compose)" ]; then if ! [ -x "$(command -v docker-compose)" ]; then
echo 'Error: docker-compose is not installed.' >&2 echo 'Error: docker-compose is not installed.' >&2
@@ -22,56 +39,120 @@ if [ -z "$email" ]; then
read -p "Enter your email (for Let's Encrypt notifications): " email read -p "Enter your email (for Let's Encrypt notifications): " email
fi fi
header "Setting up SSL for domain: $domains"
# Create required directories # Create required directories
mkdir -p ./data/certbot/conf mkdir -p ./data/certbot/conf
mkdir -p ./data/certbot/www mkdir -p ./data/certbot/www
mkdir -p ./nginx
# Create dummy certificates to bootstrap nginx
echo "Creating dummy certificates..."
rsa_key_size=4096
dummy_cert_path="./data/certbot/conf/live/$domains"
# Make sure the directory is empty and exists
rm -rf "$dummy_cert_path"
mkdir -p "$dummy_cert_path"
# Generate dummy certificates
openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1 \
-keyout "$dummy_cert_path/privkey.pem" \
-out "$dummy_cert_path/fullchain.pem" \
-subj "/CN=localhost"
# Create required files for Nginx
echo "Creating required SSL configurations..."
# Create options-ssl-nginx.conf
cat > ./data/certbot/conf/options-ssl-nginx.conf << EOF
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
EOF
# Create ssl-dhparams.pem
cat > ./data/certbot/conf/ssl-dhparams.pem << EOF
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
-----END DH PARAMETERS-----
EOF
# Generate Nginx config using template # Generate Nginx config using template
header "Configuring Nginx"
echo "Generating Nginx configuration..."
export DOMAIN_NAME=$domains export DOMAIN_NAME=$domains
envsubst < ./nginx/app.conf.template > ./nginx/app.conf envsubst < ./nginx/app.conf.template > ./nginx/app.conf
# Stop any existing services # Stop any existing services
echo "Stopping any existing services..."
docker-compose down docker-compose down
echo "### Starting Nginx..." header "Starting services with dummy certificates"
docker-compose up --force-recreate -d nginx
echo
echo "### Deleting any existing certificates for domain..." # Start services with dummy certificates
if [ -d "./data/certbot/conf/live/$domains" ]; then echo "Starting Nginx and web containers..."
docker-compose run --rm --entrypoint "\ docker-compose up --force-recreate -d
rm -rf /etc/letsencrypt/live/$domains && \
rm -rf /etc/letsencrypt/archive/$domains && \ # Give Nginx time to start
rm -rf /etc/letsencrypt/renewal/$domains.conf" certbot echo "Waiting for Nginx to start..."
sleep 5
# Check if Nginx is running
docker-compose ps nginx | grep Up
if [ $? -ne 0 ]; then
echo "Nginx failed to start! Checking logs:"
docker-compose logs nginx
exit 1
fi fi
echo
echo "### Requesting Let's Encrypt certificate..." header "Obtaining real certificates from Let's Encrypt"
# Prepare staging argument for Certbot
staging_arg="" staging_arg=""
if [ "$staging" = 1 ]; then if [ "$staging" = 1 ]; then
staging_arg="--staging" staging_arg="--staging"
echo "Running in staging mode (test certificates)"
fi fi
# Get certificates # Get real certificates
domain_args="-d $domains" domain_args="-d $domains"
echo "Requesting certificates for: $domains"
docker-compose run --rm --entrypoint "\ docker-compose run --rm --entrypoint "\
certbot certonly --webroot -w /var/www/certbot \ certbot certonly --webroot -w /var/www/certbot \
$staging_arg \ $staging_arg \
--email $email \ --email $email \
--agree-tos \ --agree-tos \
--no-eff-email \ --no-eff-email \
--force-renewal \
$domain_args" certbot $domain_args" certbot
echo
echo "### Reloading nginx..." # Check if certificates were obtained successfully
if [ ! -d "./data/certbot/conf/live/$domains" ]; then
echo "Certificate issuance failed! Check logs above."
exit 1
fi
# Reload Nginx to use the new certificates
echo "Reloading Nginx to use new certificates..."
docker-compose exec nginx nginx -s reload docker-compose exec nginx nginx -s reload
# Start all services header "HTTPS Setup Completed Successfully!"
docker-compose up -d echo "Your app is now available at: https://$domains"
echo ""
echo " echo "The certificates will auto-renew every 90 days."
HTTPS setup completed! echo "To view logs: docker-compose logs -f"
Your app is now available at: https://$domains echo "To stop the server: docker-compose down"
The certificates will auto-renew, but make sure to keep the containers running.
"