Skip to content

Instantly share code, notes, and snippets.

@douglasjarquin
Forked from kjlape/Dockerfile
Created November 4, 2024 18:23
Show Gist options
  • Save douglasjarquin/ab460f42c184ef2d4a3989016fb07afe to your computer and use it in GitHub Desktop.
Save douglasjarquin/ab460f42c184ef2d4a3989016fb07afe to your computer and use it in GitHub Desktop.
Self-Hosted Docker Registry with Kamal (as of version 2.2.2)

Problem

Kamal smooths over a lot of the rough edges of hosting an app on a server you control. One problem that needs a little more sanding is that kamal requires us to have a docker registry to push our images to. Unless you're doing open source, you probably want these app images to stay private! Until we get an official answer from kamal here's a workaround that I've been using.

Be aware that you still need some kind of public image hosting due to limitations in kamal as of version 2.2.2. There's a hack at the bottom of this document to work around this limitation as well.

Steps to deploy

  • Change values in the deploy config to suit your setup
  • Run kamal deploy
  • Run kamal htpasswd-set <username> <password> to set as many credentials as you need or rotate keys
  • Enjoy!

Optional: Self-host (Do this before deploying)

On your local machine…

  • docker run --volume ./auth:/auth --rm --entrypoint htpasswd httpd:2 -Bb /auth/htpasswd <username> <password>
  • docker run --volume ./auth:/auth --rm --port 5000:5000 -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry:2
  • In another terminal ngrok http 5000
  • Copy the ngrok url, and place it in your kamal config under registry/server
  • Ensure the credentials you gave it are configured in your kamal secrets
  • Run the steps to deploy
  • Optional: Replace the ngrok url with your freshly deployed docker registry
  • I also have a video about this on YouTube
service: docker-registry
image: my-company/docker-registry
servers:
web:
- 1.3.3.7
proxy:
ssl: true
host: docker.my-company.com
app_port: 5000
healthcheck:
path: /
registry:
username: username
server: <some url>.ngrok-free.app
password:
- KAMAL_REGISTRY_PASSWORD
builder:
arch: arm64 # This is the platform I tested on, but it should work on any platform.
volumes:
- auth:/auth
env:
clear:
REGISTRY_HTTP_ADDR: 0.0.0.0:5000
REGISTRY_AUTH: htpasswd
REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
aliases:
shell: app exec --interactive --reuse "sh"
htpasswd-set: server exec docker run --volume auth:/auth --rm --entrypoint htpasswd httpd:2 -Bb /auth/htpasswd
htpasswd-delete: server exec docker run --volume auth:/auth --rm --entrypoint htpasswd httpd:2 -D /auth/htpasswd
htpasswd-print: server exec docker run --volume auth:/auth --rm --entrypoint cat httpd:2 /auth/htpasswd
FROM registry:2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment