Mac+multipassでセルフDocker Paasを試してみる
手元でHerokuっぽく使えるものがあるといいなというところで。
できるかはわからないけどやってみる。
- dokku
- coolify
- caprover
あたり。
M2 mac miniで。
Dokku
セットアップ
とりあえずcloud-initはあまり凝ってないもので。
#cloud-config
locale: ja_JP.UTF-8
timezone: Asia/Tokyo
users:
- name: ubuntu
plain_text_passwd: ubuntu
sudo: ALL=(ALL) NOPASSWD:ALL
package_update: true
package_upgrade: true
packages:
- sudo
- wget
- curl
- tzdata
- vim
- git
- jq
- lsb-release
- ca-certificates
- gnupg2
- unzip
VM起動。
$ multipass launch 20.04 --name dokku-test -c 4 -m 4g -d 50g --cloud-init cloud-config.yaml
起動後にネットワーク確認。IPアドレスを控えておく。
$ multipass list
Name State IPv4 Image
primary Stopped -- Ubuntu 22.04 LTS
dokku-test Running 192.168.64.44 Ubuntu 22.04 LTS
172.17.0.1
Dokkuでデプロイする際に必要となるSSH鍵ペアを作成。
$ ssh-keygen -t ed25519 -C "dokku" -f ./id_ed25519_dokku
公開鍵をVMにアップロード
$ multipass transfer ./id_ed25519_dokku.pub dokku-test:.ssh/.
VMにログイン
$ multipass shell dokku-test
ドキュメントに従ってDokkuインストール
$ wget -NP . https://dokku.com/install/v0.32.4/bootstrap.sh
$ sudo DOKKU_TAG=v0.32.4 bash bootstrap.sh
SSH公開鍵をセット、これがgit pushする際の公開鍵になる模様。
$ cat ~/.ssh/id_ed25519_dokku.pub | sudo dokku ssh-keys:add admin
Dokkuのドメインを設定。今回はローカルなのでIPアドレスで。
dokku domains:set-global 192.168.64.44
アプリケーションのデプロイ
こちらもGetting Startedに従って。
まずDokku側でアプリケーションの作成を行う。引き続きmultipassのDokku VMにはログインしたままで以下を実行。
アプリケーション作成。
$ dokku apps:create ruby-getting-started
-----> Creating ruby-getting-started...
-----> Global server virtual host not set, disabling app vhost...
PostgreSQLのプラグインを有効化して、データベースを作成。
$ sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git
-----> Cloning plugin repo https://github.com/dokku/dokku-postgres.git to /var/lib/dokku/plugins/available/postgres
(snip)
$ dokku postgres:create railsdatabase
Waiting for container to be ready
Creating container database
Securing connection to database
=====> Postgres container created: railsdatabase
=====> railsdatabase postgres service information
Config dir: /var/lib/dokku/services/postgres/railsdatabase/data
Config options:
Data dir: /var/lib/dokku/services/postgres/railsdatabase/data
Dsn: postgres://postgres:9f08ec07b0115ae0b59b478280005c1f@dokku-postgres-railsdatabase:5432/railsdatabase
Exposed ports: -
Id: 582f39cb1dbbb435d1e21540e9a7751b180f87d15c7f787eefd4559175ad9ebd
Internal ip: 172.17.0.2
Initial network:
Links: -
Post create network:
Post start network:
Service root: /var/lib/dokku/services/postgres/railsdatabase
Status: running
Version: postgres:16.1
アプリケーションとデータベースの紐づけ
$ dokku postgres:link railsdatabase ruby-getting-started
-----> Setting config vars
DATABASE_URL: postgres://postgres:9f08ec07b0115ae0b59b478280005c1f@dokku-postgres-railsdatabase:5432/railsdatabase
-----> Restarting app ruby-getting-started
! App image (dokku/ruby-getting-started:latest) not found
アプリケーションは作成したけどまだコードをpushしてないのでこうなるみたい。
では手元のマシンからデプロイしてみる。
$ git clone https://github.com/heroku/ruby-getting-started
$ cd ruby-getting-started
リモートレポジトリを設定する前に~/.ssh/configを修正して、上で作成した秘密鍵を使うようにする。
Host 192.168.64.44
HostName 192.168.64.44
User dokku
IdentityFile /SOMEWHERE/id_ed25519_dokku
リモートブランチ設定。ユーザー名は"dokku"限定らしい
$ git remote add dokku dokku@192.168.64.44:ruby-getting-started
push。
$ git push dokku main
怒られた。。。
Enumerating objects: 547, done.
Counting objects: 100% (547/547), done.
Delta compression using up to 12 threads
Compressing objects: 100% (272/272), done.
Writing objects: 100% (547/547), 130.28 KiB | 130.28 MiB/s, done.
Total 547 (delta 245), reused 547 (delta 245), pack-reused 0
remote: Resolving deltas: 100% (245/245), done.
-----> Set main as deploy-branch
remote: ! Herokuish builder not supported on arm64 servers.
remote: ! Switching to pack builder.
-----> Cleaning up...
-----> Building ruby-getting-started from cnb stack heroku/builder:22 (experimental)...
remote: ! Missing pack, install it
remote: ! Removing invalid image tag dokku/ruby-getting-started:latest
remote: ! App build failed
To 192.168.64.44:ruby-getting-started
! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to '192.168.64.44:ruby-getting-started'
デプロイにはデフォルトでHeroku buildpacks
を使うプラグインが使用されるのだけど、adm64以外のプラットフォームでは無効化されているっぽい。M2 macはarm64になるのでビルドが失敗→デプロイ失敗となってる様子。
By default, the builder-herokuish plugin is not enabled for non-amd64 platforms, and attempting to use it is blocked. This is because the majority of buildpacks are not cross-platform compatible, and thus building apps will either be considerably slower - due to emulating the amd64 platform - or won't work - due to building amd64 packages on arm64 platforms.
https://dokku.com/docs/deployment/builders/herokuish-buildpacks/
強制的にherokuishを使うには、dokku VM側で以下を設定する必要がある。なお、以下は今回のアプリ限定の設定で、グローバルに設定することもできる様子。
$ dokku builder-herokuish:set ruby-getting-started allowed true
=====> Setting allowed to true
再度push、、、もやはりエラー。
Enumerating objects: 547, done.
Counting objects: 100% (547/547), done.
Delta compression using up to 12 threads
Compressing objects: 100% (272/272), done.
Writing objects: 100% (547/547), 130.28 KiB | 130.28 MiB/s, done.
Total 547 (delta 245), reused 547 (delta 245), pack-reused 0
remote: Resolving deltas: 100% (245/245), done.
-----> Cleaning up...
-----> Building ruby-getting-started from herokuish
-----> Setting config vars
CURL_CONNECT_TIMEOUT: 90
-----> Setting config vars
CURL_TIMEOUT: 600
-----> Adding BUILD_ENV to build environment...
BUILD_ENV added successfully
-----> Warning: Multiple default buildpacks reported the ability to handle this app. The first buildpack in the list below will be used.
Detected buildpacks: ruby nodejs
-----> Ruby app detected
remote: /tmp/buildpacks/01_buildpack-ruby/bin/compile: line 31: /tmp/tmp.R09XW9fbhk/bin/ruby: cannot execute binary file: Exec format error
remote: ! Failure during app build
remote: ! Removing invalid image tag dokku/ruby-getting-started:latest
remote: ! App build failed
To 192.168.64.44:ruby-getting-started
! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to '192.168.64.44:ruby-getting-started'
んー、アプリケーションの作りにもよるのだろうけども、元のサンプルはHerokuのバイナリ環境で動くことが前提になっててHerokuはamd64ってことなんだろうな。なのでアーキテクチャが違うM2 Macだ動かないということなのかも・・・ってことはIntel Macなら問題ないんではなかろうか。
Dockerアプリケーションのデプロイ
あと別の手段としてはDockerfileでデプロイする方法もある模様なのでこちらをやってみる。
ということでこちらを使ってみる。
再度Dokku VM側でアプリケーション設定。
再度アプリケーションを作成
$ dokku apps:create blog-react-app
Dockerデプロイを有効化。dockerfile-path
はレポジトリルートのDockerfileを使う場合は空で良いらしい。
$ dokku builder-dockerfile:set blog-react-app dockerfile-path
逆にデフォルトのルートのDockerfileじゃない場合はこういう感じでパスを指定してあげるっぽい。今回はしない。
$ dokku builder-dockerfile:set blog-react-app dockerfile-path Dockerfile.multipass
このサンプルレポジトリではDBも何も使ってないようなので、紐づけはしない。
では、ローカルからデプロイしてみる。
$ git clone https://github.com/dockersamples/blog-react-app
$ cd blog-react-app
$ git remote add dokku dokku@192.168.64.44:blog-react-app
$ git push dokku main
デプロイできた。
(snip)
=====> Application deployed:
http://192.168.64.44:3000
To 192.168.64.44:blog-react-app
* [new branch] main -> main
ブラウザでもOK。
Dockerなら問題なさそう。
なお、docker-composeには対応していないみたいだけど、docker-compose.yamlをdokkuのコマンドに書き換えるツールがある模様。
所感
dokkuコマンドは、Dokku VM内で叩くしかないのかなー、ただそれだけのことだけど、ちょっと手間に感じるかも。client-cliが欲しいなと思ったり。
見てみたらこの辺っぽい。
うーん、この辺の環境を必要とするCLIはちょっと嫌だなぁ、goのものがあればいいんだけども。
あとWeb UIはProのみの様子。で、OSSのUIがいくつかあるようだけど、どれも古いね。。。
これがまだ比較的新しめだけども。
Coolify
軽く試してみた感じだと、インストールは何もつまらずにめちゃめちゃ簡単、アプリケーションの作成もgithubレポジトリ連携させてデプロイとかすれば普通に立ち上がるし、Cloudflare Tunnelで独自ドメイン紐づけておけば、アプリごとにFQDN作ってくれてそれで公開もなんとなくできた。
ただなぁ、一応それっぽく動くところまではできたんだけど、果たしてこの設定であってるんだろうか?っていう微妙な思いが常にある感じなのよな。特に"Server"っていう概念がまだよくわからん。まあCoolifyのドキュメントをきちんと読み込んでもいないので当然なのかもだけど、こう触っていても腹落ちしない感が常にあって不安というのが個人的印象。ドキュメントもざっと見た感じ微妙に手が届かない感がある。
あとCLIが一切なさそうでGUIだけっぽい。ここはDokkuとは逆。普段遣いはCLIでやりたいけどたまにはGUIで全体的にみたいねん、と思うと、帯に短し襷に長し。。。
ただ気が向いたらもう少しいじって見ようかなとは思っている。ベストな設計さえ見いだせれば、簡単に使えそう、という感はある。
とりあえずHerokuと同じようなことはできそうだけど、いかにもHeroku的な雰囲気はあんまり感じない。どっちかというとDokkuのほうがHeroku感は強い。
CapRover
まだ試せてないのだけどドキュメントを見る限り、VPS等での使用が前提になっているように思える(ローカルでもできないわけではないけども、全般的にそういう雰囲気を感じる)ので、ちょっと茨の道かなぁという感を受けた、しらんけど。
ただデモとかドキュメントを見る限り、かなりHerokuライクに使えそうな雰囲気は感じた。GUIもCLIもいけるし。
この流れで知ったのだけど、こういうプライベートなIPでも名前解決してくれるサービスがあるのだね
ただHTTPSを実現しようと思うともうひと手間必要になるし、だったら全部Cloudflare Tunnelでやればいいと思った。
結局のところ、herokuライクに使おうと思うと、
- インターネット上のVPSなりなんなりに、パブリックなドメインを使って、構築する
- ローカルだとトンネルはなんとかなりそうだけども、DNSとSSLをこれらのPaaSツールとうまく連携させるってのは結構大変かも。
って感じにはなりそう。元々Herokuはインターネット上のPaaSなんやし、当然といえば当然。結局どこまで求めるか、って感じにはなりそう。もし自分でVPS借りてやるなら、CapRover選びそうな気がした。
あとはmultipassは固定プライベートIPが結構なハードルのように思えるので、再起動したりするとIP変わっちゃうってのもなかなか手間かもね。