Files
digital-garage-sale/deploy.sh
2025-04-29 14:13:26 -07:00

198 lines
5.9 KiB
Bash
Executable File

#!/bin/bash
# Deployment script for Hex's Garage Sale Catalog
# This script automates the deployment process on a Debian server
set -e # Exit immediately if a command exits with a non-zero status
# Color codes for better readability
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# Function to print colored messages
print_message() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if running as root
if [ "$(id -u)" != "0" ]; then
print_error "This script must be run as root"
exit 1
fi
# Get deployment configuration
read -p "Enter domain name (e.g., garagesale.example.com): " DOMAIN_NAME
read -p "Enter admin password (default: admin123): " ADMIN_PASSWORD
ADMIN_PASSWORD=${ADMIN_PASSWORD:-admin123}
read -p "Use PostgreSQL instead of SQLite? (y/N): " USE_POSTGRES
USE_POSTGRES=${USE_POSTGRES:-n}
# Generate a secure secret key
SECRET_KEY=$(openssl rand -hex 24)
print_message "Beginning deployment process..."
# Update system packages
print_message "Updating system packages..."
apt update && apt upgrade -y
# Install required packages
print_message "Installing required packages..."
apt install -y python3 python3-venv python3-pip nginx wkhtmltopdf
# Setup PostgreSQL if requested
if [[ "$USE_POSTGRES" =~ ^[Yy]$ ]]; then
print_message "Setting up PostgreSQL..."
apt install -y postgresql postgresql-contrib
systemctl start postgresql
systemctl enable postgresql
# Generate a secure PostgreSQL password
PG_PASSWORD=$(openssl rand -hex 12)
# Create PostgreSQL user and database
su -c "psql -c \"CREATE DATABASE garagesale;\"" postgres
su -c "psql -c \"CREATE USER garagesaleuser WITH PASSWORD '$PG_PASSWORD';\"" postgres
su -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE garagesale TO garagesaleuser;\"" postgres
DB_URL="postgresql://garagesaleuser:$PG_PASSWORD@localhost/garagesale"
print_message "PostgreSQL setup complete."
print_warning "PostgreSQL password: $PG_PASSWORD (Please save this somewhere secure)"
else
DB_URL="sqlite:////var/www/garagesale/garage_sale.db"
print_message "Using SQLite for database."
fi
# Create a dedicated user for the application
print_message "Creating application user..."
useradd -m -s /bin/bash garagesale || print_warning "User already exists, continuing..."
# Set up application directory
print_message "Setting up application directory..."
mkdir -p /var/www/garagesale
cp -r $(dirname "$0")/* /var/www/garagesale/
chown -R garagesale:www-data /var/www/garagesale
chmod -R 755 /var/www/garagesale
# Create uploads directory with proper permissions
mkdir -p /var/www/garagesale/app/static/uploads
chown -R garagesale:www-data /var/www/garagesale/app/static/uploads
chmod -R 775 /var/www/garagesale/app/static/uploads
# Set up virtual environment and install dependencies
print_message "Setting up Python virtual environment and dependencies..."
cd /var/www/garagesale
su -c "python3 -m venv venv" garagesale
su -c "source venv/bin/activate && pip install -r requirements.txt && pip install gunicorn" garagesale
if [[ "$USE_POSTGRES" =~ ^[Yy]$ ]]; then
su -c "source venv/bin/activate && pip install psycopg2-binary" garagesale
fi
# Create environment file
print_message "Creating environment file..."
cat > /var/www/garagesale/.env << EOF
SECRET_KEY="$SECRET_KEY"
ADMIN_PASSWORD="$ADMIN_PASSWORD"
DATABASE_URL="$DB_URL"
EOF
chown garagesale:garagesale /var/www/garagesale/.env
chmod 600 /var/www/garagesale/.env
# Create wsgi.py file
print_message "Creating WSGI file..."
cat > /var/www/garagesale/wsgi.py << 'EOF'
from app import create_app
app = create_app()
if __name__ == "__main__":
app.run()
EOF
chown garagesale:garagesale /var/www/garagesale/wsgi.py
# Initialize the database
print_message "Initializing the database..."
cd /var/www/garagesale
su -c "source venv/bin/activate && python init_db.py" garagesale
# Set up Gunicorn service
print_message "Setting up Gunicorn service..."
cat > /etc/systemd/system/garagesale.service << EOF
[Unit]
Description=Gunicorn instance to serve Hex's Garage Sale Catalog
After=network.target
[Service]
User=garagesale
Group=www-data
WorkingDirectory=/var/www/garagesale
Environment="PATH=/var/www/garagesale/venv/bin"
EnvironmentFile=/var/www/garagesale/.env
ExecStart=/var/www/garagesale/venv/bin/gunicorn --workers 3 --bind unix:garagesale.sock -m 007 wsgi:app
[Install]
WantedBy=multi-user.target
EOF
# Enable and start Gunicorn service
print_message "Starting Gunicorn service..."
systemctl daemon-reload
systemctl start garagesale
systemctl enable garagesale
# Set up Nginx
print_message "Setting up Nginx..."
cat > /etc/nginx/sites-available/garagesale << EOF
server {
listen 80;
server_name $DOMAIN_NAME;
location /static {
alias /var/www/garagesale/app/static;
}
location / {
proxy_pass http://unix:/var/www/garagesale/garagesale.sock;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
}
}
EOF
# Enable the Nginx site
ln -sf /etc/nginx/sites-available/garagesale /etc/nginx/sites-enabled/
nginx -t && systemctl restart nginx
print_message "Basic deployment complete!"
# Set up SSL with Let's Encrypt
read -p "Do you want to set up SSL with Let's Encrypt? (y/N): " SETUP_SSL
SETUP_SSL=${SETUP_SSL:-n}
if [[ "$SETUP_SSL" =~ ^[Yy]$ ]]; then
print_message "Setting up SSL with Let's Encrypt..."
apt install -y certbot python3-certbot-nginx
certbot --nginx -d "$DOMAIN_NAME"
print_message "SSL setup complete!"
fi
print_message "Deployment completed successfully!"
print_message "You can now access your application at: http://$DOMAIN_NAME"
if [[ "$SETUP_SSL" =~ ^[Yy]$ ]]; then
print_message "Or securely at: https://$DOMAIN_NAME"
fi
print_message "Admin interface is available at: http://$DOMAIN_NAME/admin"
print_message "Admin password: $ADMIN_PASSWORD"
exit 0