Bendangelo

Ben Avatar

I build apps using Ruby on Rails and AI. Also am fluent in Mandarin Chinese.

Self-Host any Docker image using Kamal

Jan 12, 2026 1 minute read

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

You can use your Fediverse (i.e., Mastodon, among many others) account to reply to this post.

Related Posts