【问题标题】:Docker-compose : Postgresql ECONNREFUSEDDocker-compose:Postgresql ECONNREFUSED
【发布时间】:2020-02-22 23:24:11
【问题描述】:

今天我尝试对一个完整的应用程序(前端、API 和数据库)进行 docker 化,以便可以将其部署在本地机器或/和虚拟机上。

做的时候:

docker-compose up

当我尝试使用以下环境变量启动将连接到数据库的 API(它在后台使用 Sequelize)时,我得到了“连接 ECONNREFUSED”:

DATABASE_URL: "postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-jy95}@db:5432/${POSTGRES_DB:-sourcecode}"

docker docs,据说:

现在每个容器都可以查找主机名 web 或 db 并取回 合适的容器的 IP 地址。例如,Web 的应用程序 代码可以连接到 URL postgres://db:5432 并开始使用 Postgres 数据库。

PostgreSQL docs中,我们可以看到postgresql://也是有效的:

The URI scheme designator can be either postgresql:// or postgres://. Each of the URI parts is optional.

这是我的完整 docker-compose.yml 文件:

version: '3.7'
services:
  frontend:
    image: jy95/sourcecode-front
    restart: always
    depends_on:
      - api
    ports:
      - "80:3000"
      - "443:3000"
    environment:
      API_SERVER: "api:8080"
      CDN_SERVER: "api:8080/files"
  api:
    image: jy95/sourcecode_api
    restart: always
    ports:
      - "8080:3000"
    depends_on:
      - db
    environment:
      DATABASE_URL: "postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-jy95}@db:5432/${POSTGRES_DB:-sourcecode}"
      # use a env file if you want to use other values that default ones
      # https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option
  db:
    image: postgres:12-alpine
    restart: always
    ports:
      - "5432:5432"
    environment:
      # use a env file for that part later
      # https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: jy95
      POSTGRES_DB: sourcecode
      POSTGRES_PORT: 5432
      # If we want to access more easily to the database (not recommended)
      # PGDATA: /var/lib/postgresql/data/pg_data
    #volumes:
    #  - pg_data:/var/lib/postgresql/data/pg_data

提前感谢您的帮助

PS:镜像已经在 Docker Hub 上

【问题讨论】:

  • 请您尝试使用实际值而不是变量(例如${POSTGRES_PASSWORD:-jy95}),例如DATABASE_URL=pgsql://test:test@postgresql:5432/test_db。您可以在终端中将其导出以测试export DATABASE_URL...
  • 如果应用程序在数据库完全启动之前尝试连接,就会发生这种情况。只运行docker-compose up,没有其他选项,然后观察错误消息;应用程序连接错误后是否有数据库消息出现?
  • @DavidMaze 这是我使用的命令(如我所见,我使用“depends_on”来确保在 API 之前需要数据库)。错误是:SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:5432 我不明白:docker 文档不是最新的?

标签: postgresql docker docker-compose sequelize.js


【解决方案1】:

您的评论实际上是一个很大的线索: “这是我使用的命令(如我所见,我使用“depends_on”来确保在 API 之前需要数据库)。错误是:SequelizeConnectionRefusedError: connect ECONNREFUSED 127.0.0.1:5432 我不明白: docker 文档不是最新的?”

看起来您的 api 容器正在尝试发送到 localhost 而不是 db:5432 (正如您所指出的 db 是 DNS 名称,它不太可能解析为 127.0.0.1(IP 保留给 localhost)

快速调试: 跑: docker exec -it sh (在容器中) apk 添加busybox-extras 进而: telnet 127.0.0.1 5432 -> 你会看到这是不可达的 然而 telnet db 5432 -> 这很好 此外,您可以运行 nslookup db -> 因为我们已经建立了这个 dns 名称(db)应该是可解析的

我尝试将 network_mode: host 添加到 api(在 docker-compose.yml 中),但这会导致您的应用程序崩溃。 在这一点上,我建议查看 api 的代码并查找对 127.0.0.1:5432 的任何引用 如果你运行 docker exec -it sh 进而: 打印环境 您将看到 DB_URL 环境变量设置为: postgresql://postgres:jy95@db:5432/sourcecode 但是您确定api使用了这个ENV-VAR吗? (也许您已经通过示例注释了一些代码并且您仍在使用不同的连接字符串)

【讨论】:

  • 确实很奇怪:在我的dockerfile 中,我将 NODE_ENV 设置为生产环境,以强制Sequelize 加载this variable
  • 容器内的 printenv 显示 NODE_ENV 设置为生产。如果是这种情况,那么可能会尝试启用日志记录,并在启动时记录实际的环境(const env)。您可以使用 docker-compose logs -f -t 查看日志
  • 这怎么可能?显而易见,通过您的测试(顺便提前感谢),即使按照我的指示将此变量设置为生产环境,它似乎也采用默认值(“开发”)......
  • 对于遇到此问题的任何人,只需将其添加到您的 docker-compose “环境:NODE_ENV:生产”中(即使您像我一样在 dockerfile 中将 NODE_ENV 设置为生产)
猜你喜欢
  • 2022-10-15
  • 2020-04-21
  • 1970-01-01
  • 2019-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多