首页 > 解决方案 > Elixir + docker compose 与 postgres 的连接被拒绝

问题描述

您好,我在使用 elixir 连接到 postgres 时遇到问题,我在 docker-compose 上尝试了以下操作:

我使用了环境变量,但事实并非如此,所以我尝试将字符串放入 dev.exs,但即便如此它仍然拒绝连接。

我测试了我的 postgres,它工作正常,并且数据库创建了所有正确的日志:

postgres 数据库 | 2021-02-23 22:46:30.410 UTC [1] LOG:数据库系统已准备好接受连接

.env:

DB_NAME=spiritpay-dev
DB_USER=postgres
DB_HOST=localhost
DB_PASS=12345

码头工人撰写:

version: "3.7"
services:
  app:
      restart: on-failure
      environment: 
        DB_USER: postgres
        DB_PASSWORD: 12345
        DB_NAME: spiritpay-dev
        DB_HOST: postgres-db
      build: .
      command: /bin/sh docker-entrypoint.sh
      ports: 
        - "4000:4000"
      depends_on: 
        - postgres-db 
      links:
        - postgres-db
  postgres-db:
      image: "postgres:12"
      restart: always
      container_name: "postgres-db"
      environment: 
        POSTGRES_PASSWORD: ${DB_PASS}
        POSTGRES_USER: ${DB_USER}
        POSTGRES_DB: ${DB_NAME}
      ports: 
        - "5433:5433"

开发者.exs:

use Mix.Config

# Configure your database
config :spiritpay, Spiritpay.Repo,
  username: "postgres",
  password: "12345",
  database: "spiritpay-dev",
  hostname: "postgres-db",
  port: 5433,
  show_sensitive_data_on_connection_error: true,
  pool_size: 10

# For development, we disable any cache and enable
# debugging and code reloading.
#
# The watchers configuration can be used to run external
# watchers to your application. For example, we use it
# with webpack to recompile .js and .css sources.
config :spiritpay, SpiritpayWeb.Endpoint,
  http: [port: 4000],
  debug_errors: true,
  code_reloader: true,
  check_origin: false,
  watchers: []

# ## SSL Support
#
# In order to use HTTPS in development, a self-signed
# certificate can be generated by running the following
# Mix task:
#
#     mix phx.gen.cert
#
# Note that this task requires Erlang/OTP 20 or later.
# Run `mix help phx.gen.cert` for more information.
#
# The `http:` config above can be replaced with:
#
#     https: [
#       port: 4001,
#       cipher_suite: :strong,
#       keyfile: "priv/cert/selfsigned_key.pem",
#       certfile: "priv/cert/selfsigned.pem"
#     ],
#
# If desired, both `http:` and `https:` keys can be
# configured to run both http and https servers on
# different ports.

# Do not include metadata nor timestamps in development logs
config :logger, :console, format: "[$level] $message\n"

# Set a higher stacktrace during development. Avoid configuring such
# in production as building large stacktraces may be expensive.
config :phoenix, :stacktrace_depth, 20

# Initialize plugs at runtime for faster development compilation
config :phoenix, :plug_init_mode, :runtime

日志:

app_1 | 22:46:31.020 [错误] GenServer #PID<0.368.0> 终止 app_1 | ** (DBConnection.ConnectionError) tcp connect (postgres-db:5433): 连接被拒绝 - :econnrefused app_1
| (db_connection 2.3.1) lib/db_connection/connection.ex:100: DBConnection.Connection.connect/2 app_1 | (连接 1.1.0) lib/connection.ex:622: Connection.enter_connect/5 app_1 | (stdlib 3.14) proc_lib.erl:226: :proc_lib.init_p_do_apply/3 app_1 | 最后一条消息:无 app_1 | 状态:Postgrex.Protocol app_1 | **(混合)Spiritpay.Repo 的数据库无法删除:killed app_1 | [错误] Postgrex.Protocol (#PID<0.330.0>) 连接失败:** (DBConnection.ConnectionError) tcp connect (postgres-db:5433): connection denied - :econnrefused

标签: postgresqldockerelixir

解决方案


第 1 点:

尝试用 .env 中的 postgres-db 替换 localhost,因为您的数据库的主机就是这样。您 docker compose 将内部主机映射到服务名称

文档摘录:

默认情况下,Compose 会为您的应用程序设置一个网络。服务的每个容器都加入默认网络,并且可以被该网络上的其他容器访问,并且可以通过与容器名称相同的主机名被它们发现。

要点2:

.env添加到您的应用服务:

services:
  app:
      restart: on-failure
      build: .
      command: /bin/sh docker-entrypoint.sh
      ports: 
        - "4000:4000"
      depends_on: 
        - postgres-db 
      links:
        - postgres-db
      env_file:
         - .env

在上面的示例中,您的配置似乎使您在 3 个地方定义的环境变量

  • 在未使用的 .env 中
  • 在应用服务的环境部分
  • 在 dev.exs 中硬编码上述内容只会造成混乱和负担

dev.exs从环境加载配置

第3点

您使用的端口号错误 postgres 在其上运行5432

第 4 点:

您可以通过使用以下方式监听来自任何地方的连接来测试来自主机的连接0.0.0.0

    ports:
      - 0.0.0.0:5432:5432

然后您可以使用 netcat 在 localhost 上测试连接: nc -v localhost 5432


推荐阅读