自宅サーバーにKamalでデプロイしてみた
やりたいこと
ローカルネットワーク内にLinuxサーバーを配置して、そこに公開用アプリと非公開用アプリを動かしたい
図にするとこんな感じです。
※Unboundはただのネームサーバーなので、この図はちょっとおかしいですが、ご容赦ください 🙏
つかうもの
- Docker Hub
- Unbound
- Cloudflare Tunnel
- Kamal
実行環境
- デプロイを実行する環境
- Ubuntu on WSL2
- 自宅サーバー
- EndeavourOS
つかうものの説明
Docker Hub
(2025/07時点で)KamalはPublicなDocker imageを使ったアプリケーションを動かすことが標準ではサポートされていないように見えます。
理由は、Kamalを実行するディレクトリのgitのコミットハッシュを基準としたDocker imageのタグを利用してデプロイするのが基本的な挙動なので、このあたりに追従することが難しいです。
自宅サーバーであれば、Docker Registryを自前運用すればいいだろうと考えたのですが、Kamalで利用しているDocker buildxにInsecureのパラメータをうまく渡すことができず(?)、めんどくさかったのでDocker Hubを利用するようにしました。
💭 フリーランスのお仕事でDockerを使っているので、無料の範囲内で使えますが、ありがたく使わせてもらっているので、このタイミングで課金しました(Private Repositoryが使いたかった)。
Unbound
Kamal Proxyでサブドメインに応じたDispatchをさせたいので、ネームサーバーを自宅サーバー上に構築しました。
外部に公開したくないアプリのドメインは、別になんでもいいわけですし。
↓のように、内部用のドメインを自宅サーバーのIPに流すだけですね。
local-data: "aa.example.internal. 300 IN A 192.168.1.xxx"
local-data: "bb.example.internal. 300 IN A 192.168.1.xxx"
💭 サブドメインごとに指定しているけど、いらないのでは・・・。
Cloudflare Tunnel
Cloudflareが無料で提供しているサービスで、自宅サーバーとCloudflareの間にトンネルを張って、外部からアクセスできるようにする便利なサービスです。
80ポートなどを開放する必要もなく、Dockerでサクッと起動することもでき、大変便利です。
設定
*.example.comを*.example.internalに流すだけです

起動
docker run -d --restart unless-stopped --network=host cloudflare/cloudflared:latest tunnel --no-autoupdate run --token xxx
Kamal
本題のKamalです。
Kamalがv2になったときProxyがTraefikから自前のKamal Proxyになってだいぶ設定がしやすくなったっぽい(?)です。
というのも、今回のように、アプリごとにサブドメインの設定があると思うのですが、各アプリのKamal configに自分のサブドメインの設定だけを行えば、あとはよしなにやってくれます。
もちろん、サブドメイン名の衝突が起こると問題があるでしょうが、そんなことをする人はいないはず。
設定
とあるPublicなRailsアプリを例にとります。
# config/deploy.yml
service: example
image: kehra/example
servers:
web:
- 192.168.1.xxx
proxy:
app_port: 3000
host: cc.example.com
registry:
username: test
password:
- KAMAL_REGISTRY_PASSWORD
env:
secret:
- RAILS_MASTER_KEY
volumes:
- "storage:/rails/storage"
asset_path: /rails/public/assets
builder:
arch: amd64
ssh:
user: kehra
keys: [ ~/.ssh/id_rsa ]
# .env
RAILS_MASTER_KEY=your_rails_master_key_here
KAMAL_REGISTRY_PASSWORD=your_registry_password_here
あとは、.envを何かしらの方法で読み込んで、kamal setupをするだけです。
締め
Claude Codeなど多様なAIツールのおかげで、ちょっとしたアプリを作るハードルが大きく下がったと思います。
しかし、それらを定常的に動かす場をサクッと用意したいなと思い、Dockerで動かすことを前提とした自宅サーバーを用意してみました。
お仕事ではRailsをメインで使っているので、Kamalがどういうものかを使って確かめるというところからも、こんな構成を取ってみました。
もし、どなたかのご参考になれば嬉しいです。
Discussion