GitLab CI: как подключиться к контейнеру докера, запущенному в скрипте .gitlab-ci.yml?
Начальная задача
В моей сборке GitLab CI я хочу:
- Запустите док-контейнер с локальным AmazonDB. Стандартная компоновка портов: порт
8000
в докере, порт8000
разоблачены. Конечно, все работает локально, могу подключить (curl
,awc-cli
, Java-код для БД Amazon, как хотите). - Используйте его для тестов, т.е. подключитесь к нему как
--endpoint-url http://localhost:8000
(или любой другой сопоставленный IP вместоlocalhost
).
Проблема
.gitlab-ci.yml
выглядит так:
image: docker:stable
build/test:
tags:
- gradle
- eu
stage: test
# doesn't work with or without it
# services:
# - docker:dind
script:
# display local running containers
- echo Displaying all running docker containers with "amazon/dynamodb-local" image...
- docker ps --filter ancestor=amazon/dynamodb-local
# stop all running docker containers with "amazon/dynamodb-local" image
- echo Stopping all Docker containers with "amazon/dynamodb-local" image...
- CONTAINERS=$(docker ps -q --filter ancestor=amazon/dynamodb-local)
- >
if [ "${CONTAINERS}" == "" ]; then
echo No docker containers with "amazon/dynamodb-local" image running. Nothing to stop.
else
docker stop $(docker ps -q --filter ancestor=amazon/dynamodb-local)
echo All Docker containers with "amazon/dynamodb-local" image stopped.
fi
# start DynamoDB local as a docker container with shared database
# - java -Djava.library.path=./dynamodb_local_latest/DynamoDBLocal_lib -jar ./dynamodb_local_latest/DynamoDBLocal.jar -sharedDb
# relative path to causes "Error: Unable to access jarfile" for both windows and linux
# run Docker in detached mode to not hang on the opened console
- cd ./dynamodb_local_latest
- docker run --detach -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -sharedDb
- cd ./..
# display local running containers
- echo Displaying all running docker containers with "amazon/dynamodb-local" image...
- docker ps --filter ancestor=amazon/dynamodb-local
# see https://stackru.com/questions/45389116/unable-to-access-docker-compose-containers-created-inside-docker
# $DOCKER_HOST is unix:///var/run/docker.sock
# http://localhost:8080 fails
# http://docker:8000 fails
# http://unix:///var/run/docker.sock:8000 fails
- echo docker host is ${DOCKER_HOST}
- cat /etc/hosts
# - curl docker:80 | true
# - curl docker:8000 | true
# - curl http://docker:8000 | true
# - curl http://docker:8000 | true
# - curl ${DOCKER_HOST} | true
# - curl ${DOCKER_HOST}:8000 | true
- curl localhost:8000 | true
- curl http://localhost:8000 | true
# stop all running docker containers with "amazon/dynamodb-local" image
- echo Stopping all Docker containers with "amazon/dynamodb-local" image...
- CONTAINERS=$(docker ps -q --filter ancestor=amazon/dynamodb-local)
- >
if [ "${CONTAINERS}" == "" ]; then
echo No docker containers with "amazon/dynamodb-local" image running. Nothing to stop.
else
docker stop $(docker ps -q --filter ancestor=amazon/dynamodb-local)
echo All Docker containers with "amazon/dynamodb-local" image stopped.
fi
# display local running containers
- echo Displaying all running docker containers with "amazon/dynamodb-local" image...
- docker ps --filter ancestor=amazon/dynamodb-local
Критические точки выполнения (журнал Gitlab-CI) выглядят так:
Контейнер Docker запускается:
$ docker run --detach -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -sharedDb
c823489c22fffa603c1ae1b91d898cb7de4964774d54a08c9fdf0b891c2243b4
$ echo Displaying all running docker containers with "amazon/dynamodb-local" image...
Displaying all running docker containers with amazon/dynamodb-local image...
$ docker ps --filter ancestor=amazon/dynamodb-local
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c823489c22ff amazon/dynamodb-local "java -jar DynamoDBL…" 1 second ago Up Less than a second 0.0.0.0:8000->8000/tcp peaceful_beaver
curl не работает (перепробовал все возможные варианты, это всего лишь пример):
$ curl localhost:8000 | true
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (7) Failed to connect to localhost port 8000: Connection refused
Authenticating with credentials from $DOCKER_AUTH_CONFIG
ERROR: Job failed: exit code 7
Я пробовал с и без
services:
- docker:dind
Пробовал с именами хостов localhost
или docker
или tcp://localhost
, с http://
префикс или без него, с портами 80
, 8000
или 2375
. Ничего не работает.
Ценность ${DOCKER_HOST}
является unix:///var/run/docker.sock
:
$ echo docker host is ${DOCKER_HOST}
docker host is unix:///var/run/docker.sock
/etc/hosts
не содержит псевдонима для docker
$ cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 runner-H3HL9s9t-project-913-concurrent-0
Вопросы
- Как решить эту типичную задачу?
- Это разрешимо с
docker run
, или сложныйdocker-compose
требуется использование. - Есть ссылка на рабочий пример?
- Это проблема, что нет
docker
псевдоним в/etc/hosts
? - Является
unix:///var/run/docker.sock
действительное значение${DOCKER_HOST}
? Разве значение этой переменной не должно быть установлено вvariables
из.gitlab-ci.yml
(особенно дляtcp://localhost:2375
)?
Ссылки
Есть несколько ссылок, по которым я погуглил. Решения оттуда мне пока не помогли.
- https://gitlab.com/gitlab-com/support-forum/issues/748
- https://gitlab.com/gitlab-org/charts/gitlab/issues/478
- https://blog.lwolf.org/post/how-to-build-and-test-docker-images-in-gitlab-ci/
- https://gitlab.com/gitlab-org/gitlab-foss/issues/26566 - аналогичная проблема для
docker-compose
- https://gitlab.com/gitlab-org/gitlab-foss/issues/40774 - точно такая же проблема
- Gitlab CI runner не может открывать порты вложенных контейнеров Docker
- Невозможно получить доступ к контейнерам docker-compose, созданным внутри Docker
1 ответ
Нет нужды писать такое сложное решение с ручным управлением. docker run
/ docker stop
внутри -script
раздел. Тонкий и простой способ - использовать локальную DynamoDB какservice
.
С помощью этого скрипта локальный DynamoDB будет доступен по URL из alias
из services
элемент, т.е. dynamodb-local
для этого примера:
services:
- name: amazon/dynamodb-local
alias: dynamodb-local
Выполнение aws dynamodb
с участием http://dynamodb-local:8000
URL конечной точки работает:
script:
- DYNAMODB_LOCAL_URL=http://dynamodb-local:8000
- apk add --no-cache curl jq python py-pip
- pip install awscli
- aws dynamodb list-tables --endpoint-url ${DYNAMODB_LOCAL_URL} --region eu-central-1
Этот вариант был найден в этом замечательном ответе. Большое спасибо madhead за это!