#!/bin/bash # DocFast Infrastructure Setup Script # Provisions a fresh Ubuntu/Debian server with all required services # Run as root: ./setup.sh set -euo pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color log() { echo -e "${GREEN}[INFO]${NC} $1" } warn() { echo -e "${YELLOW}[WARN]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" exit 1 } # Check if running as root if [[ $EUID -ne 0 ]]; then error "This script must be run as root" fi # Domain and user configuration DOMAIN="${DOMAIN:-docfast.dev}" APP_USER="${APP_USER:-docfast}" BACKUP_DIR="/opt/docfast-backups" INSTALL_DIR="/opt/docfast" log "Setting up DocFast infrastructure for domain: $DOMAIN" # Update system log "Updating system packages..." apt update && apt upgrade -y # Install required packages log "Installing required packages..." apt install -y \ nginx \ postfix \ opendkim \ opendkim-tools \ certbot \ python3-certbot-nginx \ ufw \ docker.io \ docker-compose-plugin \ git \ sqlite3 \ curl \ wget \ unzip \ htop \ postgresql \ postgresql-contrib # Enable and start services log "Enabling services..." systemctl enable nginx postfix opendkim docker postgresql systemctl start nginx postfix opendkim docker postgresql # Create application user if ! id "$APP_USER" &>/dev/null; then log "Creating application user: $APP_USER" useradd -r -m -s /bin/bash "$APP_USER" fi # Add user to docker group usermod -aG docker "$APP_USER" # Setup UFW firewall log "Configuring firewall..." ufw --force enable ufw default deny incoming ufw default allow outgoing ufw allow ssh ufw allow 80/tcp ufw allow 443/tcp ufw allow from 172.16.0.0/12 to any port 25 comment "Docker SMTP relay" ufw allow from 172.16.0.0/12 to any port 5432 comment "Docker PostgreSQL" # Setup PostgreSQL log "Configuring PostgreSQL..." sudo -u postgres createuser -D -A -P docfast || true # -P prompts for password sudo -u postgres createdb -O docfast docfast || true # Update PostgreSQL to allow Docker connections PG_VERSION=$(ls /etc/postgresql/) PG_CONF="/etc/postgresql/$PG_VERSION/main/postgresql.conf" PG_HBA="/etc/postgresql/$PG_VERSION/main/pg_hba.conf" # Backup original configs cp "$PG_CONF" "$PG_CONF.backup" || true cp "$PG_HBA" "$PG_HBA.backup" || true # Allow connections from Docker networks if ! grep -q "listen_addresses = '*'" "$PG_CONF"; then sed -i "s/#listen_addresses = 'localhost'/listen_addresses = '*'/" "$PG_CONF" fi # Allow Docker networks to connect if ! grep -q "172.17.0.0/16" "$PG_HBA"; then echo "host docfast docfast 172.17.0.0/16 md5" >> "$PG_HBA" echo "host docfast docfast 172.18.0.0/16 md5" >> "$PG_HBA" fi systemctl restart postgresql # Setup OpenDKIM log "Configuring OpenDKIM..." mkdir -p /etc/opendkim/keys/"$DOMAIN" chown -R opendkim:opendkim /etc/opendkim/keys # Generate DKIM keys if they don't exist if [[ ! -f /etc/opendkim/keys/"$DOMAIN"/mail.private ]]; then log "Generating DKIM keys..." cd /etc/opendkim/keys/"$DOMAIN" opendkim-genkey -s mail -d "$DOMAIN" chown opendkim:opendkim mail.private mail.txt chmod 600 mail.private fi # Copy configuration files log "Installing configuration files..." cp nginx/"$DOMAIN" /etc/nginx/sites-available/"$DOMAIN" || warn "Nginx config not found, you'll need to configure manually" cp postfix/main.cf /etc/postfix/main.cf || warn "Postfix config not found, you'll need to configure manually" cp postfix/opendkim.conf /etc/opendkim.conf || warn "OpenDKIM config not found, you'll need to configure manually" cp postfix/TrustedHosts /etc/opendkim/TrustedHosts || warn "TrustedHosts config not found, you'll need to configure manually" # Enable nginx site if [[ -f /etc/nginx/sites-available/"$DOMAIN" ]]; then ln -sf /etc/nginx/sites-available/"$DOMAIN" /etc/nginx/sites-enabled/ rm -f /etc/nginx/sites-enabled/default nginx -t && systemctl reload nginx fi # Update configurations with actual domain log "Updating configuration files..." sed -i "s/docfast\.dev/$DOMAIN/g" /etc/nginx/sites-available/"$DOMAIN" 2>/dev/null || true sed -i "s/docfast\.dev/$DOMAIN/g" /etc/postfix/main.cf 2>/dev/null || true sed -i "s/docfast\.dev/$DOMAIN/g" /etc/opendkim.conf 2>/dev/null || true # Restart services with new configs systemctl restart postfix opendkim # Setup backup directory and script log "Setting up backup system..." mkdir -p "$BACKUP_DIR" cp ../scripts/docfast-backup.sh /opt/docfast-backup.sh || warn "Backup script not found" chmod +x /opt/docfast-backup.sh # Add backup cron job if ! crontab -l 2>/dev/null | grep -q docfast-backup; then (crontab -l 2>/dev/null; echo "0 */6 * * * /opt/docfast-backup.sh >> /var/log/docfast-backup.log 2>&1") | crontab - fi # Setup application directory log "Setting up application directory..." mkdir -p "$INSTALL_DIR" chown "$APP_USER":"$APP_USER" "$INSTALL_DIR" # Install Docker Compose if ! command -v docker-compose &> /dev/null; then log "Installing docker-compose..." COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d\" -f4) curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose fi log "Base infrastructure setup complete!" echo log "Next steps:" echo "1. Configure DNS A record for $DOMAIN to point to this server" echo "2. Generate SSL certificates: certbot --nginx -d $DOMAIN" echo "3. Copy your .env file with secrets to $INSTALL_DIR/.env" echo "4. Copy your docker-compose.yml to $INSTALL_DIR/" echo "5. Build and start the application:" echo " cd $INSTALL_DIR" echo " docker-compose up -d" echo warn "Remember to:" echo "- Set up your DKIM DNS record (see /etc/opendkim/keys/$DOMAIN/mail.txt)" echo "- Configure Stripe webhooks" echo "- Set up monitoring/alerting" echo "- Test email delivery"