В нашей настройке CICD мы используем действия github для запуска пары контейнеров docker и выполнения некоторых тестов, которые зависят от этих контейнеров docker.
Вот рабочий процесс для запуска тестов:
файл docker compose (./docker/docker-compose.test.yml) — это просто простой экземпляр mongodb:
Недавно я обнаружил, что мы можем использовать образ CI для контейнеризации наших инструментов для использования в действиях github, вместо того чтобы устанавливать инструменты при каждом запуске рабочего процесса.
Я создал образ CI и отправил его в dockerhub: https://hub.docker.com/r/prosopo/ci
Затем я изменил рабочий процесс для запуска с использованием образа ci в качестве контейнер:
Однако вот где я столкнулся с загвоздкой. npm run test
запускает некоторые JS-тесты, которые ожидают, что mongodb находится по адресу localhost:27017. Когда вы запускаете это с хост-машины, это работает. Но при запуске из контейнера, то есть контейнера ci, localhost разрешается в контейнер ci, а не на хост-машину, где опубликован порт 27017. Я читал, что это сетевое взаимодействие хоста и контейнера. Поэтому я скорректировал тесты так, чтобы они указывали на docker-database-1:27017 (это имя контейнера mongo), и добавил контейнеры mongo и ci в одну и ту же сеть.
скорректировал файл docker compose:
затем в рабочем процессе:
Github не позволяет указывать аргумент --network
для контейнера ci, поэтому мне пришлось вручную добавлять его в сеть перед тестированием.
Это кажется неуклюжей настройкой, потому что:
Есть ли лучший способ сделать это? Мне кажется, что это обычная настройка, и мы не можем быть первыми, кто перейдет этот мост. Хранение наших инструментов в образе CI очень удобно для нас, чтобы избежать длительного времени установки и поддерживать единообразие инструментов, поэтому я хотел бы, чтобы это работало. Но нам нужно иметь возможность запускать тесты локально, используя localhost:27017
в качестве цели, а также запускать тесты в CICD.
Я читал, что мы могли бы использовать службы Github для этого, и Github автоматически управляет сетью для вас. Однако это запускает контейнеры параллельно заданию рабочего процесса, что означает, что образ docker должен быть доступен заранее. В другом из наших рабочих процессов мы создаем образ для зависимого контейнера и запускаем несколько других тестов — контейнеры служб здесь не будут работать, потому что образ docker недоступен до начала задания.
jobs:
check:
runs-on: ubuntu-latest
steps:
<setup steps omitted for brevity>
- name: Test
run: |
docker compose --file ./docker/docker-compose.test.yml up -d
npm run test
services:
database:
image: mongo:5.0.4
# volumes:
# - ./db:/data/db
ports:
- '27017:27017'
environment:
- MONGO_INITDB_ROOT_USERNAME=<hidden>
- MONGO_INITDB_ROOT_PASSWORD=<hidden>
- MONGO_INITDB_DATABASE=<hidden>
jobs:
check:
runs-on: ubuntu-latest
container:
image: prosopo/ci:latest
options: >
--volume ${{ github.workspace }}:/repo
steps:
<setup steps omitted for brevity>
- name: Test
run: |
docker compose --file ./docker/docker-compose.test.yml up -d
npm run test
services:
database:
image: mongo:5.0.4
# volumes:
# - ./db:/data/db
ports:
- '27017:27017'
networks:
- pronet
environment:
- MONGO_INITDB_ROOT_USERNAME=<hidden>
- MONGO_INITDB_ROOT_PASSWORD=<hidden>
- MONGO_INITDB_DATABASE=<hidden>
networks:
pronet:
driver: bridge
jobs:
check:
runs-on: ubuntu-latest
container:
image: prosopo/ci:latest
options: >
--volume ${{ github.workspace }}:/repo
steps:
<setup steps omitted for brevity>
- name: Test
run: |
docker network connect pronet $(docker ps | grep prosopo/ci:latest | awk '{print $NF}')
docker compose --file ./docker/docker-compose.test.yml up -d
npm run test