Kaquadu1

Kaquadu1

Docker & Phoenix - failed to connect to Postgres, nxdomain

Hi guys! I decided to update OTP/Elixir version of my project. I have to switch from Alpine to Debian, because dart_sass has some problems with Alpine and the package I used for solving it is not working anymore. I managed to do the update almost smoothly however I really cannot make the application connect to the database. I’m getting an nxdomain error. I must miss something and I really can’t spot it. I would really appreciate if someone could take a look and help me finding where the mistake is.

[error] Postgrex.Protocol (#PID<0.3695.0>) failed to connect: ** (DBConnection.ConnectionError) tcp connect (postgres:5432): non-existing domain - :nxdomain

Docker compose

version: "3.8"

networks:
  default:
    driver: host

services:
  postgres:
    image: postgres:15
    ports:
      - '5432:5432'
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    expose:
      - '5432'
    restart: always
    networks:
      - default

  elixir:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - postgres
    environment:
      MIX_ENV: ${MIX_ENV}
      DATABASE_URL: ${DATABASE_URL}
      SECRET_KEY_BASE: ${SECRET_KEY_BASE}
      AWS_S3_ACCESS_KEY_ID: ${AWS_S3_ACCESS_KEY_ID}
      AWS_S3_SECRET_ACCESS_KEY: ${AWS_S3_SECRET_ACCESS_KEY}
      SENDGRID_API_KEY: ${SENDGRID_API_KEY}
      PORT: ${PORT}
    ports:
      - '4000:4000'
    expose:
      - '4000'
    networks:
      - default

env file

AUTOMATIC_LOGOUT_TIME="99999999999"
CLOSING_TABS_LOGOUT_TIME="99999"
AWS_S3_ACCESS_KEY_ID="some_key"
AWS_S3_SECRET_ACCESS_KEY="some_key"
AWS_S3_BUCKET="some_bucket"
MIX_ENV="dev"
FILE_UPLOAD_ENV="dev"
NODE_ENV="production"
HOST="localhost:4000"
SENDGRID_API_KEY="development_sengrid_api_key"
PORT="4000"
SECRET_KEY_BASE="some_key"
DATABASE_URL="postgres://postgres:postgres@postgres:5432/sample_dev"
POSTGRES_PASSWORD="postgres"
POSTGRES_USER="postgres"
POSTGRES_DB="sample_dev"
DATABASE_SSL="FALSE"

Dockerfile

ARG ELIXIR_VERSION=1.15.2
ARG ERLANG_VERSION=26.0.2
ARG DEBIAN_VERSION=20230612
ARG LINUX_VERSION=debian-bullseye-${DEBIAN_VERSION}-slim

#########################
# Stage: deps-assets    #
#########################
FROM hexpm/elixir:${ELIXIR_VERSION}-erlang-${ERLANG_VERSION}-${LINUX_VERSION} as deps-assets

RUN apt-get autoremove -y
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*

RUN apt update
RUN apt-get install -f
RUN apt-get install ca-certificates --assume-yes
RUN apt-get install nodejs --assume-yes
RUN apt-get install npm --assume-yes
RUN apt-get install git --assume-yes
RUN apt-get install gcc  --assume-yes
RUN apt-get install build-essential --assume-yes

ENV MIX_ENV=prod \
    MIX_HOME=/opt/mix \
    HEX_HOME=/opt/hex

WORKDIR /app

COPY . .

RUN mix local.rebar --force \
 && mix local.hex --if-missing --force \
 && mix do deps.get --only $MIX_ENV

WORKDIR /app/apps/sample_web/assets

RUN npm install

#########################
# Stage: release        #
#########################

FROM hexpm/elixir:${ELIXIR_VERSION}-erlang-${ERLANG_VERSION}-${LINUX_VERSION} as release

RUN apt-get autoremove -y
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*

RUN apt update
RUN apt-get install -f
RUN apt-get install git --assume-yes
RUN apt-get install gcc  --assume-yes
RUN apt-get install build-essential --assume-yes

ENV MIX_ENV=prod \
    MIX_HOME=/opt/mix \
    HEX_HOME=/opt/hex

WORKDIR /app

COPY . .

COPY --from=deps-assets /app/apps/sample_web/assets/ /app/apps/sample_web/assets/
COPY --from=deps-assets /app/apps/sample_web/priv/static/ /app/apps/sample_web/priv/static/
COPY --from=deps-assets /app/deps/ /app/deps/
COPY --from=deps-assets /app/apps/sample_web/assets/static/images/ /app/apps/sample_web/priv/static/images/
COPY --from=deps-assets /app/apps/sample_web/assets/fonts/ /app/apps/sample_web/priv/static/fonts

RUN mix local.rebar --force \
 && mix local.hex --if-missing --force \
 && mix do deps.get --only $MIX_ENV, deps.compile, assets.deploy

RUN mix release \
 && rm -rf /app/deps

#########################
# Stage: production     #
#########################
FROM debian:bullseye-${DEBIAN_VERSION}-slim as production

RUN apt-get autoremove -y
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*

RUN apt update
RUN apt-get install -f
RUN apt-get install openssl
RUN apt-get install gcc --assume-yes
RUN apt-get install build-essential --assume-yes

COPY --from=release /app/_build/prod/rel/sample_umbrella ./

RUN chmod +x /bin/*

CMD ["bin/sample_umbrella", "start"]

EXPOSE 4000

Runtime config:

import Config

defmodule Config.Helper do
  def get_env(env, default) when is_number(default) do
    value = System.get_env(env)

    if value do
      String.to_integer(value)
    else
      default
    end
  end

  def get_env(env, default) do
    value = System.get_env(env) || default
    "#{value}"
  end
end

if System.get_env("MIX_ENV") in ["dev", "prod", nil] do
  config :sample, Sample.Repo,
    ssl: System.get_env("DATABASE_SSL") == "TRUE",
    url: System.get_env("DATABASE_URL"),
    socket_options: [:inet6],
    pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
    stacktrace: System.get_env("MIX_ENV") == "dev",
    timeout: 30_000,
    show_sensitive_data_on_connection_error: System.get_env("MIX_ENV") == "dev"
end

if System.get_env("MIX_ENV") == "test" do
  # Configure your database
  config :sample, Sample.Repo,
    username: "postgres",
    password: "postgres",
    database: "sample_test",
    hostname: "localhost",
    pool: Ecto.Adapters.SQL.Sandbox
end

if System.get_env("MIX_ENV") in ["dev", nil] do
  config :sample_web, SampleWeb.Endpoint,
    check_origin: ["//#{System.get_env("HOST") || "//our_application_address"}"],
    http: [:inet6, port: System.get_env("PORT")],
    secret_key_base: System.get_env("SECRET_KEY_BASE"),
    server: true,
    root: ".",
    live_view: [signing_salt: System.get_env("LIVE_VIEW_SALT") || "Nbe6JYiR"],
    watchers: [
      sass: {
        DartSass,
        :install_and_run,
        [:default, ~w(--embed-source-map --source-map-urls=absolute --watch --quiet)]
      },
      admin_sass: {
        DartSass,
        :install_and_run,
        [:admin, ~w(--embed-source-map --source-map-urls=absolute --watch --quiet)]
      },
      esbuild: {Esbuild, :install_and_run, [:default, ~w(--sourcemap=inline --watch)]}
    ]
end

if System.get_env("MIX_ENV") == "prod" do
  config :sample_web, SampleWeb.Endpoint,
    check_origin: ["//#{System.get_env("HOST") || "our_application_address"}"],
    http: [:inet6, port: System.get_env("PORT")],
    url: [scheme: "https", host: System.get_env("HOST"), port: 443],
    force_ssl: [rewrite_on: [:x_forwarded_proto], hsts: true],
    cache_static_manifest: "priv/static/cache_manifest.json",
    secret_key_base: System.get_env("SECRET_KEY_BASE"),
    server: true,
    root: ".",
    live_view: [signing_salt: System.get_env("LIVE_VIEW_SALT") || "Nbe6JYiR"]
end

config :ex_aws,
  access_key_id: System.fetch_env!("AWS_S3_ACCESS_KEY_ID"),
  secret_access_key: System.fetch_env!("AWS_S3_SECRET_ACCESS_KEY")

config :sample_web, SampleWeb.Guardian,
  secret_key:
    System.get_env("GUARDIAN_SECRET_KEY") ||
      "sample_key"

config :sample, Sample.Mailer, api_key: System.fetch_env!("SENDGRID_API_KEY")

I use just plain

docker compose build

and

docker compose up

for launching it. The database service is up and running first, with a prompt: “ready to accept connections”.

Most Liked

hubertlepicki

hubertlepicki

I don’t quite remember how to configure netowkring in docker/ docker compose to make this particular thing work, but I suspect the issue is that the host ‘postgres’ is not being resolved from the container. Probably the easiest fix is to replace that line with

DATABASE_URL="postgres://postgres:postgres@localhost:5432/sample_dev"

Where Next?

Popular in Questions Top

Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
nobody
How to bind a phoenix app to a specific ip address? could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: The documentation above suggests that while ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 42920 311
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New

We're in Beta

About us Mission Statement