背景
あるプロジェクトでは、バックエンドAPI(Go) と フロント(スマホアプリ、ブラウザアプリ) という構成で運用されていました。しかし、運用中にデータベース(DB)のレコード追加や編集が必要になる場面が増え、管理画面の必要性 が高まっていました。
管理画面の開発には以下の要件がありました:
- 学習コストの低い言語 で実装したい
- Goでの実装は不要
- PHPプログラマーのリソースを活用 する
その結果、管理画面を別リポジトリでPHPを用いて作成することになりました。また、以下のような運用面での工夫が求められました。
- 管理画面とAPIは別コンテナとして運用
- DBは共通のため、管理をAPI側に集約
ローカル環境では、各サービスのDockerコンテナ群を起動し、ネットワークを共有する構成 でDBアクセスを実現しました。
しかし、GitHub Actions上でのテスト では、DBコンテナが不足しており、DBに依存するテストを実行できないという課題が発生しました。
そこで、GitHub Actions上でのみDBのコンテナを別構築するということにしました。
この記事では、GitHub Actions上でDocker ComposeのサービスとGitHub Actionsのservices
機能を使い、DBコンテナを接続する方法 を解説します。
解決方法:GitHub Actionsでのネットワーク共有
GitHub Actionsでは、services
を利用することで、DBコンテナを簡単に追加できます。ただし、Docker Composeで定義したサービス群との接続にはネットワーク設定の工夫が必要です。
Docker Composeのネットワーク構成
まず、Docker Composeでのネットワークを確認します。以下の例では、APIと管理画面、そして共通のDBを立ち上げています。
services:
api:
build:
context: ./api
networks:
- api-external-network
db:
build:
context: ./db
networks:
- api-external-network
networks:
api-external-network:
driver: bridge
external: true
services:
admin:
build:
context: ./admin
networks:
- shared_network
networks:
shared_network:
driver: bridge
external: true
name: "${NETWORK_NAME}"
ここでは、shared_network というネットワークを作成し、api と admin サービスがこのネットワークを共有しています。
ローカル用の.env
ローカル用の.envに、バックエンド用のネットワーク名を付け加えることによって、API側のDBと接続できるようにします。
NETWORK_NAME=api-external-network
上記の設定を行うことでローカルは解決しました。
GitHub Actionsの設定
GitHub Actionsでは、servicesでDBコンテナを指定し、Docker Composeで立ち上げたサービス群とネットワークを共有する必要があります。以下はその設定例です。
jobs:
ci:
runs-on: ubuntu-latest
services:
# CI用のDBを立ち上げる
db:
image: mysql:8.0.23
ports:
- 3306:3306
env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes
BIND-ADDRESS: 0.0.0.0
MYSQL_USER: app
MYSQL_PASSWORD: password
MYSQL_DATABASE: app
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
steps:
# リポジトリを指定したディレクトリにチェックアウト
- uses: actions/checkout@v4
# テスト用の.envファイルを利用
- name: Copy Env FIle
run: cp src/.env.testing src/.env
# GitHub Actionsのネットワークを取得
- name: Get GitHub network name
id: get_network
run: |
network=$(docker network ls --filter name=github -q --format "{{.Name}}")
echo "NETWORK_NAME=$network" >> $GITHUB_ENV
# Dockerのイメージをビルドして立ち上げる
- name: Docker Compose Build and Up
run: docker compose up -d
# (割愛)別リポジトリからDB情報を取得してGA上のDBへスキーマ情報を流す
# PHPUnitを実行
- name: Laravel PHPUnit Testing
run: docker compose exec -T php ./vendor/bin/phpunit
解説
network=$(docker network ls --filter name=github -q --format "{{.Name}}")
docker network ls
でネットワーク一覧を取得でき、プレフィックスにはgithubと付くため、それで検索ができます。そして、取得したネットワーク名を環境変数に設定して、docker compose時にそれを設定するという流れになります。
まとめ
こういった需要があるか微妙なところですが(笑)
ただやろうと思って調べても中々情報がなかったので、記事にしてみました。
是非ご活用ください!