# Dokku Deployment Guide for Casera API

This guide provides step-by-step instructions for deploying the Casera Go API to a remote server using Dokku.

## Table of Contents

1. [Prerequisites](#prerequisites)
2. [Server Setup](#server-setup)
3. [Install Dokku](#install-dokku)
4. [Create the App](#create-the-app)
5. [Configure PostgreSQL](#configure-postgresql)
6. [Configure Redis](#configure-redis)
7. [Set Environment Variables](#set-environment-variables)
8. [Configure Storage](#configure-storage)
9. [Deploy the Application](#deploy-the-application)
10. [Configure SSL](#configure-ssl)
11. [Set Up Worker Process](#set-up-worker-process)
12. [Push Notifications (Optional)](#push-notifications-optional)
13. [Maintenance Commands](#maintenance-commands)
14. [Troubleshooting](#troubleshooting)

---

## Prerequisites

### Server Requirements
- Ubuntu 22.04 LTS (recommended) or 20.04 LTS
- Minimum 2GB RAM (4GB+ recommended for production)
- 20GB+ disk space
- Root or sudo access
- Domain name pointed to your server's IP

### Local Requirements
- Git installed
- SSH key configured for server access

---

## Server Setup

### 1. Connect to Your Server

```bash
ssh root@your-server-ip
```

### 2. Update System Packages

```bash
apt update && apt upgrade -y
```

### 3. Set Up Swap (Recommended for servers with limited RAM)

```bash
# Create 2GB swap file
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

# Make permanent
echo '/swapfile none swap sw 0 0' | tee -a /etc/fstab
```

### 4. Configure Firewall

```bash
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable
```

---

## Install Dokku

### 1. Download and Install Dokku

```bash
# Download the installation script
wget -NP . https://dokku.com/install/v0.34.4/bootstrap.sh

# Run the installer (takes 5-10 minutes)
sudo DOKKU_TAG=v0.34.4 bash bootstrap.sh
```

### 2. Configure Dokku

```bash
# Set your domain (replace with your actual domain)
dokku domains:set-global casera.treytartt.com

# Add your SSH public key for deployments
# Run this from your LOCAL machine:
cat ~/.ssh/id_rsa.pub | ssh root@your-server-ip dokku ssh-keys:add admin
```

### 3. Install Required Plugins

```bash
# PostgreSQL plugin
dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres

# Redis plugin
dokku plugin:install https://github.com/dokku/dokku-redis.git redis

# Let's Encrypt plugin (for SSL)
dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git
```

---

## Create the App

### 1. Create the Dokku App

```bash
dokku apps:create casera-api
```

### 2. Set the Domain

```bash
dokku domains:add casera-api api.casera.treytartt.com
```

### 3. Configure Buildpack (if needed)

The app uses a Dockerfile, so Dokku will auto-detect it. If you need to force Docker builds:

```bash
dokku builder:set casera-api build-dir .
dokku builder-dockerfile:set casera-api dockerfile-path Dockerfile
```

---

## Configure PostgreSQL

### 1. Create PostgreSQL Service

```bash
# Create the database service
dokku postgres:create casera-db

# Link to the app (automatically sets DATABASE_URL)
dokku postgres:link casera-db casera-api
```

### 2. Verify Connection

```bash
# Check the connection info
dokku postgres:info casera-db

# Connect to the database
dokku postgres:connect casera-db
```

### 3. Set Individual Database Variables

Dokku sets `DATABASE_URL` automatically, but the app expects individual variables:

```bash
# Get the database credentials
dokku postgres:info casera-db

# Set individual variables (replace with actual values from info command)
dokku config:set casera-api \
  DB_HOST=dokku-postgres-casera-db \
  DB_PORT=5432 \
  POSTGRES_DB=casera_db \
  POSTGRES_USER=postgres \
  POSTGRES_PASSWORD=1mJPfu6rzG9r6xukcGbUOU5NoCg0jKfa
```

---

## Configure Redis

### 1. Create Redis Service

```bash
# Create the Redis service
dokku redis:create casera-redis

# Link to the app (automatically sets REDIS_URL)
dokku redis:link casera-redis casera-api
```

### 2. Verify Connection

```bash
dokku redis:info casera-redis
```

---

## Set Environment Variables

### 1. Required Variables

```bash
dokku config:set casera-api \
  PORT=5000 \
  DEBUG=false \
  ALLOWED_HOSTS=api.casera.treytartt.com,localhost \
  TIMEZONE=UTC \
  SECRET_KEY=8553813eda361017a02677ed504abdd331537cfe6f7cc407345f037cc22c75fc
```

### 2. Email Configuration

```bash
dokku config:set casera-api \
  EMAIL_HOST=smtp.fastmail.com \
  EMAIL_PORT=587 \
  EMAIL_USE_TLS=true \
  EMAIL_HOST_USER=treytartt@fastmail.com \
  EMAIL_HOST_PASSWORD=2t9y4n4t497z5863 \
  DEFAULT_FROM_EMAIL="Casera <treytartt@fastmail.com>"
```

### 3. Apple Sign In (Optional)

```bash
dokku config:set casera-api \
  APPLE_CLIENT_ID=com.tt.casera.CaseraDev \
  APPLE_TEAM_ID=V3PF3M6B6U
```

### 4. Push Notifications (Optional)

The API uses direct APNs/FCM connections (no external push server needed):

```bash
dokku config:set casera-api \
  APNS_AUTH_KEY_PATH=/push_certs/AuthKey_R9N3SM2WD5.p8 \
  APNS_AUTH_KEY_ID=R9N3SM2WD5 \
  APNS_TEAM_ID=V3PF3M6B6U \
  APNS_TOPIC=com.tt.casera.CaseraDev \
  APNS_PRODUCTION=true \
  FCM_SERVER_KEY=your-firebase-server-key
```

### 5. Admin Panel URL

```bash
dokku config:set casera-api \
  NEXT_PUBLIC_API_URL=https://api.casera.treytartt.com
```

### 6. View All Configuration

```bash
dokku config:show casera-api
```

---

## Configure Storage

### 1. Create Persistent Storage Directory

```bash
# Create storage directory on host
mkdir -p /var/lib/dokku/data/storage/casera-api/uploads

# Set permissions
chown -R 32767:32767 /var/lib/dokku/data/storage/casera-api
```

### 2. Mount Storage to App

```bash
dokku storage:mount casera-api /var/lib/dokku/data/storage/casera-api/uploads:/app/uploads
```

---

## Deploy the Application

### 1. Add Dokku Remote (Local Machine)

```bash
cd /path/to/myCribAPI-go
git remote add dokku dokku@your-server-ip:casera-api
```

### 2. Deploy

```bash
git push dokku master:main
# Or if your branch is already 'main':
git push dokku main
```

### 3. Watch Deployment Logs

```bash
# On server
dokku logs casera-api -t
```

### 4. Verify Deployment

```bash
# Check app status
dokku ps:report casera-api

# Check app is running
curl https://api.casera.treytartt.com/api/health/
```

---

## Configure SSL

### 1. Set Let's Encrypt Email

```bash
dokku letsencrypt:set casera-api email admin@treytartt.com
```

### 2. Enable Let's Encrypt

```bash
dokku letsencrypt:enable casera-api
```

### 3. Set Up Auto-Renewal

```bash
dokku letsencrypt:cron-job --add
```

---

## Set Up Worker Process

The worker process handles background jobs (task reminders, overdue alerts, daily digests, email sending, etc.).

### 1. Configure Worker Environment Variables

```bash
dokku config:set casera-api \
  TASK_REMINDER_HOUR=20 \
  TASK_REMINDER_MINUTE=0 \
  OVERDUE_REMINDER_HOUR=9 \
  DAILY_DIGEST_HOUR=11
```

**Schedule times are in UTC:**
| Variable | Default | Description |
|----------|---------|-------------|
| `TASK_REMINDER_HOUR` | 20 | Hour to send "task due soon" notifications (8 PM UTC) |
| `TASK_REMINDER_MINUTE` | 0 | Minute for task reminder |
| `OVERDUE_REMINDER_HOUR` | 9 | Hour to send overdue task alerts (9 AM UTC) |
| `DAILY_DIGEST_HOUR` | 11 | Hour to send daily summary (11 AM UTC) |

### 2. Scale Worker Process

```bash
# Scale to 1 worker
dokku ps:scale casera-api worker=1

# Verify processes
dokku ps:report casera-api
```

### 3. Verify Worker is Running

```bash
# Check worker logs
dokku logs casera-api -p worker

# Should see:
# "Registered task reminder job"
# "Registered overdue reminder job"
# "Registered daily digest job"
# "Starting worker server..."
```

---

## Maintenance Commands

### View Logs

```bash
# Real-time logs
dokku logs casera-api -t

# Last 100 lines
dokku logs casera-api -n 100

# Worker logs
dokku logs casera-api -p worker
```

### Database Operations

```bash
# Connect to database
dokku postgres:connect casera-db

# Export database backup
dokku postgres:export casera-db > backup.sql

# Import database backup
dokku postgres:import casera-db < backup.sql
```

### Run Migrations Manually

```bash
# Enter the app container
dokku enter casera-api web

# Migrations run automatically on startup, but if needed:
/app/api migrate
```

### Restart App

```bash
dokku ps:restart casera-api
```

### Scale App

```bash
# Scale web process
dokku ps:scale casera-api web=2 worker=1

# View current scale
dokku ps:report casera-api
```

### Stop/Start App

```bash
dokku ps:stop casera-api
dokku ps:start casera-api
```

---

## Troubleshooting

### Check App Status

```bash
dokku ps:report casera-api
dokku logs casera-api -n 200
```

### Common Issues

#### 1. App Won't Start

```bash
# Check logs for errors
dokku logs casera-api -n 500

# Verify environment variables
dokku config:show casera-api

# Check if ports are available
dokku proxy:ports casera-api
```

#### 2. Database Connection Failed

```bash
# Verify link
dokku postgres:linked casera-api casera-db

# Check database is running
dokku postgres:info casera-db

# Re-link if needed
dokku postgres:unlink casera-db casera-api
dokku postgres:link casera-db casera-api
```

#### 3. Redis Connection Failed

```bash
# Verify link
dokku redis:linked casera-api casera-redis

# Check Redis is running
dokku redis:info casera-redis
```

#### 4. Storage/Upload Issues

```bash
# Check mounts
dokku storage:report casera-api

# Verify permissions
ls -la /var/lib/dokku/data/storage/casera-api/
```

#### 5. SSL Certificate Issues

```bash
# Check certificate status
dokku letsencrypt:list

# Renew manually
dokku letsencrypt:enable casera-api
```

### View Resource Usage

```bash
# Docker stats for all containers
docker stats

# Disk usage
dokku storage:report casera-api
df -h
```

---

## Quick Reference

| Command | Description |
|---------|-------------|
| `dokku apps:list` | List all apps |
| `dokku logs casera-api -t` | Tail logs |
| `dokku ps:restart casera-api` | Restart app |
| `dokku config:show casera-api` | Show env vars |
| `dokku postgres:connect casera-db` | Connect to DB |
| `dokku enter casera-api web` | Shell into container |
| `dokku ps:scale casera-api web=2` | Scale processes |

---

## Environment Variables Reference

| Variable | Required | Description |
|----------|----------|-------------|
| `SECRET_KEY` | Yes | 32+ character secret key |
| `DEBUG` | Yes | Set to `false` in production |
| `ALLOWED_HOSTS` | Yes | Comma-separated list of domains |
| `DATABASE_URL` | Auto | Set by postgres:link |
| `REDIS_URL` | Auto | Set by redis:link |
| `EMAIL_HOST` | Yes | SMTP server |
| `EMAIL_PORT` | Yes | SMTP port (587) |
| `EMAIL_HOST_USER` | Yes | SMTP username |
| `EMAIL_HOST_PASSWORD` | Yes | SMTP password |
| `APPLE_CLIENT_ID` | No | iOS Bundle ID |
| `APPLE_TEAM_ID` | No | Apple Developer Team ID |
| `APNS_AUTH_KEY_PATH` | No | Path to APNs .p8 key |
| `APNS_AUTH_KEY_ID` | No | APNs Key ID |
| `APNS_TEAM_ID` | No | APNs Team ID |
| `APNS_TOPIC` | No | APNs topic (bundle ID) |
| `APNS_PRODUCTION` | No | Use production APNs (default: false) |
| `FCM_SERVER_KEY` | No | Firebase Cloud Messaging server key |
