Closed5

Mac+multipassでセルフDocker Paasを試してみる

kun432kun432

手元でHerokuっぽく使えるものがあるといいなというところで。
できるかはわからないけどやってみる。

  • dokku
  • coolify
  • caprover

あたり。

M2 mac miniで。

kun432kun432

Dokku

https://dokku.com/

セットアップ

とりあえずcloud-initはあまり凝ってないもので。

cloud-config.yaml
#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インストール

https://dokku.com/docs/getting-started/installation/

$ 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に従って。

https://dokku.com/docs/deployment/application-deployment/

まず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でデプロイする方法もある模様なのでこちらをやってみる。

https://dokku.com/docs/deployment/builders/dockerfiles/

ということでこちらを使ってみる。

https://github.com/dockersamples/blog-react-app

再度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のコマンドに書き換えるツールがある模様。

https://dokkupose.netlify.app/

所感

dokkuコマンドは、Dokku VM内で叩くしかないのかなー、ただそれだけのことだけど、ちょっと手間に感じるかも。client-cliが欲しいなと思ったり。

見てみたらこの辺っぽい。

https://dokku.com/docs/community/clients/

うーん、この辺の環境を必要とするCLIはちょっと嫌だなぁ、goのものがあればいいんだけども。

あとWeb UIはProのみの様子。で、OSSのUIがいくつかあるようだけど、どれも古いね。。。

https://github.com/ledokku/ledokku

https://github.com/palfrey/wharf

これがまだ比較的新しめだけども。

https://github.com/texm/shokku

kun432kun432

Coolify

https://coolify.io/

軽く試してみた感じだと、インストールは何もつまらずにめちゃめちゃ簡単、アプリケーションの作成もgithubレポジトリ連携させてデプロイとかすれば普通に立ち上がるし、Cloudflare Tunnelで独自ドメイン紐づけておけば、アプリごとにFQDN作ってくれてそれで公開もなんとなくできた。

ただなぁ、一応それっぽく動くところまではできたんだけど、果たしてこの設定であってるんだろうか?っていう微妙な思いが常にある感じなのよな。特に"Server"っていう概念がまだよくわからん。まあCoolifyのドキュメントをきちんと読み込んでもいないので当然なのかもだけど、こう触っていても腹落ちしない感が常にあって不安というのが個人的印象。ドキュメントもざっと見た感じ微妙に手が届かない感がある。

あとCLIが一切なさそうでGUIだけっぽい。ここはDokkuとは逆。普段遣いはCLIでやりたいけどたまにはGUIで全体的にみたいねん、と思うと、帯に短し襷に長し。。。

ただ気が向いたらもう少しいじって見ようかなとは思っている。ベストな設計さえ見いだせれば、簡単に使えそう、という感はある。

とりあえずHerokuと同じようなことはできそうだけど、いかにもHeroku的な雰囲気はあんまり感じない。どっちかというとDokkuのほうがHeroku感は強い。

kun432kun432

CapRover

https://caprover.com/

まだ試せてないのだけどドキュメントを見る限り、VPS等での使用が前提になっているように思える(ローカルでもできないわけではないけども、全般的にそういう雰囲気を感じる)ので、ちょっと茨の道かなぁという感を受けた、しらんけど。

ただデモとかドキュメントを見る限り、かなりHerokuライクに使えそうな雰囲気は感じた。GUIもCLIもいけるし。

kun432kun432

この流れで知ったのだけど、こういうプライベートなIPでも名前解決してくれるサービスがあるのだね

https://sslip.io/

ただHTTPSを実現しようと思うともうひと手間必要になるし、だったら全部Cloudflare Tunnelでやればいいと思った。

結局のところ、herokuライクに使おうと思うと、

  • インターネット上のVPSなりなんなりに、パブリックなドメインを使って、構築する
  • ローカルだとトンネルはなんとかなりそうだけども、DNSとSSLをこれらのPaaSツールとうまく連携させるってのは結構大変かも。

って感じにはなりそう。元々Herokuはインターネット上のPaaSなんやし、当然といえば当然。結局どこまで求めるか、って感じにはなりそう。もし自分でVPS借りてやるなら、CapRover選びそうな気がした。

あとはmultipassは固定プライベートIPが結構なハードルのように思えるので、再起動したりするとIP変わっちゃうってのもなかなか手間かもね。

このスクラップは2024/01/23にクローズされました