问题
我正在尝试在 GitLab CI 中运行我的单元测试。对于我的测试设置,我使用 docker-compose 启动由三个 Neo4j 实例组成的数据库集群,然后通过 localhost 在 docker 主机上运行测试。
在我的机器上这工作得很好,所以我尝试在 GitLab CI 上做同样的事情。我最初在让 docker-compose 在 CI 容器内运行时遇到了一些问题,但我设法使用以下 .gitlab-ci.yaml 使其工作:
image: "tiangolo/docker-with-compose:latest"
before_script:
- apk add --update nodejs npm
- npm install npm@latest -g
- npm install
services:
- docker:dind
run-test:
script:
- docker-compose up -d --build
- npm test
依赖项已安装,docker-compose 成功启动数据库,并且 npm test
运行我的单元测试。到目前为止,一切都很好。 但是以某种形式使用数据库连接的所有测试都会失败,因为它们无法在 localhost:7687 上访问它。我收到以下错误消息
Neo4jError: Could not perform discovery. No routing servers available. Known routing table: RoutingTable[database=default database, expirationTime=0, currentTime=1588275075260, routers=[], readers=[], writers=[]]
请记住,我在本地计算机上使用相同的 docker-compose.yaml 并且一切正常,因此数据库配置不应该有问题。
我已经尝试过的
我认为我的测试是在数据库完全启动之前运行的,所以我添加了一个sleep 120
,如下所示
run-test:
script:
- docker-compose up -d --build
- sleep 120
- npm test
我什至测量了集群在 CI 容器内启动所需的时间,并适当选择了超时,但运气不好,测试仍然失败。
然后我查看了 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.2 docker 3590cde9c5df runner-k3xtxnwc-project-17881831-concurrent-0-6d9d78b64ad6df95-docker-0
172.17.0.3 runner-k3xtxnwc-project-17881831-concurrent-0
$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' core1
172.19.0.2
$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' core2
172.19.0.4
但这对我来说看起来不错。然后我尝试用 docker:7678
、172.0.0.1
甚至 $(dockerspect -f '{ {范围.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' core1):7678
。但它们都不起作用。
尝试curl localhost:7474
(neo4j http控制台)返回无法连接到本地主机端口7474:连接被拒绝
编辑:
我的 docker-compose.yaml
version: '3'
services:
dbc1:
build: ./database
container_name: core1
hostname: core1
ports:
- 7474:7474
- 7687:7687
environment:
- NEO4J_dbms_mode=CORE
- NEO4J_causal__clustering_minimum__core__cluster__size__at__formation=3
- NEO4J_causal__clustering_minimum__core__cluster__size__at__runtime=3
- NEO4J_causal__clustering_initial__discovery__members=core1:5000,core2:5000,core3:5000
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_connector_bolt_advertised__address=localhost:7687
- NEO4J_dbms_connector_http_advertised__address=localhost:7474
volumes:
- dbdata1:/data
ulimits:
nofile:
soft: 40000
hard: 40000
dbc2:
build: ./database
container_name: core2
hostname: core2
ports:
- 8474:7474
- 8687:7687
environment:
- NEO4J_dbms_mode=CORE
- NEO4J_causal__clustering_minimum__core__cluster__size__at__formation=3
- NEO4J_causal__clustering_minimum__core__cluster__size__at__runtime=3
- NEO4J_causal__clustering_initial__discovery__members=core1:5000,core2:5000,core3:5000
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_connector_bolt_advertised__address=localhost:8687
- NEO4J_dbms_connector_http_advertised__address=localhost:8474
volumes:
- dbdata2:/data
ulimits:
nofile:
soft: 40000
hard: 40000
dbc3:
build: ./database
container_name: core3
hostname: core3
ports:
- 9474:7474
- 9687:7687
environment:
- NEO4J_dbms_mode=CORE
- NEO4J_causal__clustering_minimum__core__cluster__size__at__formation=3
- NEO4J_causal__clustering_minimum__core__cluster__size__at__runtime=3
- NEO4J_causal__clustering_initial__discovery__members=core1:5000,core2:5000,core3:5000
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_dbms_connector_bolt_advertised__address=localhost:9687
- NEO4J_dbms_connector_http_advertised__address=localhost:9474
volumes:
- dbdata3:/data
ulimits:
nofile:
soft: 40000
hard: 40000
volumes:
dbdata1:
driver: local
dbdata2:
driver: local
dbdata3:
driver: local
我的数据库 Dockerfile(位于 ./database):
FROM graphfoundation/ongdb:3.6
RUN echo "* soft nofile 40000" >> /etc/security/limits.conf
RUN echo "* hard nofile 40000" >> /etc/security/limits.conf
## inject password change into startup script
# create alternative startup script
RUN echo "#!/bin/bash -eu" >> /docker-entrypoint-modified.sh
# add command to change password
RUN echo "bin/neo4j-admin set-initial-password testpassword" >> /docker-entrypoint-modified.sh
# copy the contents of docker-entrypoint.sh, but skip the first line
RUN tail -n +2 /docker-entrypoint.sh >> /docker-entrypoint-modified.sh
# replace docker-entrypoint.sh with docker-entrypoint-modify
RUN cat /docker-entrypoint-modified.sh > /docker-entrypoint.sh
EXPOSE 7474 7473 7687
最佳答案
事实证明,我对 docker-in-docker 有一些误解,我通过更改 .gitlab-ci.yaml< 中的以下行,将 localhost“重新路由”到 docker-in-docker 服务解决了问题
:
services:
- docker:dind
至
services:
- name: docker:dind
alias: localhost
关于docker - 无法在 GitLab CI docker-in-docker 中针对 neo4j 数据库运行测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61547125/