Neo4j Docker 与 Python FastAPI、https 上的 Traefic 组合,"Connection refused"
Neo4j Docker Compose with Python FastAPI, Traefic on https, "Connection refused"
我正在使用 Docker 组合多个容器(Full Stack FastAPI 的自定义版本,但包含 Neo4j)。
完整 docker-compose.yml here 和 neo4j 的摘录:
neo4j:
image: neo4j
networks:
- ${TRAEFIK_PUBLIC_NETWORK?Variable not set}
- default
ports:
- "6477:6477"
- "7474:7474"
- "7687:7687"
volumes:
- app-neo4j-data:/data
- app-neo4j-plugins:/plugins
env_file:
- .env
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_AUTH=${NEO4J_USERNAME?Variable not set}/${NEO4J_PASSWORD?Variable not set}
- NEO4J_dbms_default__advertised__address=0.0.0.0
- NEO4J_dbms_default__listen__address=0.0.0.0
- NEO4J_dbms_connector_bolt_advertised__address=0.0.0.0:7687
- NEO4J_dbms_connector_bolt_listen__address=0.0.0.0:7687
- NEO4J_dbms_connector_http_listen__address=:7474
- NEO4J_dbms_connector_http_advertised__address=:7474
- NEO4J_dbms_connector_https_listen__address=:6477
- NEO4J_dbms_connector_https_advertised__address=:6477
- NEO4J_dbms_connector_bolt_listen__address=:7687
- NEO4J_dbms_mode=SINGLE
deploy:
labels:
- traefik.enable=true
- traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK?Variable not set}
- traefik.constraint-label=${TRAEFIK_PUBLIC_TAG?Variable not set}
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-http.rule=Host(`neo4j.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-http.entrypoints=http
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-http.middlewares=${STACK_NAME?Variable not set}-https-redirect
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.rule=Host(`neo4j.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.entrypoints=https
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.tls=true
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.tls.certresolver=le
- traefik.http.services.${STACK_NAME?Variable not set}-neo4j.loadbalancer.server.port=7474
replicas: 1
resources:
limits:
memory: 1024M
reservations:
memory: 500M
restart_policy:
condition: on-failure
我尝试使用 bolt://login:password@neo4j:7687
从后端访问 bolt
但出现以下错误:
neo4j.exceptions.ServiceUnavailable: Couldn't connect to neo4j:7687 (resolved to ('10.0.3.11:7687',)):
Failed to establish connection to ResolvedIPv4Address(('10.0.3.11', 7687)) (reason [Errno 111] Connection refused)
我在 Whosebug 上查看了大量回复,但一无所获。这确实适用于开发,但我还没有在那里实现 https,所以我不确定这是否是导致问题的原因。
我很茫然,希望得到任何指导。
此特定问题与 Docker 或 Neo4j 没有直接关系。相反,它需要有限的时间来初始化数据库。解决方案是重试连接。这是我的处理方式:
from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed
max_tries = 60 * 5 # 5 minutes
wait_seconds = 1
@retry(
stop=stop_after_attempt(max_tries),
wait=wait_fixed(wait_seconds),
before=before_log(logger, logging.INFO),
after=after_log(logger, logging.WARN),
)
def initNeo4j() -> None:
try:
init_gdb()
except Exception as e:
raise e
其中 init_gdb()
是初始化 Neo4j 的脚本。
问题出现在 Docker 完成容器实例化并且主后端服务器开始初始化和构建自身之后。创建管理员用户时,数据库必须已启动并且 运行,如果未启动,则会出现此错误。
鉴于相同的错误被用于涵盖众多问题,不一定清楚数据库未准备就绪,而不是到达它的某些设置不正确。
我正在使用 Docker 组合多个容器(Full Stack FastAPI 的自定义版本,但包含 Neo4j)。
完整 docker-compose.yml here 和 neo4j 的摘录:
neo4j:
image: neo4j
networks:
- ${TRAEFIK_PUBLIC_NETWORK?Variable not set}
- default
ports:
- "6477:6477"
- "7474:7474"
- "7687:7687"
volumes:
- app-neo4j-data:/data
- app-neo4j-plugins:/plugins
env_file:
- .env
environment:
- NEO4J_ACCEPT_LICENSE_AGREEMENT=yes
- NEO4J_AUTH=${NEO4J_USERNAME?Variable not set}/${NEO4J_PASSWORD?Variable not set}
- NEO4J_dbms_default__advertised__address=0.0.0.0
- NEO4J_dbms_default__listen__address=0.0.0.0
- NEO4J_dbms_connector_bolt_advertised__address=0.0.0.0:7687
- NEO4J_dbms_connector_bolt_listen__address=0.0.0.0:7687
- NEO4J_dbms_connector_http_listen__address=:7474
- NEO4J_dbms_connector_http_advertised__address=:7474
- NEO4J_dbms_connector_https_listen__address=:6477
- NEO4J_dbms_connector_https_advertised__address=:6477
- NEO4J_dbms_connector_bolt_listen__address=:7687
- NEO4J_dbms_mode=SINGLE
deploy:
labels:
- traefik.enable=true
- traefik.docker.network=${TRAEFIK_PUBLIC_NETWORK?Variable not set}
- traefik.constraint-label=${TRAEFIK_PUBLIC_TAG?Variable not set}
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-http.rule=Host(`neo4j.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-http.entrypoints=http
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-http.middlewares=${STACK_NAME?Variable not set}-https-redirect
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.rule=Host(`neo4j.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.entrypoints=https
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.tls=true
- traefik.http.routers.${STACK_NAME?Variable not set}-neo4j-https.tls.certresolver=le
- traefik.http.services.${STACK_NAME?Variable not set}-neo4j.loadbalancer.server.port=7474
replicas: 1
resources:
limits:
memory: 1024M
reservations:
memory: 500M
restart_policy:
condition: on-failure
我尝试使用 bolt://login:password@neo4j:7687
从后端访问 bolt
但出现以下错误:
neo4j.exceptions.ServiceUnavailable: Couldn't connect to neo4j:7687 (resolved to ('10.0.3.11:7687',)):
Failed to establish connection to ResolvedIPv4Address(('10.0.3.11', 7687)) (reason [Errno 111] Connection refused)
我在 Whosebug 上查看了大量回复,但一无所获。这确实适用于开发,但我还没有在那里实现 https,所以我不确定这是否是导致问题的原因。
我很茫然,希望得到任何指导。
此特定问题与 Docker 或 Neo4j 没有直接关系。相反,它需要有限的时间来初始化数据库。解决方案是重试连接。这是我的处理方式:
from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed
max_tries = 60 * 5 # 5 minutes
wait_seconds = 1
@retry(
stop=stop_after_attempt(max_tries),
wait=wait_fixed(wait_seconds),
before=before_log(logger, logging.INFO),
after=after_log(logger, logging.WARN),
)
def initNeo4j() -> None:
try:
init_gdb()
except Exception as e:
raise e
其中 init_gdb()
是初始化 Neo4j 的脚本。
问题出现在 Docker 完成容器实例化并且主后端服务器开始初始化和构建自身之后。创建管理员用户时,数据库必须已启动并且 运行,如果未启动,则会出现此错误。
鉴于相同的错误被用于涵盖众多问题,不一定清楚数据库未准备就绪,而不是到达它的某些设置不正确。