# Создание контейнеров служб PostgreSQL

Вы можете создать контейнер службы PostgreSQL, который будет использоваться в вашем рабочем процессе. В этом руководстве показаны примеры создания службы PostgreSQL для заданий, которые выполняются в контейнерах или непосредственно на компьютере средства выполнения тестов.

## Введение

В этом руководстве показаны примеры рабочих процессов, которые настраивают сервисный контейнер с помощью изображения Docker Hub `postgres`. Рабочий процесс запускает сценарий, который подключается к службе PostgreSQL, создает таблицу, а затем заполняет ее данными. Чтобы убедиться в том, что рабочий процесс создает и заполняет таблицу PostgreSQL, сценарий выводит данные из таблицы в консоль.

> \[!NOTE]
> Если в рабочих процессах используются действия контейнеров Docker, контейнеры заданий или контейнеры служб, необходимо использовать средство выполнения Linux:
>
> * При использовании размещенных в GitHub средств выполнения необходимо применять средство выполнения Ubuntu.
> * Если вы применяете локальные средства выполнения, необходимо использовать компьютер Linux в качестве средства выполнения, а Docker нужно установить.

## Необходимые компоненты

Вы должны знать, как работают контейнеры GitHub Actions служб и сетевые различия между выполнением заданий непосредственно на средстве выполнения или в контейнере. Дополнительные сведения см. в разделе [Взаимодействие с контейнерами служб Docker](/ru/actions/tutorials/use-containerized-services/use-docker-service-containers).

Вы также можете найти полезное представление о YAML, синтаксисе и GitHub ActionsPostgreSQL. Дополнительные сведения см. в разделе:

* [Написание рабочих процессов](/ru/actions/how-tos/write-workflows)
* [Руководство](https://www.postgresqltutorial.com/) по PostgreSQL в документации по PostgreSQL

## Выполнение заданий в контейнерах

Настройка заданий для запуска в контейнере упрощает сетевые конфигурации между заданием и контейнерами служб. Контейнеры Docker в одной пользовательской сети моста предоставляют все порты друг другу, поэтому вам не нужно сопоставлять порты контейнера службы с узлом Docker. Вы можете получить доступ к контейнеру службы из контейнера заданий с помощью метки, настроенной в рабочем процессе.

Этот файл рабочего процесса можно скопировать в каталог `.github/workflows` репозитория и при необходимости изменить его.

```yaml copy
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@v6

      # 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
```

### Настройка задания runner для заданий в контейнерах

Этот рабочий процесс настраивает задание, которое выполняется в контейнере `node:20-bookworm-slim` и использует `ubuntu-latest` средство запуска  GitHub, размещенное в качестве узла Docker для контейнера. Дополнительные сведения о контейнере `node:20-bookworm-slim` см. в статье об [образе узла](https://hub.docker.com/_/node) в Docker Hub.

Рабочий процесс настраивает контейнер службы с меткой `postgres`. Все службы должны выполняться в контейнере, поэтому для каждой из них требуется указать `image` контейнера. Этот пример использует образ контейнера `postgres`, предоставляет пароль PostgreSQL по умолчанию и включает параметры проверки работоспособности, чтобы была возможность убедиться, что служба запущена. Дополнительные сведения см. в разделе [Образ Postgres](https://hub.docker.com/_/postgres) на Docker Hub.

```yaml copy
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 copy
steps:
  # Downloads a copy of the code in your repository before running CI tests
  - name: Check out repository code
    uses: actions/checkout@v6

  # 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_HOST` и `POSTGRES_PORT` для создания клиента. Эти две переменные среды задаются на шаге рабочего процесса "Подключение к PostgreSQL", после чего становятся доступны скрипту *client.js*. Дополнительные сведения о скрипте см. в разделе ["Тестирование контейнера](#testing-the-postgresql-service-container) службы PostgreSQL".

Имя узла службы PostgreSQL — это метка, настроенная в рабочем процессе; в данном случае — `postgres`. Так как контейнеры Docker в той же пользовательской сети моста открывают все порты по умолчанию, вы можете получить доступ к контейнеру службы через стандартный порт PostgreSQL 5432.

## Выполнение заданий непосредственно на компьютере средства выполнения тестов

При запуске задания непосредственно на компьютере средства выполнения тестов необходимо сопоставить порты контейнера службы с портами на узле Docker. Вы можете получить доступ к контейнерам служб из узла Docker, используя `localhost` и номер порта узла Docker.

Этот файл рабочего процесса можно скопировать в каталог `.github/workflows` репозитория и при необходимости изменить его.

```yaml copy
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@v6

      # 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
```

### Настройка задания runner для заданий непосредственно на компьютере runner

В примере используется `ubuntu-latest` метод  GitHub, размещенный в в качестве узла Docker.

Рабочий процесс настраивает контейнер службы с меткой `postgres`. Все службы должны выполняться в контейнере, поэтому для каждой из них требуется указать `image` контейнера. Этот пример использует образ контейнера `postgres`, предоставляет пароль PostgreSQL по умолчанию и включает параметры проверки работоспособности, чтобы была возможность убедиться, что служба запущена. Дополнительные сведения см. в разделе [Образ Postgres](https://hub.docker.com/_/postgres) на Docker Hub.

Рабочий процесс сопоставляет порт 5432 в контейнере службы PostgreSQL с узлом Docker. Дополнительные сведения о ключевом слове `ports` см. в разделе [Взаимодействие с контейнерами служб Docker](/ru/actions/tutorials/use-containerized-services/use-docker-service-containers#mapping-docker-host-and-service-container-ports).

```yaml copy
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
```

### Настройка шагов для заданий непосредственно на компьютере runner

Рабочий процесс выполняет следующие действия:

1. извлекает репозиторий в средстве выполнения;
2. устанавливает зависимости;
3. выполняет скрипт для создания клиента.

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

  # 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_HOST` и `POSTGRES_PORT` для создания клиента. Эти две переменные среды задаются на шаге рабочего процесса "Подключение к PostgreSQL", после чего становятся доступны скрипту *client.js*. Дополнительные сведения о скрипте см. в разделе ["Тестирование контейнера](#testing-the-postgresql-service-container) службы PostgreSQL".

Имя узла — `localhost` или `127.0.0.1`.

## Тестирование контейнера службы PostgreSQL

Вы можете протестировать рабочий процесс с помощью следующего сценария, который подключается к службе PostgreSQL и добавляет новую таблицу с данными заполнителей. Затем сценарий выводит в терминал значения, хранящиеся в таблице PostgreSQL. Сценарий может использовать любой выбранный язык, но в этом примере используется Node.js и модуль npm `pg`. Дополнительные сведения см. в [модуле npm pg](https://www.npmjs.com/package/pg).

Вы можете изменить *client.js*, чтобы включить все операции PostgreSQL, необходимые для вашего рабочего процесса. В этом примере сценарий подключается к службе PostgreSQL, добавляет таблицу в базу данных `postgres`, вставляет данные заполнителей, а затем извлекает данные.

Добавьте в репозиторий новый файл *client.js* с приведенным ниже кодом.

```javascript copy
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_HOST` и `POSTGRES_PORT` для указания IP-адреса и порта службы PostgreSQL. Если `host` и `port` не определены, по умолчанию используется узел `localhost` и порт 5432.

Сценарий создает таблицу и заполняет ее данными заполнителя. Чтобы убедиться в том, что база данных `postgres` содержит эти данные, сценарий выводит содержимое базы данных в журнал консоли.

При запуске этого рабочего процесса вы увидите следующие выходные данные на шаге «Подключение к PostgreSQL», который подтверждает успешное создание таблицы PostgreSQL и добавление данных:

```text
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' } ]
```