Kamal is built for Linux servers, so a Mac mini needs a few workarounds. It works because Kamal only needs SSH plus a working docker command on the target. Here’s the path:

1. Prepare the Mac mini

Docker via Colima, started at boot (from the previous answer):

brew install colima docker
brew services start colima

Make docker available to non-interactive SSH sessions. This is the most common failure. Kamal runs commands over SSH without loading your login profile, so Homebrew’s path is missing. On the mini, add to ~/.zshenv (not .zprofile):

export PATH="/opt/homebrew/bin:$PATH"

Verify from the MacBook:

ssh youruser@mac-mini.local docker ps

If that prints a container list (even empty), you’re set.

SSH keys (so Kamal can log in without a password):

ssh-copy-id youruser@mac-mini.local

2. Set up Kamal in your Rails app

Rails 8 already includes Kamal and a Dockerfile. Otherwise:

bundle add kamal
bundle exec kamal init

Make sure you have a production-ready Dockerfile (Rails 7.1+ generates one).

3. Configure config/deploy.yml

service: myapp
image: yourdockerhubuser/myapp

servers:
  web:
    - mac-mini.local        # or the mini's IP

ssh:
  user: youruser

proxy:
  ssl: false                # no Let's Encrypt on a LAN-only host
  app_port: 80              # Rails 8 Dockerfile uses Thruster on 80; use 3000 for older Dockerfiles

registry:
  username: yourdockerhubuser
  password:
    - KAMAL_REGISTRY_PASSWORD

builder:
  arch: arm64               # the mini is Apple Silicon; use amd64 if it's an Intel mini

env:
  secret:
    - RAILS_MASTER_KEY

volumes:
  - "myapp_storage:/rails/storage"   # persists SQLite DB / uploads (Rails 8 default)

Notes:

  • Registry: Kamal pushes the image to a registry and the mini pulls it. Docker Hub or GitHub Container Registry both work. Kamal 2 also supports a local registry (registry: server: localhost:5555) if you don’t want an account.
  • Builder arch: If your MacBook is Apple Silicon too, builds are native and fast. If it’s Intel and the mini is ARM, Kamal will cross-build, which is slower.

4. Secrets

In .kamal/secrets:

KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
RAILS_MASTER_KEY=$(cat config/master.key)

Export your registry token in your shell first, or pull it from a password manager.

5. Adjust Rails for plain HTTP

Since there’s no SSL, in config/environments/production.rb set:

config.assume_ssl = false
config.force_ssl = false

Otherwise Rails redirects to HTTPS and you’ll get redirect loops or failed health checks.

6. Deploy

kamal setup      # first time: bootstraps, boots kamal-proxy, builds, pushes, deploys
kamal deploy     # subsequent deploys

Then open http://mac-mini.local in your browser.

Useful commands: kamal app logs -f, kamal app exec -i bash, kamal rollback <version>.

Gotchas

  • Docker bootstrap: kamal setup tries to install Docker if it isn’t found, and that only works on Linux. If the PATH fix above is in place, Kamal detects Docker and skips this.
  • Sleep: Keep the mini awake (Energy settings, “Wake for network access”), otherwise your app disappears.
  • Colima resources: The default is 2 CPUs/2 GB RAM. For a Rails app plus a database you may want colima start --cpu 4 --memory 6.
  • Ports 80/443: Colima forwards these, but if something else on the mini already uses port 80, kamal-proxy will fail to start.
  • Reliability: Colima inside macOS is fine for a home setup, but it isn’t a typical production target. If you run into odd issues, a small Ubuntu VM on the mini (via UTM/Multipass) would be a closer match to what Kamal expects.

If you want to reach the app from outside your home, Tailscale (or Cloudflare Tunnel with a real domain for SSL) pairs well with this. Tell me whether your app uses SQLite or Postgres and I can add the database part to the config.

🤖 created with help of ai