#!/bin/bash # Smartbotic Nginx + SSL Setup Script # Sets up nginx as reverse proxy with Let's Encrypt SSL # # Usage: # sudo ./setup-nginx.sh --domain console.example.com --email admin@example.com # sudo ./setup-nginx.sh --domain console.example.com --email admin@example.com --staging set -e # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' print_info() { echo -e "${GREEN}[INFO]${NC} $1"; } print_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } print_error() { echo -e "${RED}[ERROR]${NC} $1"; } print_step() { echo -e "${BLUE}[STEP]${NC} $1"; } usage() { cat < /dev/null; then print_info " nginx is already installed" return fi if [ "$DRY_RUN" = true ]; then echo " [DRY-RUN] apt-get update && apt-get install -y nginx" else apt-get update -qq apt-get install -y nginx fi } # Install certbot install_certbot() { print_step "Installing certbot..." if command -v certbot &> /dev/null; then print_info " certbot is already installed" return fi if [ "$DRY_RUN" = true ]; then echo " [DRY-RUN] apt-get install -y certbot python3-certbot-nginx" else apt-get update -qq apt-get install -y certbot python3-certbot-nginx fi } # Create initial HTTP-only config for certificate issuance create_http_config() { print_step "Creating initial HTTP configuration..." run_cmd mkdir -p "$CERTBOT_WEBROOT" local http_config="# Temporary HTTP config for Let's Encrypt challenge server { listen 80; listen [::]:80; server_name $SERVER_NAMES; location /.well-known/acme-challenge/ { root $CERTBOT_WEBROOT; } location / { return 503 'SSL certificate pending'; add_header Content-Type text/plain; } } " if [ "$DRY_RUN" = true ]; then echo " [DRY-RUN] Creating $NGINX_CONF" echo "$http_config" else echo "$http_config" > "$NGINX_CONF" ln -sf "$NGINX_CONF" "$NGINX_ENABLED" 2>/dev/null || true # Remove default site if exists rm -f /etc/nginx/sites-enabled/default 2>/dev/null || true nginx -t && systemctl reload nginx fi } # Obtain SSL certificate obtain_certificate() { print_step "Obtaining SSL certificate from Let's Encrypt..." print_info " Domains: $SERVER_NAMES" local certbot_args="certonly --webroot -w $CERTBOT_WEBROOT $CERTBOT_DOMAINS --email $EMAIL --agree-tos --non-interactive" if [ "$STAGING" = true ]; then certbot_args="$certbot_args --staging" print_warn " Using Let's Encrypt STAGING server (certificates won't be trusted)" fi if [ "$DRY_RUN" = true ]; then echo " [DRY-RUN] certbot $certbot_args" else certbot $certbot_args fi } # Create full HTTPS config create_https_config() { print_step "Creating HTTPS configuration..." local template template=$(find_template) if [ -z "$template" ]; then print_error "Cannot find nginx template file" print_info "Expected locations:" print_info " - $TEMPLATE_DIR/smartbotic.conf.template" print_info " - /opt/smartbotic/share/smartbotic/nginx/smartbotic.conf.template" exit 1 fi print_info " Using template: $template" print_info " Primary domain: $PRIMARY_DOMAIN" print_info " All domains: $SERVER_NAMES" if [ "$DRY_RUN" = true ]; then echo " [DRY-RUN] Generating config from template" else # Replace placeholders sed -e "s/{{DOMAIN}}/$PRIMARY_DOMAIN/g" \ -e "s/{{SERVER_NAMES}}/$SERVER_NAMES/g" \ "$template" > "$NGINX_CONF" nginx -t && systemctl reload nginx fi } # Create HTTP-only config (no SSL) create_http_only_config() { print_step "Creating HTTP-only configuration (no SSL)..." local http_config="# Smartbotic Nginx Configuration (HTTP only) # Domains: $SERVER_NAMES upstream smartbotic_http { server 127.0.0.1:8090; keepalive 32; } server { listen 80; listen [::]:80; server_name $SERVER_NAMES; access_log /var/log/nginx/smartbotic_access.log; error_log /var/log/nginx/smartbotic_error.log; client_max_body_size 50M; # Gzip compression gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml; location /api/ { proxy_pass http://smartbotic_http; proxy_http_version 1.1; proxy_set_header Host \$host; 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; proxy_set_header Connection \"\"; proxy_read_timeout 300s; proxy_buffering off; } location / { proxy_pass http://smartbotic_http; proxy_http_version 1.1; proxy_set_header Host \$host; 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; proxy_set_header Connection \"\"; } } " if [ "$DRY_RUN" = true ]; then echo " [DRY-RUN] Creating $NGINX_CONF" else echo "$http_config" > "$NGINX_CONF" ln -sf "$NGINX_CONF" "$NGINX_ENABLED" 2>/dev/null || true rm -f /etc/nginx/sites-enabled/default 2>/dev/null || true nginx -t && systemctl reload nginx fi } # Setup certificate renewal setup_renewal() { print_step "Setting up automatic certificate renewal..." if [ "$DRY_RUN" = true ]; then echo " [DRY-RUN] Configuring certbot renewal timer" else systemctl enable certbot.timer 2>/dev/null || true systemctl start certbot.timer 2>/dev/null || true print_info " Certbot renewal timer enabled" fi } # Renew certificates renew_certificates() { print_step "Renewing certificates..." if [ "$DRY_RUN" = true ]; then echo " [DRY-RUN] certbot renew" else certbot renew systemctl reload nginx fi } # Main main() { echo "" print_info "Smartbotic Nginx + SSL Setup" print_info "============================" if [ ${#DOMAINS[@]} -gt 0 ]; then print_info "Domains: $SERVER_NAMES" fi if [ -n "$EMAIL" ]; then print_info "Email: $EMAIL" fi if [ "$STAGING" = true ]; then print_warn "Mode: STAGING (test certificates)" fi if [ "$DRY_RUN" = true ]; then print_warn "DRY-RUN MODE - no changes will be made" fi echo "" if [ "$RENEW" = true ]; then renew_certificates echo "" print_info "Certificate renewal complete!" exit 0 fi # Install packages install_nginx if [ "$NO_SSL" = true ]; then # HTTP only mode create_http_only_config echo "" print_info "Nginx configured (HTTP only)" print_info "Access WebUI at: http://$PRIMARY_DOMAIN/" elif [ "$NGINX_ONLY" = true ]; then # Just nginx, no certbot create_http_only_config echo "" print_info "Nginx installed and configured" print_info "Run with --email to set up SSL later" else # Full SSL setup install_certbot # Check if certificate already exists if [ -d "/etc/letsencrypt/live/$PRIMARY_DOMAIN" ] && [ "$DRY_RUN" = false ]; then print_info "Certificate already exists for $PRIMARY_DOMAIN" create_https_config else create_http_config obtain_certificate create_https_config fi setup_renewal echo "" print_info "Setup complete!" echo "" echo "Your Smartbotic instance is now available at:" for d in "${DOMAINS[@]}"; do echo " https://$d/" done echo "" echo "Certificate renewal is automatic via certbot timer." echo "To manually renew: sudo certbot renew" echo "" fi # Enable and start nginx if [ "$DRY_RUN" = false ]; then systemctl enable nginx systemctl start nginx 2>/dev/null || systemctl reload nginx fi } main