はじめに
こちらは YouTube の CircleCI チャンネル、CircleCI Japanese (日本語)再生リストに収録の【チュートリアル】03 CircleCI で PostgreSQL のビルド済み Docker イメージを使おう!をブログにしたものです。
また、使用しているリポジトリはこちらです。
やりたいこと
CircleCI を使って、ビルド、テスト、リリース、デプロイを行う中で、とりわけテストの際に、データベースを使用したテストを行いたい場合があります。データを永続的に取り扱う場合に、CRUD と呼ばれる 4 つの基本機能については、データの登録順序などに依存せず、正しく動作しているかどうか、開発の初期段階、及び(テーブル構成の変化を伴うような)機能の追加・削除時に確実にテストしておきたいものです。
- Create: データの作成
- Read: データの読み出し
- Update: データの更新
- Delete: データの削除
今回は、CircleCI のコンフィグの中で、PostgreSQL を使用する方法、とりわけ、テスト用途に特化した(つまり、コンテナサイズの小さい、軽量な)CircleCI 作成のビルド済みコンテナを使った方法をご紹介します。
コンフィグ中でビルド済みコンテナを使用する
先ほど紹介させていただいたリポジトリの中のコンフィグ config.yml を見ていきましょう。
ジョブ定義: ビルド済み Docker イメージの指定方法
それでは、build ジョブの定義を先頭から見ていきましょう。まずは、Docker イメージの指定に関わる部分です。
このジョブの中では2つの Docker イメージを指定してしています。
- cimg/python - データベースにアクセスするプログラムを実行
- cimg/postgres - データベース(PostgreSQL)を実行
名前空間 cimg/
はこれらのイメージが CircleCI によって用意されたビルド済みコンテナのイメージ(CircleCI では「コンビニエンス イメージ」と呼んでいます)のうち、次世代の CircleCI イメージであることを示しています。コンビニエンス イメージの一覧は、circleci デベロッパーサイトのこちらのページから見ることが可能です。
さて、順番が前後してしまいますが、先に cimg/postgres の利用に関わるコンフィグの記述を見ていきましょう。
jobs:
build:
docker:
- image: cimg/postgres:13.3
auth:
username: $DOCKER_HUB_USERNAME
password: $DOCKER_HUB_ACCESS_TOKEN
environment:
POSTGRES_USER: circleci
POSTGRES_DB: postgres_test
POSTGRES_HOST_AUTH_METHOD: trust
TZ: "/usr/share/zoneinfo/Asia/Tokyo"
イメージを指定した後の auth: 以下、username, password で Docker Hub にログインするためのユーザ名とパスワード(アクセストークン)を指定しています。これは、Rate Limit によるイメージダウンロード制限回避のためです。また、実際のユーザ名、アクセストークンは(今回の例では)コンテクスト中に格納してあります(プロジェクトの環境変数にも格納可能ですが、プロジェクトを跨って共有するため)。
その後に、cimg/postgres イメージが使用する環境変数 POSTGRES_USER
, POSTGRES_DB
, POSTGRES_HOST_AUTH_METHOD
, 及び TZ
がコンフィグ中に指定されています。本ブログ公開時点では cimg/postgres イメージは、ベータ版公開となっていますが、下記 URL に Docker Hub へのリンク、GitHub リポジトリへのリンクも用意されているので、合わせてご覧ください。
- circleci Discuss の記事: Next-Gen PostgreSQL Convenience Image Beta
CircleCI のビルド済み Docker イメージに関しては、下記のオンラインマニュアルも合わせてご覧ください。
次に、cimg/python の利用に関わるコンフィグを見ていきましょう。
jobs:
build:
docker:
- image: cimg/python:3.9.5
auth:
username: $DOCKER_HUB_USERNAME
password: $DOCKER_HUB_ACCESS_TOKEN
environment:
TEST_DATABASE_URL: postgres://circleci@localhost:5432/postgres_test
TZ: "/usr/share/zoneinfo/Asia/Tokyo"
PAGER: cat
ここでは3つの環境変数が定義されています。TEST_DATABASE_URL
は、cimg/postgres によって起動されるデータベースに接続する際に使用する URL です。TZ
は先ほどと同様にタイムゾーンの指定です。
なお、PAGER
については注意が必要かも知れません。後ほど、テストの際に psql
コマンドを使って、データベースに SQL 文を発行した際の実行結果を表示しているのですが、デフォルトのページャーでは表示が一部、うまくいかなかったためにここでは cat
をページャーとして使用する定義をしています。
ジョブ定義: ステップ内での処理
それでは、build ジョブで実際に steps 内で実行しているステップを追って見ていきましょう。
- run: |
sudo rm -rf /var/lib/apt/lists/*
sudo apt update
sudo apt install postgresql-client-12
上のステップでは、PostgreSQL に接続するためのクライアントツールをapt install
でインストールしています。
- run: |
dockerize -wait tcp://localhost:5432 -timeout 1m
上のステップは注意が必要かも知れません。cimg/python イメージの起動が完了した時点で、cimg/postgres イメージの起動が完了している(=PostgreSQL サーバに接続可能な状態になっている)ことは必ずしも保証されていないので、localhost:5432 が接続可能になるまで、最大 1m(1 分)、ここで待ち処理を行う定義をしています(PostgreSQL サーバの起動が完了しておらず、接続できない時に、テストをエラーとして終了させたい訳ではないため)。
- run: |
psql \
-d $TEST_DATABASE_URL \
-c "CREATE TABLE test (name text)"
PostgreSQL サーバに接続可能になったら、クライアントツール(psql
)を使用して、CREATE TABLE
文で test テーブルを作成します。
- run: |
psql \
-d $TEST_DATABASE_URL \
-c "INSERT INTO test (name) VALUES ('舟木'), ('森本'), ('ローズ'), ('ズーバー')"
次に、作成した test テーブルに対して、レコードの挿入を行います。ここでは、4 行分のレコードを挿入しています。
- run: |
psql \
-d $TEST_DATABASE_URL \
-c "SELECT * from test"
最後に、挿入したレコードをSELECT
文で取得し、表示することで動作を確認しています。次のように結果が表示されるのを CircleCI のダッシュボードから確認します。
さいごに
今回のサンプルでは、アプリケーション自身がデータベースに接続し、処理を依頼するのではなく、コンフィグの中からデータベースに接続し、処理の依頼を行いましたが、ご自身で書いたコードからデータベースに接続するようなテストを実行する場合であっても、コード中で同様の処理を行うことになります。
データベースに接続するようなコードのテストを自動化する上で、デモ動画での説明と合わせ、ぜひご参考にしていただければと思います。
合わせて、他のチュートリアル動画も鋭意増強中です。合わせてご参照をいただければと思います。