Dagger入門(Python SDK)
概要
Docker創始者らが開発したソフトウェアのビルド・テスト・デプロイの自動化(CI/CD)ツールDaggerを使用してみました。
本記事では公式リファレンスに則りDaggerを導入する方法とDaggerを使う上で認識しておくべきと感じた前提知識をまとめました。
(Daggerはまだ新しい技術であり、アップデートも繰り返されているため、今後執筆時点(2023.1.3)と状況が大きく変わって来る可能性があるのでその点ご了承下さい。)
Daggerの前提知識・使用イメージ
(1)既存のシステムを置き換えるか
Daggerは既存のCI/CDツール(GitHubActionやJenkins)を置き換えるというよりも、それらのシステムの上で動かすことになります。
具体的にはそれぞれのパイプラインからDaggerを呼び出して使うことになります。公式ドキュメント
実際にテストを実行する部分のプログラムをDaggerに置き換えることで、CI/CDツールが変わったとしても、同じDaggerシステムを呼び出すという運用にすることでプラットフォームに依存しないパイプラインを構築できるということになります。
(2)DaggerはDockerを使用する前提で設計されている
Daggerは、Dockerコンテナにアクセス(又はコンテナを構築)し、そのコンテナ上でテストプログラムを動かすという思想が基礎になって設計されています。この点はDaggerを使い始める前に十分理解しておく必要があります。
(3)docker-composeのサポート
Daggerは現時点(2023年1月3日時点)でdocker-composeをサポートしていません。
したがって、docker-composeを使用したい場合は、docker-composeによるビルドを既存のCI/CDツールで行い、それにより構築されたコンテナにDaggerでアクセスする等、 ひと工夫が必要になります。
ただし、docker-composeと連携する必要性については開発者も理解しており、今後正式に使えるようになる可能性が高いです。
Daggerを使ってみる
Dagger(Python SDK)導入
まずpythonおよびDockerを使用できる環境を準備して下さい。(この点についてはこの記事では触れません。)
公式ドキュメントでは仮想環境を使用することが推奨されているので、venvにて仮想環境を作成します。
py -m venv test_env
.\test_env\Scripts\activate
上記のコマンドで仮想環境に入った後、以下のコマンドでDaggerをインストールします。
pip install dagger-io
導入自体はこれで完了です。
サンプルプログラムを実行する
(1)コンテナを構築するだけのプログラム
DockerHubからpython実行用のイメージをプルしてきて、そのpythonバージョンを取得し出力するだけのプログラムです。
import sys
import anyio
import dagger
async def test():
async with dagger.Connection(dagger.Config(log_output=sys.stderr)) as client:
python = (
client.container()
# コンテナイメージの指定(ここではpython:3.10-slim-buster)
.from_("python:3.10-slim-buster")
# pythonのバージョンを取得
.with_exec(["python", "-V"])
)
# 実行する
version = await python.stdout()
#取得したpythonバージョンを出力
print(f"Hello from Dagger and {version}")
if __name__ == "__main__":
anyio.run(test)
上記のプログラムを任意のフォルダにtest.pyとして保存し実行してください。
python test.py
このように表示されれば成功です。同時にdocker上にコンテナも立ち上がっていると思います。
Hello from Dagger and Python 3.10.8
(2)実際にテストを実行してみる
まずテストを行うプログラムを準備します。ここでは、公式リファレンス通りfastapiのプログラムをぎてゅbより入手します。
(自前でテスト用のプログラムがある場合はこの作業は不要です。)
git clone https://github.com/tiangolo/fastapi
そして以下のプログラムをクローンしてきたフォルダ内にtest.pyとして作成します。
import sys
import anyio
import dagger
async def test():
async with dagger.Connection(dagger.Config(log_output=sys.stderr)) as client:
# get reference to the local project
src = client.host().directory(".")
python = (
client.container().from_("python:3.10-slim-buster")
# ホストのディレクトリをイメージにマウントする
.with_mounted_directory("/src", src)
# カレントディレクトリを/srcに指定
.with_workdir("/src")
# 依存パッケージのインストールを実行
.with_exec(["pip", "install", "-e", ".[test]"])
# テストを実行
.with_exec(["pytest", "tests"])
)
# execute
await python.exit_code()
print("Tests succeeded!")
if __name__ == "__main__":
anyio.run(test)
プログラムを実行します。
python test.py
するとテストが実行され以下のように表示されれば成功です。
Tests succeeded!
以上
Discussion