#!/bin/bash # FluentGerman.ai — Debian deployment setup script # Run as root or with sudo set -e APP_NAME="fluentgerman" APP_DIR="/opt/$APP_NAME" # Resolved from this script's location, so the copies below survive the `cd` # in step 5 and don't depend on where the script was invoked from. REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)" # A fresh install has no .env yet, so nothing depends on the database password # and we can generate one. An existing install keeps whatever its .env holds. FRESH_INSTALL=true [ -f "$APP_DIR/backend/.env" ] && FRESH_INSTALL=false APP_USER="fluentgerman" DB_NAME="fluentgerman" DB_USER="fluentgerman" echo "=== FluentGerman.ai — Deployment Setup ===" # 1. System user if ! id "$APP_USER" &>/dev/null; then useradd --system --no-create-home --shell /bin/false "$APP_USER" echo "✓ Created system user: $APP_USER" fi # 2. Install Python if needed apt-get update -qq apt-get install -y -qq python3 python3-venv python3-pip > /dev/null echo "✓ Python installed" # Generated here, not earlier: a minimal Debian has no python3 until now DB_PASSWORD="$(python3 -c 'import secrets; print(secrets.token_urlsafe(24))')" # 3. MySQL database setup echo "Setting up MySQL database..." mysql -u root -e "CREATE DATABASE IF NOT EXISTS $DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" mysql -u root -e "CREATE USER IF NOT EXISTS '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASSWORD';" if [ "$FRESH_INSTALL" = true ]; then # Nothing is using the old password yet — pin it to the one .env will get mysql -u root -e "ALTER USER '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASSWORD';" fi mysql -u root -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost';" mysql -u root -e "FLUSH PRIVILEGES;" echo "✓ MySQL database ready" # 4. Application directory mkdir -p "$APP_DIR/backend" "$APP_DIR/frontend" cp -r "$REPO_DIR"/backend/* "$APP_DIR/backend/" # `*` never matches dotfiles, and step 6 needs this one cp "$REPO_DIR/backend/.env.example" "$APP_DIR/backend/" cp -r "$REPO_DIR"/frontend/* "$APP_DIR/frontend/" chown -R "$APP_USER:$APP_USER" "$APP_DIR" echo "✓ Files deployed to $APP_DIR" # 5. Python virtual environment cd "$APP_DIR/backend" python3 -m venv venv source venv/bin/activate pip install --quiet -r requirements.txt deactivate echo "✓ Python venv created" # 6. Environment file if [ "$FRESH_INSTALL" = true ]; then cp "$APP_DIR/backend/.env.example" "$APP_DIR/backend/.env" # Generate random secret key SECRET=$(python3 -c "import secrets; print(secrets.token_urlsafe(48))") sed -i "s/generate-a-strong-random-key-here/$SECRET/" "$APP_DIR/backend/.env" # Match the database user created above (token_urlsafe is / and # free) sed -i "s#://$DB_USER:YOUR_PASSWORD@#://$DB_USER:$DB_PASSWORD@#" "$APP_DIR/backend/.env" # It holds real credentials now chown "$APP_USER:$APP_USER" "$APP_DIR/backend/.env" chmod 600 "$APP_DIR/backend/.env" echo "⚠ Created .env from template — EDIT $APP_DIR/backend/.env with your API keys and passwords!" fi # 7. Systemd service cp "$REPO_DIR/deploy/fluentgerman.service" /etc/systemd/system/ systemctl daemon-reload systemctl enable "$APP_NAME" if [ "$FRESH_INSTALL" = true ]; then # Don't go live with the template's LLM key and default admin password echo "✓ Systemd service installed (not started — configure .env first)" else systemctl restart "$APP_NAME" echo "✓ Systemd service restarted" fi # 8. Nginx config cp "$REPO_DIR/deploy/nginx.conf.example" /etc/nginx/sites-available/$APP_NAME ln -sf /etc/nginx/sites-available/$APP_NAME /etc/nginx/sites-enabled/ nginx -t && systemctl reload nginx echo "✓ Nginx configured" echo "" echo "=== Deployment complete! ===" if [ "$FRESH_INSTALL" = true ]; then echo "The database password was generated and written to .env — leave it alone." echo "1. Edit /opt/$APP_NAME/backend/.env: set LLM_API_KEY and ADMIN_PASSWORD" echo "2. Start it: systemctl start $APP_NAME" echo "3. Access: http://your-server-domain" else echo "1. Edit /opt/$APP_NAME/backend/.env if anything changed" echo "2. Restart: systemctl restart $APP_NAME" echo "3. Access: http://your-server-domain" fi