Comprehensive step-by-step instructions for deploying to a remote server: - Server setup and prerequisites - Dokku installation and plugins - PostgreSQL and Redis configuration - Environment variables reference - SSL setup with Let's Encrypt - Worker process scaling - Push notifications setup - Maintenance commands and troubleshooting 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
592 lines
11 KiB
Markdown
592 lines
11 KiB
Markdown
# 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.yourdomain.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.yourdomain.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=<password-from-info>
|
|
```
|
|
|
|
---
|
|
|
|
## 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.yourdomain.com,localhost \
|
|
TIMEZONE=UTC \
|
|
SECRET_KEY=$(openssl rand -hex 32)
|
|
```
|
|
|
|
### 2. Email Configuration
|
|
|
|
```bash
|
|
dokku config:set casera-api \
|
|
EMAIL_HOST=smtp.gmail.com \
|
|
EMAIL_PORT=587 \
|
|
EMAIL_USE_TLS=true \
|
|
EMAIL_HOST_USER=your-email@gmail.com \
|
|
EMAIL_HOST_PASSWORD=your-app-password \
|
|
DEFAULT_FROM_EMAIL="Casera <noreply@casera.com>"
|
|
```
|
|
|
|
### 3. Apple Sign In (Optional)
|
|
|
|
```bash
|
|
dokku config:set casera-api \
|
|
APPLE_CLIENT_ID=com.yourcompany.casera \
|
|
APPLE_TEAM_ID=XXXXXXXXXX
|
|
```
|
|
|
|
### 4. Push Notifications (Optional)
|
|
|
|
```bash
|
|
dokku config:set casera-api \
|
|
GORUSH_URL=http://localhost:8088 \
|
|
APNS_AUTH_KEY_ID=XXXXXXXXXX \
|
|
APNS_TEAM_ID=XXXXXXXXXX \
|
|
APNS_TOPIC=com.yourcompany.casera \
|
|
APNS_USE_SANDBOX=false \
|
|
FCM_SERVER_KEY=your-firebase-server-key
|
|
```
|
|
|
|
### 5. Admin Panel URL
|
|
|
|
```bash
|
|
dokku config:set casera-api \
|
|
NEXT_PUBLIC_API_URL=https://api.casera.yourdomain.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
|
|
```
|
|
|
|
### 3. For Push Notification Certificates
|
|
|
|
```bash
|
|
# Create certs directory
|
|
mkdir -p /var/lib/dokku/data/storage/casera-api/certs
|
|
|
|
# Copy your APNs key file
|
|
scp /local/path/to/AuthKey_XXXXXX.p8 root@your-server:/var/lib/dokku/data/storage/casera-api/certs/apns_key.p8
|
|
|
|
# Mount certs directory
|
|
dokku storage:mount casera-api /var/lib/dokku/data/storage/casera-api/certs:/certs:ro
|
|
|
|
# Set the path in config
|
|
dokku config:set casera-api APNS_AUTH_KEY_PATH=/certs/apns_key.p8
|
|
```
|
|
|
|
---
|
|
|
|
## 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.yourdomain.com/api/health/
|
|
```
|
|
|
|
---
|
|
|
|
## Configure SSL
|
|
|
|
### 1. Set Let's Encrypt Email
|
|
|
|
```bash
|
|
dokku letsencrypt:set casera-api email admin@yourdomain.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, email sending, etc.).
|
|
|
|
### 1. Create Procfile (if not exists)
|
|
|
|
The Dockerfile already handles this, but if you need a Procfile:
|
|
|
|
```bash
|
|
# In your local repo, create Procfile:
|
|
echo "web: /app/api" > Procfile
|
|
echo "worker: /app/worker" >> Procfile
|
|
```
|
|
|
|
### 2. Scale Worker Process
|
|
|
|
```bash
|
|
# Scale to 1 worker
|
|
dokku ps:scale casera-api worker=1
|
|
|
|
# Verify processes
|
|
dokku ps:report casera-api
|
|
```
|
|
|
|
---
|
|
|
|
## Push Notifications (Optional)
|
|
|
|
### Option A: Run Gorush as Separate Dokku App
|
|
|
|
```bash
|
|
# Create Gorush app
|
|
dokku apps:create gorush
|
|
|
|
# Deploy Gorush (using Docker image)
|
|
dokku git:from-image gorush appleboy/gorush:latest
|
|
|
|
# Set environment
|
|
dokku config:set gorush \
|
|
GORUSH_CORE_PORT=8080 \
|
|
GORUSH_IOS_ENABLED=true \
|
|
GORUSH_IOS_KEY_ID=XXXXXXXXXX \
|
|
GORUSH_IOS_TEAM_ID=XXXXXXXXXX \
|
|
GORUSH_IOS_TOPIC=com.yourcompany.casera \
|
|
GORUSH_IOS_PRODUCTION=true
|
|
|
|
# Mount certificates
|
|
dokku storage:mount gorush /var/lib/dokku/data/storage/casera-api/certs:/certs:ro
|
|
dokku config:set gorush GORUSH_IOS_KEY_PATH=/certs/apns_key.p8
|
|
|
|
# Update Casera API to point to Gorush
|
|
dokku config:set casera-api GORUSH_URL=http://gorush.web:8080
|
|
```
|
|
|
|
### 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 |
|