Skip to main content

PostgreSQLサービスコンテナの作成

ワークフローで利用するPostgreSQLサービスコンテナを作成できます。 このガイドでは、コンテナで実行されるジョブか、ランナーマシン上で直接実行されるジョブのためのPostgreSQLサービスの作成例を紹介します。

はじめに

このガイドでは、Docker Hub の postgres イメージを使ってサービス コンテナーを構成するワークフローの例を示します。 ワークフローの実行スクリプトは、PostgreSQL サービスに接続し、テーブルを作成してから、データを入力します。 ワークフローが PostgreSQL テーブルを作成してデータを入力することをテストするために、スクリプトはテーブルからコンソールにデータを出力します。

注: ワークフローが Docker コンテナー アクション、ジョブ コンテナーあるいはサービス コンテナーを使うなら、Linux のランナーを使う必要があります。

  • GitHubホストランナーを使うなら、Ubuntuランナーを使わなければなりません。
  • セルフホストランナーを使っているなら、ランナーとしてLinuxマシンを使い、Dockerをインストールしておかなければなりません。

前提条件

GitHub Actionsとのサービスコンテナの動作と、ジョブを直接ランナー上で動作させる場合とコンテナ内で動作させる場合のネットワーキングの差異について、親しんでおいてください。 詳細については、「サービス コンテナーについて」を参照してください。

YAML、GitHub Actionsの構文、PosgreSQLの基本な理解があれば役立つかも知れません。 詳細については、次を参照してください。

コンテナ内でのジョブの実行

ジョブをコンテナ内で実行するように設定すれば、ジョブとサービスコンテナ間のネットワーク設定が単純になります。 同じユーザ定義ブリッジネットワーク上にあるDockerコンテナは、すべてのポートを互いに公開するので、サービスコンテナのポートをDockerホストにマップする必要がありません。 ワークフロー中で設定したラベルを使って、ジョブコンテナからサービスコンテナにアクセスできます。

このワークフロー ファイルをリポジトリの .github/workflows ディレクトリにコピーして、必要に応じて修正できます。

YAML
name: PostgreSQL service example
on: push

jobs:
  # Label of the container job
  container-job:
    # Containers must run in Linux based operating systems
    runs-on: ubuntu-latest
    # Docker Hub image that `container-job` executes in
    container: node:10.18-jessie

    # Service containers to run with `container-job`
    services:
      # Label used to access the service container
      postgres:
        # Docker Hub image
        image: postgres
        # Provide the password for postgres
        env:
          POSTGRES_PASSWORD: postgres
        # Set health checks to wait until postgres has started
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      # Downloads a copy of the code in your repository before running CI tests
      - name: Check out repository code
        uses: actions/checkout@v2

      # Performs a clean installation of all dependencies in the `package.json` file
      # For more information, see https://docs.npmjs.com/cli/ci.html
      - name: Install dependencies
        run: npm ci

      - name: Connect to PostgreSQL
        # Runs a script that creates a PostgreSQL table, populates
        # the table with data, and then retrieves the data.
        run: node client.js
        # Environment variables used by the `client.js` script to create a new PostgreSQL table.
        env:
          # The hostname used to communicate with the PostgreSQL service container
          POSTGRES_HOST: postgres
          # The default PostgreSQL port
          POSTGRES_PORT: 5432

ランナージョブの設定

このワークフローは、node:10.18-jessie コンテナーで実行され、ubuntu-latest GitHub ホステッド ランナーをコンテナーの Docker ホストとして使用するジョブを構成します。 node:10.18-jessie コンテナーの詳細については、Docker Hub のノード イメージを参照してください。

ワークフローは、postgres ラベルを使用してサービス コンテナーを構成します。 すべてのサービスはコンテナー内で実行しなければならないので、各サービスについてコンテナー image を指定する必要があります。 この例では postgres コンテナ イメージを使っており、デフォルトの PostgreSQL のパスワードが提供され、サービスが動作していることを確認するための正常性チェック オプションが含まれます。 詳しくは、Docker Hub の postgres イメージをご覧ください。

YAML
jobs:
  # Label of the container job
  container-job:
    # Containers must run in Linux based operating systems
    runs-on: ubuntu-latest
    # Docker Hub image that `container-job` executes in
    container: node:10.18-jessie

    # Service containers to run with `container-job`
    services:
      # Label used to access the service container
      postgres:
        # Docker Hub image
        image: postgres
        # Provide the password for postgres
        env:
          POSTGRES_PASSWORD: postgres
        # Set health checks to wait until postgres has started
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

ステップの設定

ワークフローは以下のステップを実行します。

  1. ランナー上にリポジトリをチェックアウト
  2. 依存関係のインストール
  3. クライアントを作成するスクリプトの実行
YAML
steps:
  # Downloads a copy of the code in your repository before running CI tests
  - name: Check out repository code
    uses: actions/checkout@v2

  # Performs a clean installation of all dependencies in the `package.json` file
  # For more information, see https://docs.npmjs.com/cli/ci.html
  - name: Install dependencies
    run: npm ci

  - name: Connect to PostgreSQL
    # Runs a script that creates a PostgreSQL table, populates
    # the table with data, and then retrieves the data.
    run: node client.js
    # Environment variable used by the `client.js` script to create
    # a new PostgreSQL client.
    env:
      # The hostname used to communicate with the PostgreSQL service container
      POSTGRES_HOST: postgres
      # The default PostgreSQL port
      POSTGRES_PORT: 5432

client.js スクリプトは、クライアントを作成するための環境変数 POSTGRES_HOSTPOSTGRES_PORT を探します。 ワークフローは、これら 2 つの環境変数を "PostgreSQL に接続する" ステップの一部として設定し、client.js スクリプトから利用できるようにします。 スクリプトの詳細については、「PostgreSQL サービス コンテナーのテスト」を参照してください。

PostgreSQL サービスのホスト名は、ワークフロー内で構成されたラベルです (ここでは postgres)。 同じユーザー定義ブリッジネットワーク上のDockerコンテナは、デフォルトですべてのポートをオープンするので、サービスコンテナにはデフォルトのPostgreSQLのポートである5432でアクセスできます。

ランナーマシン上で直接のジョブの実行

ランナーマシン上で直接ジョブを実行する場合、サービスコンテナ上のポートをDockerホスト上のポートにマップしなければなりません。 Docker ホストからサービス コンテナーへは、localhost と Docker ホストのポート番号を使ってアクセスできます。

このワークフロー ファイルをリポジトリの .github/workflows ディレクトリにコピーして、必要に応じて修正できます。

YAML
name: PostgreSQL Service Example
on: push

jobs:
  # Label of the runner job
  runner-job:
    # You must use a Linux environment when using service containers or container jobs
    runs-on: ubuntu-latest

    # Service containers to run with `runner-job`
    services:
      # Label used to access the service container
      postgres:
        # Docker Hub image
        image: postgres
        # Provide the password for postgres
        env:
          POSTGRES_PASSWORD: postgres
        # Set health checks to wait until postgres has started
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          # Maps tcp port 5432 on service container to the host
          - 5432:5432

    steps:
      # Downloads a copy of the code in your repository before running CI tests
      - name: Check out repository code
        uses: actions/checkout@v2

      # Performs a clean installation of all dependencies in the `package.json` file
      # For more information, see https://docs.npmjs.com/cli/ci.html
      - name: Install dependencies
        run: npm ci

      - name: Connect to PostgreSQL
        # Runs a script that creates a PostgreSQL table, populates
        # the table with data, and then retrieves the data
        run: node client.js
        # Environment variables used by the `client.js` script to create
        # a new PostgreSQL table.
        env:
          # The hostname used to communicate with the PostgreSQL service container
          POSTGRES_HOST: localhost
          # The default PostgreSQL port
          POSTGRES_PORT: 5432

ランナージョブの設定

この例では、Docker ホストとして ubuntu-latest GitHub ホストテッド ランナーを使用します。

ワークフローは、postgres ラベルを使用してサービス コンテナーを構成します。 すべてのサービスはコンテナー内で実行しなければならないので、各サービスについてコンテナー image を指定する必要があります。 この例では postgres コンテナ イメージを使っており、デフォルトの PostgreSQL のパスワードが提供され、サービスが動作していることを確認するための正常性チェック オプションが含まれます。 詳しくは、Docker Hub の postgres イメージをご覧ください。

このワークフローはPostgreSQLサービスコンテナ上のポート5432をDockerホストにマップします。 ports キーワードについて詳しくは、「サービス コンテナーについて」をご覧ください。

YAML
jobs:
  # Label of the runner job
  runner-job:
    # You must use a Linux environment when using service containers or container jobs
    runs-on: ubuntu-latest

    # Service containers to run with `runner-job`
    services:
      # Label used to access the service container
      postgres:
        # Docker Hub image
        image: postgres
        # Provide the password for postgres
        env:
          POSTGRES_PASSWORD: postgres
        # Set health checks to wait until postgres has started
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
        ports:
          # Maps tcp port 5432 on service container to the host
          - 5432:5432

ステップの設定

ワークフローは以下のステップを実行します。

  1. ランナー上にリポジトリをチェックアウト
  2. 依存関係のインストール
  3. クライアントを作成するスクリプトの実行
YAML
steps:
  # Downloads a copy of the code in your repository before running CI tests
  - name: Check out repository code
    uses: actions/checkout@v2

  # Performs a clean installation of all dependencies in the `package.json` file
  # For more information, see https://docs.npmjs.com/cli/ci.html
  - name: Install dependencies
    run: npm ci

  - name: Connect to PostgreSQL
    # Runs a script that creates a PostgreSQL table, populates
    # the table with data, and then retrieves the data
    run: node client.js
    # Environment variables used by the `client.js` script to create
    # a new PostgreSQL table.
    env:
      # The hostname used to communicate with the PostgreSQL service container
      POSTGRES_HOST: localhost
      # The default PostgreSQL port
      POSTGRES_PORT: 5432

client.js スクリプトは、クライアントを作成するための環境変数 POSTGRES_HOSTPOSTGRES_PORT を探します。 ワークフローは、これら 2 つの環境変数を "PostgreSQL に接続する" ステップの一部として設定し、client.js スクリプトから利用できるようにします。 スクリプトの詳細については、「PostgreSQL サービス コンテナーのテスト」を参照してください。

ホスト名は、localhost または 127.0.0.1 です。

PostgreSQLサービスコンテナのテスト

次のスクリプトを使用してワークフローをテストできます。このスクリプトは、PostgreSQL サービスに接続し、プレースホルダーデータを含む新しいテーブルを追加します。 そしてそのスクリプトは PostgreSQL テーブルに保存されている値をターミナルに出力します。 スクリプトでは任意の言語を使えますが、この例では Node.js と pg npm モジュールを使っています。 詳しくは、npm redis モジュールに関するページをご覧ください。

client.js を変更して、ワークフローで必要な任意の PostgreSQL 操作を含めることができます。 この例のスクリプトは、PostgreSQL サービスに接続し、postgres データベースにテーブルを追加し、プレースホルダー データをいくつか挿入してから、データを取得します。

以下のコードを使用して、リポジトリに client.js という名前の新しいファイルを追加してください。

JavaScript
const { Client } = require('pg');

const pgclient = new Client({
    host: process.env.POSTGRES_HOST,
    port: process.env.POSTGRES_PORT,
    user: 'postgres',
    password: 'postgres',
    database: 'postgres'
});

pgclient.connect();

const table = 'CREATE TABLE student(id SERIAL PRIMARY KEY, firstName VARCHAR(40) NOT NULL, lastName VARCHAR(40) NOT NULL, age INT, address VARCHAR(80), email VARCHAR(40))'
const text = 'INSERT INTO student(firstname, lastname, age, address, email) VALUES($1, $2, $3, $4, $5) RETURNING *'
const values = ['Mona the', 'Octocat', 9, '88 Colin P Kelly Jr St, San Francisco, CA 94107, United States', 'octocat@github.com']

pgclient.query(table, (err, res) => {
    if (err) throw err
});

pgclient.query(text, values, (err, res) => {
    if (err) throw err
});

pgclient.query('SELECT * FROM student', (err, res) => {
    if (err) throw err
    console.log(err, res.rows) // Print the data in student table
    pgclient.end()
});

このスクリプトは、PostgreSQL サービスへの新しい接続を作成し、POSTGRES_HOSTPOSTGRES_PORT 環境変数を使って PostgreSQL サービスの IP アドレスとポートを指定します。 hostport が定義されていない場合、既定のホストは localhost で、既定のポートは 5432 です。

スクリプトはテーブルを作成し、そのテーブルにプレースホルダーデータを展開します。 postgres データベースにデータが含まれていることをテストするため、スクリプトでテーブルの内容をコンソール ログに出力します。

このワークフローを実行すると、「PostgreSQL への接続」ステップに次の出力が表示されます。これにより、PostgreSQL テーブルが正常に作成されてデータが追加されたことを確認できます。

null [ { id: 1,
    firstname: 'Mona the',
    lastname: 'Octocat',
    age: 9,
    address:
     '88 Colin P Kelly Jr St, San Francisco, CA 94107, United States',
    email: 'octocat@github.com' } ]