内部ツール向けデプロイツール「Clace」を試す
Clace
概要
ClaceはApache-2.0ライセンスのプロジェクトで、社内ツール用のウェブアプリ開発とデプロイメント・プラットフォームを構築している。Claceは、あらゆる言語/フレームワークの複数のウェブアプリを、1台のマシンで簡単かつ安全にホスティングできる。Claceはクロスプラットフォーム(Linux/Windows/OSX)で、ウェブアプリを管理するためのGitOpsワークフローを提供する。
Claceは、リバースプロキシ、ハイパーメディアベースのマイクロフレームワーク、コンテナオーケストレータ(DockerまたはPodmanを使用)の機能を単一の軽量バイナリに統合している。Claceサーバーを起動し、DockerまたはPodmanが動作していることを確認した後、新しいアプリをGitHubのソース・レポから1つのコマンドでインストールできる。Claceはイメージをビルドし、最初のAPIコールでコンテナを起動する。
Claceは、開発マシン上で任意のコンテナ化されたウェブアプリを開発し、共有サーバー上にアプリをデプロイするために使用できる。アプリはgitリポジトリから直接デプロイされ、ビルドステップは必要ない。ClaceはStreamlitアプリのデプロイに使用でき、チーム全体のアクセス制御のためにOAuth認証を追加できる。
このリポジトリはClaceサーバとクライアントのソースコードをホストしている。ドキュメントサイトclace.ioのソースはdocs repoにある。アプリをビルドするためのテンプレートであるアプリ仕様は、appspecsレポで定義されている。
特徴
Claceは以下の用途に使用できる:
- コンテナ化されたアプリケーションをデプロイし、Claceがコンテナのライフサイクルを構築・管理する。
- Starlarkを使ってハイパーメディアベースのアプリケーションを構築する(コンテナは不要)
- バックエンドAPIをコンテナで実装し、ハイパーメディアベースのUIをClaceで実装するハイブリッドアプローチ
Claceはすべてのアプリケーションで以下をサポートする:
- 複数のアプリのアトミックアップデート。
- アプリのアップデートのステージング・モード。コードやコンフィグの変更が本番環境で動作するかどうかを、本番環境で動作させる前に検証する。
- コード変更を試すためのプレビューアプリ作成サポート。
- githubとの統合をサポートし、アプリをgithubのコードから直接デプロイできる。
- OAuthとSSOベースの認証
- アプリレベルでドメインベースとパスベースのルーティングをサポート。
コンテナ化されたアプリに対して、Claceは以下をサポートする:
- devおよびprodモードでのイメージビルドの管理
- コンテナのパラメータを渡す
- サポートされているフレームワーク(Flask、Streamlit、Containerfileを持つレポ)については、レポのコードを変更することなく、仕様書からアプリをビルドできる。
ハイパーメディアベースのアプリをビルドするために、Claceは以下をサポートしている:
- 自動エラー処理のサポート
- esbuildを使用したECMAScriptモジュールの自動作成。
- TailwindCSSとDaisyUIウォッチャー統合のサポート。
- certmagicに基づくSSL証明書の自動作成。
- バックエンドのアプリコードは、allowlistベースのパーミッションを持つセキュリティサンドボックスで実行される。
- ビルドステップがなく、開発成果物は本番環境ですぐに使用できる。
- SQLiteを使用したアプリケーション・データの永続化のサポート
- SQLiteデータベースによってバックアップされたコンテンツ・ハッシュ・ベースのファイル名を持つ仮想ファイルシステムにより、積極的な静的コンテンツ・キャッシュが可能になる。
- 静的アーティファクトのBrotli圧縮、パフォーマンスのためのHTTPアーリーヒントのサポート。
Quick Startを進めていく。今回はローカルのLAN内にいるUbuntu 22.04サーバで。
インストールスクリプトが用意されているのでそれを実行。インストールスクリプト使うタイプは環境を隔離できなくて何やってるかがぱっとわからないので個人的には好みではないのだけど、中身を確認した感じ
- tar.gz落としてきて展開
- ファイル・ディレクトリ配置しつつ初期設定ファイルを生成
ぐらいっぽいので、素直に実行した。
$ curl -L https://clace.io/install.sh | sh
######################################################################## 100.0%
clace was installed successfully to /home/kun432/clhome/bin/clace
Generated password is: XXXXXXXXXXXXXXXX
Password config has been setup, save the above password for app access with admin account
Manually add the following to your $HOME/.bash_profile (or similar). Also run it now for this session:
source "/home/kun432/clhome/bin/clace.env"
See https://clace.io/docs/quickstart for quick start guide.
諸々は$HOME/clhome
以下にインストールされる模様。あとadminアカウント用のパスワードも自動生成されるが、どうやらアプリデプロイ後のアクセスに必要になる様子。一旦控えておく。
$ tree /home/kun432/clhome
/home/kun432/clhome
├── bin
│ ├── clace
│ └── clace.env
├── clace.toml
└── tmp
└── clace-v0.6.5-linux-amd64
├── LICENSE
└── README.md
3 directories, 5 files
画面の指示通り、環境設定用の1行を.bash_profileなり.bashrcなりに追加する。自分は.bashrcに追加。
source "/home/kun432/clhome/bin/clace.env"
.bashrcを再読み込み
$ exec $SHELL -l
PATHが通った。
$ which clace
/home/kun432/clhome/bin/clace
ではclaceのサーバを起動する。
$ clace server start &
[1] 1503168
Server listening on http://127.0.0.1:25222
Server listening on https://0.0.0.0:25223
ローカルからアクセスする場合は、25222番ポート、リモートからアクセスする場合は25223番ポートにアクセスすれば良さそう。
ということでリモートからアクセスしてみた(証明書の警告が表示されるのはスルー)
今のところアプリを何もデプロイしていないので何も表示されない様子。管理画面とかも特になくてCLIがメインになるのかな?
Usage一応見ておく。
$ clace --help
NAME:
clace - Clace client and server https://clace.io/
USAGE:
clace [global options] command [command options] [arguments...]
COMMANDS:
server Manage the Clace server
app Manage Clace apps
preview Manage Clace preview apps
account Manage Clace accounts
param Manage app parameter values
version Manage app versions
password Generate a password bcrypt config entry
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--config-file value, -c value TOML configuration file [$CL_CONFIG_FILE]
--version, -v Print version info (default: false)
--help, -h show help
以下のサブコマンドがある様子。
server
app
preview
account
param
version
password
clace app
がアプリ関連のコマンドに思える。こちらもUsageを見てみる。
$ clace app --help
NAME:
clace app - Manage Clace apps
USAGE:
clace app command [command options] [arguments...]
COMMANDS:
create Create a new app
list List apps
delete Delete an app
approve Approve app permissions
reload Reload the app source code
promote Promote the app from staging to production
update-settings Update Clace apps settings. Settings changes are NOT staged, they apply immediately to matched stage, prod and preview apps.
update-metadata Update Clace app metadata. Metadata updates are staged and have to be promoted to prod. Use "clace param" to update app parameter metadata.
help, h Shows a list of commands or help for one command
OPTIONS:
--help, -h show help
サブコマンドごとにサブコマンドがある模様。crace app create
でアプリがデプロイできるっぽい。
アプリのデプロイ
ではClaceを使ってアプリをデプロイする。Quick Startでは以下のレポジトリで公開されているいるデモアプリのうち、
- disk_uasge
- bookmarks
をデプロイする様子。
とりあえずdisk_usageアプリからやってみる。githubレポジトリから直接デプロイできるっぽい。
$ clace app create --approve github.com/claceio/apps/system/disk_usage /disk_usage
App audit results /disk_usage - app_prd_2i0elsayewvbxlcsoxpaqigui0b
App audit results /disk_usage_cl_stage - app_stg_2i0elsayewvbxlcsoxpaqigui0b
Plugins :
fs.in
Permissions:
fs.in.abs []
fs.in.list []
fs.in.find []
App created. Permissions have been approved
HTTP Url: http://localhost:25222/disk_usage
HTTPS Url: https://localhost:25223/disk_usage
アプリがデプロイされた様子。ブラウザでhttps://X.X.X.X:25223/disk_usage
にアクセス(ホスト名は適宜変更)してみると、BASIC認証のダイアログが開く。ユーザ名はadmin
、パスワードはclaceサーバ起動時に表示されたパスワードを入力する。
claceのインストールディレクトリ内のディスク使用状況を表示するサンプルっぽい。
もう一つのbookmarksアプリもデプロイしてみる。
$ clace app create --approve github.com/claceio/apps/utils/bookmarks /book
App audit results /book - app_prd_2i0gfm0za1peptgguhemklnziuy
App audit results /book_cl_stage - app_stg_2i0gfm0za1peptgguhemklnziuy
Plugins :
store.in
Permissions:
store.in.select []
store.in.insert []
store.in.update []
store.in.select_one []
store.in.begin []
store.in.commit []
store.in.delete_by_id []
App created. Permissions have been approved
HTTP Url: http://localhost:25222/book
HTTPS Url: https://localhost:25223/book
同様にブラウザでアクセスしてみるとこんな感じ。
なお、clace app create
時に--auth none
をつけると認証が無効化される様子。
アプリのコンテナ化
さきほどデプロイしたデモアプリは、ビルドツールBazekの設定言語であるStarlarkのgo実装、Starlark-goで書かれている。どうやらStarlarkで書かれている場合はコンテナ等が不要・Claceサーバで直接動作するらしい。
逆にそれ以外の言語で書かれたアプリの場合はコンテナが使用される。デフォルトではpodmanが使用され、見つからない場合はdockerになる。
アプリのコンテナ化には2つの方法がある
- 必要なファイルをレポジトリに入れておく。
-
app.star
- アプリの設定。多分Starlarkで書く。
-
Containerfile
/Dockerfile
- コンテナの設定。
-
- (AppSpec)(https://clace.io/docs/app/overview/#building-apps-from-spec)を指定する。
- アプリごとのデプロイ用テンプレートのようなもの?
- 作成したアプリのコードの変更は一切不要、コンテナ設定ファイルも不要
- サポートしているAppSpecは https://github.com/claceio/appspecs にある
- container
- image
- proxy
- python-flask
- python-streamlit-poetry
- python-streamlit
ここでは2のパターンを見てみる。streamlitが公開しているデモアプリのレポジトリを使ってデプロイしてみる。
$ clace app create \
--spec python-streamlit \
--branch master \
--approve \
github.com/streamlit/streamlit-example /streamlit
App audit results /streamlit - app_prd_2i0w9ijw5ywcjlzdras0ormgszx
App audit results /streamlit_cl_stage - app_stg_2i0w9ijw5ywcjlzdras0ormgszx
Plugins :
proxy.in
container.in
Permissions:
proxy.in.config [<CONTAINER_URL>]
container.in.config [auto]
App created. Permissions have been approved
HTTP Url: http://localhost:25222/streamlit
HTTPS Url: https://localhost:25223/streamlit
URLにアクセスしてみる。表示されるまでにちょっと時間がかかる。
裏では以下が行われている。
- 上記のgithubレポジトリがクローンされる
- クローンしたレポジトリ内に、Claceで起動させるために必要なファイルをAppSpec
python-streamlit
からコピーする - アプリのソースやメタデータをClaseサーバのメタデータデータベース(SQlite)に読み込む
- アプリAPIへの初回アクセス時に、Claceサーバは以下を実行する
- AppSpecに定義されている
Containerfile
を使ってコンテナイメージを作成 - イメージからコンテナを起動し、アプリAPIへのプロキシをセットアップ
- AppSpecに定義されている
docker ps
を見てみるとたしかに起動していた。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d4fe081913ac cli-app_prd_XXXXXXXX... "bash -x /streamlit_…" 9 minutes ago Up 9 minutes 127.0.0.1:32768->8501/tcp cli-app_prd_XXXXXXXX...
(snip)
アプリへパラメータを渡す場合にはapp paramsを使うか、または、アプリデプロイ時に直接指定(ex: app create --param port=9000
)したり、アプリ起動後に変更(ex: param update port 9000 /myapp
)したりできる様子。
ソースのレポジトリにContainerfile
もしくはDockerfile
があれば、どの言語やフレームワークでも使用可能な汎用のcontainer
specが使用される。コンテナファイルにEXPOSE
が設定されていればポートは指定しなくても良い。
ちなみに、AppSpecの中身がどうなっているかを見てみると、どうやらStarlarkの設定ファイル(app.star
、params.star
)はあらかじめ用意されていて、これは必須っぽい。
このあたりは隠蔽されていてあまり来にしなくていいのかもしれないけど、なんとなくStarlarkの記法とかに慣れておいたほうが良さそうに思える。以下はcontainer
specのapp.star
の中身。一応「Pythonの方言」という扱いらしいので、なんとなく読める感。
アプリの管理
Claceサーバーには複数のアプリケーションをインストールでき、各アプリケーションは固有のパスを持ち、個別に管理が可能。
アプリのパスはdomain_name:url_path
で構成され、アプリ作成時にdomain_name
が指定されない場合はデフォルトドメインで作成される。
特定のドメインに一致するものが見つからない場合、デフォルトドメインが検索される。
ルーティングの詳細はapp routingを参照
ローカル環境では、URLベースのルーティングを使用するか、
*.localhost
ドメインをドメインベースのパスに使用することができる。
本番環境では、ワイルドカードDNSがセットアップされていれば、アプリごとに新しいDNSエントリを作成することなく、ドメインベースのルーティングを使用できる。アプリは、1つのClaceサーバー上の複数の異なるドメインでホストすることができる。
アプリのインストール
アプリのインストールは
clace app create --appprove <source_url> <[domain:]app_path
で行う。例えばdisk_usageのデモだとこうなる。
$ clace app create --approve github.com/claceio/apps/system/disk_usage /disk_usage
-
github.com/claceio/apps
レポジトリのmainブランチからsystem/disk_usage
のソースを取得してインストール - デフォルトドメインの
/disk_usage
のパスで動作するように設定
アプリのコードがローカルにある場合はsource_urlでパスを指定すれば良い。
clace app create --approve ./diskapp /disk_usage_local
ローカルにコードがある場合は--dev
オプションを付けるとdevモードになり、コードを変更するとリロード等を行わなくても自動で反映される。
devモード以外=prodモードの場合はアプリのリロード(app reload
)が必要になる。リロードは以下。
clare app reload --approve --promote "/disk_usage"
githubレポジトリからインストールしたアプリでapp reload
を行うと、アプリ作成時に指定したブランチ(デフォルトはmain
)から最新の変更が取得されて反映される。
devモード以外の場合、コードはSQLiteメタデータデータベースに読み込まれてClaceサーバで管理される。