跳至主要内容

创建 PostgreSQL 服务容器

您可以创建一个 PostgreSQL 服务容器以在您的工作流中使用。本指南展示了为在容器中或直接在 Runner 机器上运行的作业创建 PostgreSQL 服务的示例。

简介

本指南向您展示了使用 Docker Hub `postgres` 镜像配置服务容器的工作流示例。工作流运行一个脚本,该脚本连接到 PostgreSQL 服务,创建一个表,然后用数据填充它。为了测试工作流是否创建并填充了 PostgreSQL 表,脚本将表中的数据打印到控制台。

注意

如果您的工作流使用 Docker 容器 Actions、作业容器或服务容器,则必须使用 Linux Runner。

  • 如果您使用的是 GitHub 托管的 Runner,则必须使用 Ubuntu Runner。
  • 如果您使用的是自托管的 Runner,则必须使用 Linux 机器作为您的 Runner,并且必须安装 Docker。

先决条件

您应该熟悉服务容器如何在 GitHub Actions 中工作,以及直接在 Runner 上运行作业与在容器中运行作业之间的网络差异。有关详细信息,请参阅“关于服务容器”。

您可能还会发现了解 YAML(GitHub Actions 的语法)和 PostgreSQL 的基本知识很有帮助。有关详细信息,请参阅

在容器中运行作业

将作业配置为在容器中运行可以简化作业和服务容器之间的网络配置。同一用户定义的桥接网络上的 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:20-bookworm-slim

    # 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@v4

      # Performs a clean installation of all dependencies in the `package.json` file
      # For more information, see https://docs.npmjs.net.cn/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:20-bookworm-slim容器中运行的作业,并使用ubuntu-latest GitHub 托管运行器作为容器的 Docker 主机。有关node:20-bookworm-slim容器的更多信息,请参阅 Docker Hub 上的node 镜像

此工作流使用标签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:20-bookworm-slim

    # 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@v4

  # Performs a clean installation of all dependencies in the `package.json` file
  # For more information, see https://docs.npmjs.net.cn/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环境变量来创建客户端。此工作流将这两个环境变量设置为“连接到 PostgreSQL”步骤的一部分,以便让client.js脚本可以使用它们。有关脚本的更多信息,请参阅“测试 PostgreSQL 服务容器”。

PostgreSQL 服务的主机名是您在工作流中配置的标签,在本例中为postgres。由于同一用户定义的桥接网络上的 Docker 容器默认情况下会打开所有端口,因此您将能够在默认的 PostgreSQL 端口 5432 上访问服务容器。

直接在运行器机器上运行作业

当您直接在运行器机器上运行作业时,需要将服务容器上的端口映射到 Docker 主机上的端口。您可以使用localhost和 Docker 主机端口号从 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@v4

      # Performs a clean installation of all dependencies in the `package.json` file
      # For more information, see https://docs.npmjs.net.cn/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

为直接在运行器机器上运行的作业配置运行器作业

此示例使用ubuntu-latest GitHub 托管运行器作为 Docker 主机。

此工作流使用标签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@v4

  # Performs a clean installation of all dependencies in the `package.json` file
  # For more information, see https://docs.npmjs.net.cn/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环境变量来创建客户端。此工作流将这两个环境变量设置为“连接到 PostgreSQL”步骤的一部分,以便让client.js脚本可以使用它们。有关脚本的更多信息,请参阅“测试 PostgreSQL 服务容器”。

主机名是localhost127.0.0.1

测试 PostgreSQL 服务容器

您可以使用以下脚本测试您的工作流,该脚本连接到 PostgreSQL 服务并添加一个包含一些占位符数据的新表。然后,脚本将存储在 PostgreSQL 表中的值打印到终端。您的脚本可以使用任何您喜欢的语言,但此示例使用 Node.js 和pg npm 模块。有关更多信息,请参阅npm pg 模块

您可以修改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', '[email protected]']

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: '[email protected]' } ]