Skip to content

Deploy with Kamal

Kamal (v2) deploys TrocOS to any VPS using Docker. It handles zero-downtime deploys, SSL, and a PostgreSQL container as an accessory. This option gives you the most control and lowest running cost.

Prerequisites

  • A VPS running Ubuntu 22.04+ (e.g., Hetzner, OVH, DigitalOcean) — 1 vCPU / 1 GB RAM minimum
  • Docker installed on the VPS: curl -fsSL https://get.docker.com | sh
  • A container registry account (Docker Hub, GitLab Registry, or GitHub Container Registry)
  • Your domain's DNS pointing to the VPS IP
  • Ruby 3.2+ and the kamal gem on your local machine: gem install kamal

1. Configure config/deploy.yml

Edit config/deploy.yml in the TrocOS repo. Here is an annotated starting point:

yaml
service: trocos
image: registry.example.com/yourorg/trocos

servers:
  web:
    hosts:
      - YOUR_VPS_IP

# kamal-proxy handles routing and SSL (replaces Traefik from v1)
proxy:
  host: your-domain.com
  app_port: 3000
  ssl: true                    # automatic Let's Encrypt
  healthcheck:
    path: /up

registry:
  server: registry.example.com
  username: youruser
  password:
    - KAMAL_REGISTRY_PASSWORD  # resolved from .kamal/secrets

builder:
  arch: amd64

env:
  secret:
    - DATABASE_URL
  clear:
    RAILS_ENV: production

accessories:
  postgres:
    image: postgres:16
    host: YOUR_VPS_IP
    port: "127.0.0.1:5432:5432"
    env:
      clear:
        POSTGRES_DB: trocos_production
        POSTGRES_USER: trocos
      secret:
        - POSTGRES_PASSWORD
    directories:
      - postgres-data:/var/lib/postgresql/data

2. Create .kamal/secrets

This file is sourced before every deploy. Do not commit it to git.

bash
# .kamal/secrets
KAMAL_REGISTRY_PASSWORD=your_registry_password
POSTGRES_PASSWORD=choose_a_strong_password
DATABASE_URL="postgres://trocos:${POSTGRES_PASSWORD}@trocos-postgres/trocos_production"

Add .kamal/secrets to your .gitignore.

Kamal v2 vs v1

Kamal v2 uses proxy: (not traefik:), .kamal/secrets (not .env), and SSL is configured with ssl: true under proxy:. If you're migrating from v1, see the Kamal upgrade guide.

3. First deploy

sh
# Start the PostgreSQL accessory first
kamal accessory boot postgres

# Build the image, push it, and deploy
kamal setup

4. Run migrations and first-time setup

sh
kamal app exec 'bin/rails db:migrate'
kamal app exec 'bin/rails trocos:setup'

The trocos:setup task creates your first admin account.

5. Subsequent deploys

sh
kamal deploy

Kamal performs a zero-downtime rolling deploy.

Useful commands

sh
kamal app logs              # Stream application logs
kamal app exec 'bin/rails console'   # Open Rails console
kamal app exec 'bin/rails db:migrate'  # Run pending migrations
kamal accessory logs postgres        # PostgreSQL logs

Released under the AGPL-3.0 License.