GitLab CIとgitlab-ci-multi-runner
を使用する場合、内部で起動されたDockerコンテナーを取得して、ビルドが実行されているDockerイメージである「ホスト」にポートを公開することができません。
私の.gitlab-ci.yml
ファイル:
test:
image: docker
stage: test
services:
- docker:dind
script:
- APP_CONTAINER_ID=`docker run -d --privileged -p "9143:9143" appropriate/nc nc -l 9143`
- netstat -a
- docker exec $APP_CONTAINER_ID netstat -a
- nc -v localhost 9143
私のコマンド:
gitlab-ci-multi-runner exec docker --docker-privileged test
出力:
$ netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 runner--project-1-concurrent-0:54664 docker:2375 TIME_WAIT
tcp 0 0 runner--project-1-concurrent-0:54666 docker:2375 TIME_WAIT
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
$ docker exec $APP_CONTAINER_ID netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:9143 0.0.0.0:* LISTEN
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
$ nc -v localhost 9143
ERROR: Build failed: exit code 1
FATAL: exit code 1
ここで何が間違っていますか?
元の質問が続く-上記は短く、テストしやすい例です
ポート9143
でリッスンするアプリケーションイメージがあります。その起動と設定はdocker-compose.yml
を介して管理され、docker-compose up
を使用してローカルマシンで問題なく動作します-localhost:9143
に問題なくアクセスできます。
ただし、共有ランナーを介してGitLab CI(gitlab.com
バージョン)で実行する場合、ポートは公開されていないようです。
私の.gitlab-ci.yml
の関連部分:
test:
image: craigotis/buildtools:v1
stage: test
script:
- docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com/craigotis/myapp
- docker-compose up -d
- sleep 60 # a temporary hack to get the logs
- docker-compose logs
- docker-machine env
- docker-compose port app 9143
- netstat -a
- docker-compose ps
- /usr/local/bin/wait-for-it.sh -h localhost -p 9143 -t 60
- cd mocha
- npm i
- npm test
- docker-compose down
出力は次のとおりです。
$ docker-compose logs
...
app_1 | [Thread-1] INFO spark.webserver.SparkServer - == Spark has ignited ...
app_1 | [Thread-1] INFO spark.webserver.SparkServer - >> Listening on 0.0.0.0:9143
app_1 | [Thread-1] INFO org.Eclipse.jetty.server.Server - jetty-9.0.z-SNAPSHOT
app_1 | [Thread-1] INFO org.Eclipse.jetty.server.ServerConnector - Started ServerConnector@6919dc5{HTTP/1.1}{0.0.0.0:9143}
...
$ docker-compose port app 9143
0.0.0.0:9143
$ netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 runner-e11ae361-project-1925166-concurrent-0:53646 docker:2375 TIME_WAIT
tcp 0 0 runner-e11ae361-project-1925166-concurrent-0:53644 docker:2375 TIME_WAIT
tcp 0 0 runner-e11ae361-project-1925166-concurrent-0:53642 docker:2375 TIME_WAIT
Active UNIX domain sockets (servers and established)
Proto RefCnt Flags Type State I-Node Path
$ docker-compose ps
stty: standard input: Not a tty
Name Command State Ports
----------------------------------------------------------------------------------------
my_app_1 wait-for-it.sh mysql_serve ... Up 8080/tcp, 0.0.0.0:9143->9143/tcp
mysql_server docker-entrypoint.sh --cha ... Up 3306/tcp
$ /usr/local/bin/wait-for-it.sh -h localhost -p 9143 -t 60
wait-for-it.sh: waiting 60 seconds for localhost:9143
wait-for-it.sh: timeout occurred after waiting 60 seconds for localhost:9143
私のdocker-compose.yml
の内容:
version: '2'
networks:
app_net:
driver: bridge
services:
app:
image: registry.gitlab.com/craigotis/myapp:latest
depends_on:
- "db"
networks:
- app_net
command: wait-for-it.sh mysql_server:3306 -t 60 -- Java -jar /opt/app*.jar
ports:
- "9143:9143"
db:
image: mysql:latest
networks:
- app_net
container_name: mysql_server
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=true
seemsアプリケーションコンテナが9143
をリッスンしているようで、共有GitLabランナーに適切に公開されていますが、実際には公開されていないようです。それは私のローカルマシンでうまく動作します-この作業を行う必要がある特別な回避策/調整がありますかinsideGitLabで実行されているDockerコンテナですか?
公式の gitlab.comドキュメントのgitab-ci は PostgreSQLの例 を指します
動作中のCI はlocalhostに接続しようとせず、むしろ サービス名
services
キーワードは、ビルド中に実行され、imageキーワードが定義するdockerイメージにリンクされる別のdockerイメージのみを定義します。これにより、ビルド時にサービスイメージにアクセスできます。MySQLのサービスコンテナには、ホスト名
mysql
でアクセスできます。
したがって、データベースサービスにアクセスするには、ソケットまたはmysql
ではなくlocalhost
という名前のホストに接続する必要があります。
これがあなたのケースに当てはまるかどうかを確認し、app:9143
の代わりに localhost:9143
。
docker:dind
を使用すると、コンテナが作成され、Docker構成コンテナがその中にセットアップされます。 docker:dind
コンテナー内のlocalhostにポートを公開します。コードが実行されている環境からlocalhost
としてこれにアクセスすることはできません。
このdocker:dind
コンテナを参照するために、docker
というホスト名が設定されています。 cat /etc/hosts
を使用して確認できます。
localhost:9143
を参照する代わりに、docker:9143
を使用する必要があります。
あなたのdocker-compose.yml
は大丈夫のようです。
しかし、IPまたはポートのルーティングにエラーがあると思います。共有情報からわかるように、アプリはport914 on ip .0.0. as0.0で実行されています.0.0:9143。
localhost:9143
としてアクセスし、127.0.0.1:9143
として解釈できます。
this によると。
127.0.0.1 is the loopback address (also known as localhost).
0.0.0.0 is a non-routable meta-address used to designate an invalid, unknown, or non-applicable target (a ‘no particular address’ place holder).
127.0.0.1:9143
でアプリを実行して、結果を共有してみてください。
[〜#〜] update [〜#〜]
または、サービスを使用して、サービス名で documentation のように実行できます:
servicesキーワードは、ビルド中に実行され、imageキーワードが定義するdockerイメージにリンクされる別のdockerイメージのみを定義します。これにより、ビルド時にサービスイメージにアクセスできます。
MySQLのサービスコンテナは、hostnamemysql
でアクセスできます。したがって、データベースサービスにアクセスするには、ソケットまたはlocalhost
。ではなく、mysqlという名前のホストに接続する必要があります。
通常、Dockerマシンはlocalhostでは実行されませんが、他のIPアドレスを持つdockerホストで実行されます。 docker-machine ip
を使用して、DockerホストIPを取得してください。