麺を食べればご機嫌

仕事、プログラミング、映画とやら

MySQLのDockerコンテナを立ち上げ、GitHub Actions上で自動テストを行う

はじめに

ここ1,2ヶ月個人開発に励んでいます。 その中でGitHub Actions上で、MySQLのコンテナになかなか接続できなかったため、ここに整理したいと思います。 GitHub Actionsでdocker-compose.ymlを使ってコンテナを立ち上げて、自動テストを考えている方の参考になれば幸いです。 (DockerコンテナはGitHub Actionsのserviceは使っておらず、docker-compose.ymlでコンテナの立ち上げを行なっています)

docker-compse.yml(CI用)

PythonのコンテナからMySQLのコンテナを接続してます。

version: "3"

services:
  python:
    build:
      context: .
      dockerfile: ./python/Dockerfile
    depends_on:
      mysql:
        condition: service_healthy
    links:
      - mysql
    environment:
      - DB_HOST
      - DB_PORT
      - DB_DATABASE
      - DB_USERNAME
      - DB_PASSWORD
    tty: true

  mysql:
    build:
      context: .
      dockerfile: ./mysql/Dockerfile
    ports:
      - 3306:3306
    environment:
      - MYSQL_DATABASE
      - MYSQL_ROOT_PASSWORD
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "mysql"]
      timeout: 20s
      retries: 10
ポイント① healthcheck
depends_on:
      mysql:
        condition: service_healthy

Pythonのコンテナはhealthcheckを行なった後に立ち上げを行います。 depends_onについてはこちらを参考にしました。

healthcheck:
  test: ["CMD", "mysqladmin" ,"ping", "-h", "mysql"]
  timeout: 20s
  retries: 10

MySQLコンテナで行うhealthcheckを定義します。 mysqladminはサーバの稼働状況を確認するコマンドになります。

ここを書いとかないと、エラー (2003) 「'server' の MySQL サーバーに接続できませんが出てしまいます。 このエラーはホスト名(IPAdress)が認識できないわけではなく、MySQLの立ち上げが間に合わず、接続が拒否がされているためのエラーです。

ポイント② --linkオプション

まずGitHub Actions上では、こちらのリファレンスを見ると、bridgeネットワークを使わなければなりません。 docker network inspect ネットワーク名を実行しましたが、認識されていなかったので、おそらく新規で独自のnetworkを作れないんだと思います。

なので、デフォルトのbridgeネットワークを使うのですが、bridgeネットワークはコンテナ名ではなくIPアドレスを指定して、コンテナの接続を行います。 何が問題かというとコンテナが立ち上がる度にIPアドレスはかわってしまうため、環境変数としてIPアドレスを指定できないことです。 (GitHub Actionsのserviceを使ってMySQLを立ち上げれば、固定のアドレスになるためそちらを使ってもいいかもしれません)

その問題を解決するために--linksオプションを使います。

links:
  - mysql
# - 接続したいコンテナ名:参照名
# コンテナ名と参照名が一緒であれば参照名は記載不要

これでホスト名にmysqlを指定すると接続されます。

.github/workflows/test.yml

name: Test

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: docker-compose up
        env:
          MYSQL_DATABASE: ****
          MYSQL_ROOT_PASSWORD: ****
          DB_HOST: mysql
          DB_PORT: 3306
          DB_DATABASE: ****
          DB_USERNAME: ****
          DB_PASSWORD: ****
        run: |
          docker-compose up -d --remove-orphans

      - name: Run Tests
        run: |
          docker exec -i kabucalculator_python_1 bash -c "cd test && python -m unittest"
docker-compose up のステップ

envでdocker-compse.ymlへ渡す環境変数を設定してます。 ホスト名はmysqlです。

env:
    MYSQL_DATABASE: ****
    MYSQL_ROOT_PASSWORD: ****
    DB_HOST: mysql
    DB_PORT: 3306
    DB_DATABASE: ****
    DB_USERNAME: ****
    DB_PASSWORD: ****
Run Test

Pythonのコンテナに入って、テストコマンドを実行しています。

さいごに

GitHub Actionsの自動テストでdocker-composeを使う記事はそんなに多くなかったので、 もし同じようなことを考えている方の参考になれば幸いです。