当使用GitLab CI以及 gitlab-ci-multi-runner
时,我无法获得内部启动的Docker容器以将其端口暴露给"host",这是运行构建的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
我在这做错了什么?
Original Question Follows - above is a shorter, easier-to-test example
我有一个监听端口 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上运行的Docker容器中进行此工作?
4 回答
通常,docker机器不会在localhost上运行,而是在具有其他ip地址的docker主机上运行 . 尝试使用
docker-machine ip
来获取您的docker主机ip .官方gitab-ci on gitlab.com documentation指的是example of PostgreSQL
Its working CI不会尝试连接到localhost,而是尝试连接到service name
您可以检查这是否适用于您的情况,并尝试在
app:9143
而不是localhost:9143
中访问您的应用程序服务 .你的
docker-compose.yml
似乎还可以 .但我认为您的IP或端口路由存在错误 . 正如我从您的共享信息中看到的那样,您的应用程序在 port 9143 上运行,在ip 0.0.0.0 上为0.0.0.0:9143 .
并且您将其作为
localhost:9143
访问,可以解释为127.0.0.1:9143
.根据this .
您可以尝试在
127.0.0.1:9143
上运行您的应用,然后分享结果 .UPDATE
或者您可以使用服务按服务名称运行它documentation建议:
services关键字仅定义在构建期间运行的另一个docker镜像,并链接到image关键字定义的docker镜像 . 这允许您在构建期间访问服务映像 .
可以在 hostname
mysql
下访问MySQL的服务容器 . 因此,为了访问您的数据库服务,您必须连接到名为mysql的主机而不是套接字或localhost
.使用
docker:dind
时,会创建一个容器,并在其中设置docker-compose容器 . 它将端口暴露给docker:dind
容器中的localhost . 您无法从执行代码的环境中将其作为localhost
进行访问 .设置了
docker
的主机名,供您引用此docker:dind
容器 . 您可以使用cat /etc/hosts
进行检查 .而不是引用
localhost:9143
,你应该使用docker:9143
.