# 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 " ``` ### 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) ```bash dokku config:set casera-api \ GORUSH_CORE_PORT=8080 \ GORUSH_IOS_ENABLED=true \ GORUSH_IOS_KEY_PATH=/push_certs/AuthKey_R9N3SM2WD5.p8 \ GORUSH_IOS_KEY_ID=R9N3SM2WD5 \ GORUSH_IOS_TEAM_ID=V3PF3M6B6U \ GORUSH_IOS_TOPIC=com.tt.casera.CaseraDev \ GORUSH_IOS_PRODUCTION=true \ GORUSH_ANDROID_ENABLED=false ``` // GORUSH_ANDROID_APIKEY=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..." ``` --- #### 7. Set Proxy Port ```bash dokku proxy:ports-set gorush http:80:8080 ``` #### 8. Restart Gorush ```bash dokku ps:restart gorush ``` #### 9. Configure Casera API to Use Gorush ```bash dokku config:set casera-api GORUSH_URL=http://gorush.web:8080 ``` #### 10. Verify Gorush is Running ```bash # Check status dokku ps:report gorush # Check logs dokku logs gorush # Test health endpoint (if you have a domain set) curl http://gorush.yourdomain.com/api/stat/go ``` ### Option B: Use External Push Service Configure the app to use an external push notification service instead. --- ## 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 | | `GORUSH_URL` | No | Push notification server URL | | `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 |