# Optimization Factory Deployment Guide

This deployment solution provides two distinct deployment paths for the Optimization Factory application, with the ability to seamlessly switch between them on an already-deployed machine.

## Overview

The deployment script (`deploy.sh`) offers two modes:

- **Simple Mode**: Quick setup for testing, accessing the application directly via the server's IP address and a configurable port (e.g., `http://203.0.113.55:8080`)
- **Production Mode**: Full-featured deployment with a custom domain and free SSL certificate (e.g., `https://www.example.com`)

The script intelligently handles cleanup of the old mode before setting up the new one, making it safe to switch between deployment modes.

## Prerequisites

- Ubuntu 22.04 EC2 instance with root/sudo access
- For production mode: A registered domain name
- For production mode: DNS management access to create A records
- **AWS Configuration**: Properly configured AWS credentials and permissions

### AWS Configuration Setup

Before deploying the application, you must configure AWS credentials and permissions:

#### Option 1: IAM Role (Recommended for EC2)

1. **Create an IAM Role**:

   - Go to AWS IAM Console → Roles → Create Role
   - Select "EC2" as the service
   - Attach policies with necessary permissions (e.g., `S3FullAccess`, `EC2FullAccess`, etc.)
   - Name your role (e.g., `OptimizationFactoryRole`)

2. **Attach the role to your EC2 instance**:
   - Go to EC2 Console → Instances
   - Select your instance → Actions → Security → Modify IAM Role
   - Choose the role you created
   - Apply changes

#### Option 2: AWS Credentials File

1. **Install AWS CLI** (if not already installed):

   ```bash
   sudo apt update
   sudo apt install awscli -y
   ```

2. **Configure AWS credentials**:

   ```bash
   aws configure
   ```

   Enter your:

   - AWS Access Key ID
   - AWS Secret Access Key
   - Default region (e.g., `us-east-1`)
   - Default output format (e.g., `json`)

3. **Verify configuration**:
   ```bash
   aws sts get-caller-identity
   ```

#### Required AWS Permissions

Ensure your AWS credentials/role have the following permissions:

- **S3**: Full access to buckets used by the application
- **EC2**: Instance management permissions
- **IAM**: Basic read permissions (if needed)
- **CloudWatch**: Log access (if using logging)

#### Environment Variables

Add these to your `.env` file:

```bash
# AWS Configuration
AWS_ACCESS_KEY_ID=your_access_key
AWS_SECRET_ACCESS_KEY=your_secret_key
AWS_DEFAULT_REGION=us-east-1
```

### SSH Key Configuration Setup

The application needs SSH access to connect to optimization instances. The deployment script automatically handles SSH key setup, but you need to ensure your SSH key is available.

#### Required SSH Key

You need an SSH key pair that matches the key pair used when launching EC2 instances for optimization jobs. The deployment script will automatically detect the SSH key name from your `.env` file's `SSH_KEY_PATH` setting.

#### Automatic SSH Key Setup (Recommended)

The deployment script automatically:

1. **Creates SSH directory**: Sets up `/var/www/.ssh/` for the `www-data` user
2. **Sets proper permissions**: Ensures security with correct file permissions (700 for directory, 600 for key)
3. **Auto-detects key**: Extracts the SSH key name from your `.env` file's `SSH_KEY_PATH` and looks for it in common locations:
   - `/home/ubuntu/.ssh/[your-key-name].pem`
   - `/root/.ssh/[your-key-name].pem`
4. **Copies key**: Automatically copies the key to the correct location for `www-data` user
5. **Updates .env file**: Automatically sets `SSH_KEY_PATH=/var/www/.ssh/[your-key-name].pem` in your `.env` file
6. **Provides guidance**: Shows helpful instructions if the key isn't found

#### Manual SSH Key Setup (If Needed)

If the automatic setup doesn't find your SSH key, you can manually copy it:

```bash
# Create SSH directory for www-data user
sudo mkdir -p /var/www/.ssh

# Copy your SSH key (replace with your actual key path and name)
sudo cp /path/to/your/[your-key-name].pem /var/www/.ssh/

# Set proper ownership and permissions
sudo chown -R www-data:www-data /var/www/.ssh
sudo chmod 700 /var/www/.ssh
sudo chmod 600 /var/www/.ssh/[your-key-name].pem
```

#### Verify SSH Key Setup

After deployment, verify the SSH key is properly configured:

```bash
# Check if the key exists and has correct permissions
sudo ls -la /var/www/.ssh/

# Test SSH connection (replace with actual optimization instance IP and your key name)
sudo -u www-data ssh -i /var/www/.ssh/[your-key-name].pem ubuntu@optimization-instance-ip
```

#### SSH Key Requirements

- **Key Name**: Any name (automatically detected from `SSH_KEY_PATH` in your `.env` file)
- **Key Format**: PEM format (standard AWS EC2 key pair format)
- **Permissions**: 600 (readable only by owner)
- **Location**: Must be accessible to the `www-data` user
- **Matching**: Must match the key pair used when launching optimization EC2 instances

## Path A: Simple IP-Based Deployment

This mode is perfect for testing, development, or quick deployments where you want direct access via IP address.

### Step-by-Step Instructions

1. **SSH into your server**:

   ```bash
   ssh -i your-key.pem ubuntu@your-server-ip
   ```

2. **Clone the repository**:

   ```bash
   git clone https://github.com/your-org/optimization-factory.git
   cd optimization-factory
   ```

3. **Navigate to deployment directory and make script executable**:

   ```bash
   cd deployment
   chmod +x deploy.sh
   ```

4. **Create the environment file**:

   ```bash
   cp ../env.example ../.env
   nano ../.env
   ```

   **Important**: Set the `PORT` variable in the `.env` file. For example:

   ```
   PORT=8080
   ```

   Also configure your other required variables like `CODEFLASH_API_KEY`, `GITHUB_TOKEN`, etc.

5. **Run the deployment script in simple mode**:

   ```bash
   sudo ./deploy.sh simple
   ```

6. **Access your application**:
   The script will output the URL where your application is accessible. It will be something like:
   ```
   http://203.0.113.55:8080
   ```

### Expected Output

```
[INFO] Starting deployment in 'simple' mode...
[INFO] Performing common setup...
[INFO] Installing common dependencies...
[INFO] Copying application from current project directory...
[INFO] Application directory exists, preserving data files...
[INFO] Backed up jobs.json
[INFO] Backed up config directory
[INFO] Backed up .env file
[INFO] Restoring preserved data files...
[SUCCESS] Restored jobs.json
[SUCCESS] Restored config directory
[SUCCESS] Restored .env file
[INFO] Cleaned up temporary backup files
[INFO] Setting proper permissions...
[INFO] Creating symlinks for data file access...
[SUCCESS] Created symlink for jobs.json
[SUCCESS] Created symlink for config directory
[SUCCESS] Created symlink for .env file
[INFO] Setting up Python virtual environment...
[INFO] Installing Python dependencies...
[SUCCESS] AWS credentials verified successfully
[INFO] Setting up SSH keys for www-data user...
[INFO] Found SSH key name in .env: Deployed_Optimization_Factory_key_pair.pem
[INFO] Found SSH key 'Deployed_Optimization_Factory_key_pair.pem' in ubuntu user directory, copying to www-data...
[SUCCESS] SSH key copied successfully
[INFO] Updating .env file with correct SSH key path...
[SUCCESS] SSH key path updated in .env file: /var/www/.ssh/Deployed_Optimization_Factory_key_pair.pem
[INFO] Configuring for Simple IP-Based Deployment...
[INFO] Cleaning up any existing production configuration...
[INFO] Using port: 8080
[INFO] Configuring firewall...
[INFO] Creating systemd service...
[INFO] Starting service...
[SUCCESS] Simple deployment completed!
[SUCCESS] Your application is now accessible at: http://203.0.113.55:8080
[INFO] Service status: active
[SUCCESS] Deployment completed successfully!
```

## Path B: Production Deployment (Domain + SSL)

This mode provides a production-ready deployment with Nginx reverse proxy, custom domain, and SSL certificate.

### Step-by-Step Instructions

#### Step 3.1: Point Your Domain

1. **Get your server's public IP**:

   ```bash
   curl ifconfig.me
   ```

2. **Create an A record in your DNS settings**:
   - Log into your domain registrar or DNS provider
   - Create an A record pointing your domain (e.g., `www.example.com`) to your server's public IP
   - Wait for DNS propagation (usually 5-15 minutes)

#### Step 3.2: Run the Deployment Script

1. **SSH into your server**:

   ```bash
   ssh -i your-key.pem ubuntu@your-server-ip
   ```

2. **Clone the repository** (if not already done):

   ```bash
   git clone https://github.com/your-org/optimization-factory.git
   cd optimization-factory
   ```

3. **Navigate to deployment directory and make script executable**:

   ```bash
   cd deployment
   chmod +x deploy.sh
   ```

4. **Create the environment file**:

   ```bash
   cp ../env.example ../.env
   nano ../.env
   ```

   Configure your required variables. Note: The `PORT` variable is not used in production mode as Nginx handles the port.

5. **Run the deployment script in production mode**:
   ```bash
   sudo ./deploy.sh production
   ```

#### Step 3.3: Configure Your Domain in Nginx

1. **Edit the Nginx configuration**:

   ```bash
   sudo nano /etc/nginx/sites-available/optimization-factory
   ```

2. **Replace the placeholder domain**:
   Find the line:

   ```
   server_name your_domain.com; # <-- CHANGE THIS TO YOUR ACTUAL DOMAIN
   ```

   Replace `your_domain.com` with your actual domain:

   ```
   server_name www.example.com;
   ```

3. **Restart Nginx**:

   ```bash
   sudo systemctl restart nginx
   ```

4. **Test your domain**:
   Visit `http://www.example.com` in your browser. You should see your application.

#### Step 3.4: Enable HTTPS with Certbot

1. **Install Certbot**:

   ```bash
   sudo apt install certbot python3-certbot-nginx -y
   ```

2. **Obtain SSL certificate**:

   ```bash
   sudo certbot --nginx -d www.example.com
   ```

3. **Follow the prompts**:

   - Enter your email address
   - Agree to terms of service
   - Choose whether to share your email with EFF
   - Certbot will automatically configure Nginx for HTTPS

4. **Test automatic renewal**:

   ```bash
   sudo certbot renew --dry-run
   ```

5. **Access your secure application**:
   Visit `https://www.example.com` - you should see your application with a valid SSL certificate.

## How to Update the Application

To deploy new code or updates:

1. **SSH into your server**:

   ```bash
   ssh -i your-key.pem ubuntu@your-server-ip
   ```

2. **Navigate to the deployment directory**:

   ```bash
   cd optimization-factory/deployment
   ```

3. **Re-run the deployment script with your current mode**:

   ```bash
   # If you're currently in simple mode:
   sudo ./deploy.sh simple

   # If you're currently in production mode:
   sudo ./deploy.sh production
   ```

### Data Preservation During Updates

The deployment script automatically preserves your data during updates:

- ✅ **jobs.json**: Preserves running job states and instance mappings
- ✅ **config/analysis/**: Preserves all analysis results and configurations
- ✅ **config/repos.csv**: Preserves repository configurations
- ✅ **.env**: Preserves your environment variables and settings

### Symlink Access

After deployment, you can access data files from your original repository directory:

```bash
# Access jobs.json from your repository
cat server/jobs.json

# Access config files
ls -la config/

# Edit repository configurations
nano config/repos.csv

# View analysis results
ls -la config/analysis/
```

The script creates symlinks so you can edit files in your familiar repository location while the application uses the deployed version.

The script will automatically pull the latest code and restart the services.

## Switching Between Deployment Modes

This is a powerful feature that allows you to reconfigure your server from one mode to another without manual cleanup.

### Switching from Simple to Production Mode

If you're currently running in simple mode and want to switch to production mode:

1. **Ensure your domain is pointing to your server** (see Step 3.1 above)

2. **Run the production deployment**:
   ```bash
   sudo ./deploy.sh production
   ```

The script will automatically:

- Stop and disable Nginx (if running)
- Remove the simple mode firewall rules
- Install and configure Nginx
- Set up the production firewall rules
- Configure the application to use Unix socket instead of TCP port
- Start both the application and Nginx services

3. **Configure your domain** (see Step 3.3 above)

4. **Enable SSL** (see Step 3.4 above)

### Switching from Production to Simple Mode

If you're currently running in production mode and want to switch to simple mode:

1. **Configure your .env file** with the desired PORT:

   ```bash
   sudo nano /opt/optimization-factory/.env
   ```

   Set: `PORT=8080` (or your preferred port)

2. **Run the simple deployment**:
   ```bash
   sudo ./deploy.sh simple
   ```

The script will automatically:

- Stop and disable Nginx
- Remove Nginx configuration files
- Remove production firewall rules
- Configure the application to use TCP port instead of Unix socket
- Set up simple mode firewall rules
- Start the application service

3. **Access your application** at `http://your-server-ip:8080`

## Managing Services & Viewing Logs

### Service Management Commands

**Check service status**:

```bash
sudo systemctl status optimization-factory
sudo systemctl status nginx  # (production mode only)
```

**Restart services**:

```bash
sudo systemctl restart optimization-factory
sudo systemctl restart nginx  # (production mode only)
```

**Stop services**:

```bash
sudo systemctl stop optimization-factory
sudo systemctl stop nginx  # (production mode only)
```

**Enable/disable services**:

```bash
sudo systemctl enable optimization-factory
sudo systemctl disable optimization-factory
```

### Viewing Logs

**Application logs**:

```bash
# View recent logs
sudo journalctl -u optimization-factory

# Follow logs in real-time
sudo journalctl -u optimization-factory -f

# View logs from last boot
sudo journalctl -u optimization-factory -b

# View logs with timestamps
sudo journalctl -u optimization-factory --since "1 hour ago"
```

**Nginx logs** (production mode only):

```bash
# Access logs
sudo tail -f /var/log/nginx/access.log

# Error logs
sudo tail -f /var/log/nginx/error.log

# Combined logs
sudo tail -f /var/log/nginx/access.log /var/log/nginx/error.log
```

**System logs**:

```bash
# View system logs
sudo journalctl -f

# View boot logs
sudo journalctl -b
```

### Troubleshooting

**If the application won't start**:

1. Check the service status: `sudo systemctl status optimization-factory`
2. View logs: `sudo journalctl -u optimization-factory -f`
3. Check the .env file: `sudo nano /opt/optimization-factory/.env`
4. Verify Python dependencies: `sudo /opt/optimization-factory/venv/bin/pip list`

**If optimization jobs fail with SSH errors**:

1. Check SSH key exists: `sudo ls -la /var/www/.ssh/`
2. Verify key permissions: `sudo ls -la /var/www/.ssh/Deployed_Optimization_Factory_key_pair.pem`
3. Test SSH connection: `sudo -u www-data ssh -i /var/www/.ssh/Deployed_Optimization_Factory_key_pair.pem ubuntu@instance-ip`
4. Ensure key matches EC2 key pair: Check AWS EC2 Console → Key Pairs
5. Re-run deployment script: `sudo ./deploy.sh simple` (or `production`)

**If AWS credentials are not working**:

1. Check AWS credentials: `aws sts get-caller-identity`
2. Verify .env file has AWS variables: `sudo nano /opt/optimization-factory/.env`
3. Check IAM role attachment: AWS EC2 Console → Instances → Your Instance → Security → IAM Role
4. Test AWS CLI: `aws ec2 describe-instances --region us-east-2`

**If Nginx won't start** (production mode):

1. Check Nginx status: `sudo systemctl status nginx`
2. Test configuration: `sudo nginx -t`
3. View error logs: `sudo tail -f /var/log/nginx/error.log`

**If SSL certificate issues** (production mode):

1. Check certificate status: `sudo certbot certificates`
2. Test renewal: `sudo certbot renew --dry-run`
3. View Certbot logs: `sudo tail -f /var/log/letsencrypt/letsencrypt.log`

## Security Considerations

- The application runs as the `www-data` user for security
- Firewall rules are automatically configured based on the deployment mode
- Security headers are included in the Nginx configuration
- SSL certificates are automatically renewed by Certbot
- Regular security updates should be applied: `sudo apt update && sudo apt upgrade`

## File Locations

- Application directory: `/opt/optimization-factory`
- Environment file: `/opt/optimization-factory/.env`
- Systemd service: `/etc/systemd/system/optimization-factory.service`
- Nginx configuration: `/etc/nginx/sites-available/optimization-factory`
- Application logs: `journalctl -u optimization-factory`
- Nginx logs: `/var/log/nginx/`

## Support

For issues or questions:

1. Check the logs first using the commands above
2. Verify your configuration files
3. Ensure all prerequisites are met
4. Check that your domain DNS is properly configured (production mode)
5. Verify firewall rules are correct for your deployment mode
