1
votes

Hello I have a problem connecting to postgres with the elixir, I tried the following on docker-compose:

I used environment variables, but it wasn’t so I tried putting string in dev.exs, but even then it still rejects the connection.

I tested my postgres and it works normally and has the database created all right log:

postgres-db | 2021-02-23 22:46:30.410 UTC [1] LOG: database system is ready to accept connections

.env:

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

docker-compose:

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"

dev.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

logs:

app_1 | 22:46:31.020 [error] GenServer #PID<0.368.0> terminating app_1 | ** (DBConnection.ConnectionError) tcp connect (postgres-db:5433): connection refused - :econnrefused app_1
| (db_connection 2.3.1) lib/db_connection/connection.ex:100: DBConnection.Connection.connect/2 app_1 | (connection 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 | Last message: nil app_1 | State: Postgrex.Protocol app_1 | ** (Mix) The database for Spiritpay.Repo couldn't be dropped: killed app_1 | [error] Postgrex.Protocol (#PID<0.330.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (postgres-db:5433): connection refused - :econnrefused

1

1 Answers

1
votes

Point 1:

Try replacing localhost by postgres-db in .env since the host of your database is that. You docker compose maps internal hosts to service names

Excerpt from the docs :

By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.

Point2:

add .env to your app service:

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

In the above example you configuration seems vake you your environment variables defined in 3 places

  • in .env which is not used
  • in environment section of app service
  • hardcoded in dev.exs the above will only create confusion and burden

in dev.exs load configuration from environment

Point3

the port number you use is wrong postgres operates on 5432

Point 4:

You can test connection from host machine by listening to connections from everywhere 0.0.0.0 using:

    ports:
      - 0.0.0.0:5432:5432

then you can test connection on localhost using netcat: nc -v localhost 5432