Writing · 2026 · 1 min

Self-Host any Docker image using Kamal

I been using Kamal for the past year in my own Ruby on Rails projects. And it’s fantastic:

  • One yaml file for config
  • Light-weight
  • Fast deployments
  • Command line tool
  • It’s open source
  • Can build / pull any docker image
  • Automatic SSL certs
  • Manages env vars
  • Can deploy multiple docker services
  • New does not require a repository for custom images

So naturally I wanted to also use this for my own self-hosting. But this tool was not developed for deploying premade docker images, so I had to make a work around. It basically involves creating a wrapper docker file that just pulls the original image. This isn’t ideal, but it works with no issues.

I haven’t seen this documented anywhere, so I decided to share this.

Setup

I’ll show you how to install Vikunja on your own server. If you don’t know, this is an open-source todo app, and it’s fairly lightweight.

  • Install Ruby
gem install kamal
mkdir vikunja
mkdir vikunja/config
touch vikunja/config/deploy.yml
touch vikunja/Dockerfile

Creating the deploy.yml

The basic deploy.yml looks like this, replace it with your server:

service: vikunja
image: myname/vikunja

servers:
  web:
    - myip

proxy:
  ssl: true
  host: myhost
  app_port: 3456

registry:
  # Points to your local Kamal registry tunnel
  server: localhost:5555

ssh:
  user: app

builder:
  arch: arm64 # change this to make the arch
  context: .

env:
  clear:
    VIKUNJA_SERVICE_PUBLICURL: https://myhost
    VIKUNJA_SERVICE_ENABLEREGISTRATION: "false"
    VIKUNJA_DATABASE_PATH: /db/vikunja.db
  secret:
    - VIKUNJA_SERVICE_JWTSECRET

volumes:
  - "/data/vikunja-files:/app/vikunja/files"
  - "/data/vikunja-db:/db"
  - "/data/vikunja-cache:/.cache"

Creating Secrets

If you don’t want to commit your secrets, like VIKUNJA_SERVICE_JWTSECRET, you can create a new directory:

mkdir .kamal
vim .kamal/secrets

And in this file paste in your secrets:

VIKUNJA_SERVICE_JWTSECRET=mysecretcode12344

Creating the Dockerfile

This file just wraps the original image.

# Inherit directly from the official Vikunja image
FROM vikunja/vikunja:latest

# No changes needed, but you can add custom labels if you want
LABEL description="Vikunja wrapped for Kamal deployment"

Deploying

cd vikunja
kamal setup
kamal repository setup
kamal deploy

Final Tree

Your dir structure should look something like this:

.
|____README.md
|____.gitignore
|____Gemfile
|____.kamal
| |____secrets
|____config
| |____deploy.yml
|____Gemfile.lock
|____Dockerfile

I used a Gemfile to lock the version of Kamal, but this isn’t necessary.

Good luck!

Comments

No comments yet. Be the first.

Leave a comment

Plain text. Comments are reviewed before they appear; your email is never asked for.