Hello. I’m new to Docker and am trying to create docker containers of phoenix. I use docker-compose.yml
for creating 2 containers, application one and postgres one.
This is my docker-compose.yml
version: '3'
networks:
backend:
driver: bridge
services:
db:
build: ./dockerfiles/db
volumes:
- ./volumes/db/data:/var/lib/postgresql/0.1.0
ports:
- 5432:5432
environment:
- POSTGRES_DB=milk
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
restart: always
tty: true
networks:
- backend
app:
build:
dockerfile: ./dockerfiles/app/Dockerfile
context: .
command: "bin/milk start"
environment:
- DATABASE_URL=ecto://postgres:postgres@db/milk
- SECRET_KEY_BASE=KL6jdYa8VzDIg1TjqQcGZsaGSnd43grQYWrl95dYjn/SJB7KABj7N4BWgaCxSF81
ports:
- 4000:4000
tty: true
networks:
- backend
and these are Dockerfile
s.
dockerfiles/app/Dockerfile
FROM elixir:1.9.4-alpine AS build
RUN apk add --no-cache build-base npm git python
WORKDIR /app
RUN mix local.hex --force && \
mix local.rebar --force
ENV MIX_ENV=prod
COPY mix.exs mix.lock ./
COPY config config
RUN mix do deps.get, deps.compile
COPY priv priv
COPY lib lib
COPY rel rel
RUN mix compile
RUN mix ecto.create
RUN mix ecto.migrate
RUN mix release
FROM alpine:3.9 AS app
RUN apk add --no-cache openssl ncurses-libs
WORKDIR /app
RUN chown nobody:nobody /app
USER nobody:nobody
COPY --from=build --chown=nobody:nobody /app/_build/prod/rel/milk ./
ENV HOME=/app
CMD ["bin/milk", "start"]
dockerfiles/db/Dockerfile
FROM postgres:13.0-alpine
CMD ["postgres"]
EXPOSE 5432
I have changed the hostname
localhost to db, and changed the database config in config/
directory.
config/prod.exs
use Mix.Config
# For production, don't forget to configure the url host
# to something meaningful, Phoenix uses this information
# when generating URLs.
#
# Note we also include the path to a cache manifest
# containing the digested version of static files. This
# manifest is generated by the `mix phx.digest` task,
# which you should run after static files are built and
# before starting your production server.
config :milk, MilkWeb.Endpoint,
http: [port: {:system, "PORT"}],
url: [host: "localhost", port: 4000],
#cache_static_manifest: "priv/static/cache_manifest.json",
server: true,
root: ".",
version: Application.spec(:milk, :vsn)
# Do not print debug messages in production
config :logger, level: :info
config :milk, Milk.Repo,
username: "postgres",
password: "postgres",
database: "milk",
hostname: "db",
show_sensitive_data_on_connection_error: true,
pool_size: 10
# ## SSL Support
#
# To get SSL working, you will need to add the `https` key
# to the previous section and set your `:url` port to 443:
#
# config :milk, MilkWeb.Endpoint,
# ...
# url: [host: "example.com", port: 443],
# https: [
# :inet6,
# port: 443,
# cipher_suite: :strong,
# keyfile: System.get_env("SOME_APP_SSL_KEY_PATH"),
# certfile: System.get_env("SOME_APP_SSL_CERT_PATH")
# ]
#
# The `cipher_suite` is set to `:strong` to support only the
# latest and more secure SSL ciphers. This means old browsers
# and clients may not be supported. You can set it to
# `:compatible` for wider support.
#
# `:keyfile` and `:certfile` expect an absolute path to the key
# and cert in disk or a relative path inside priv, for example
# "priv/ssl/server.key". For all supported SSL configuration
# options, see https://hexdocs.pm/plug/Plug.SSL.html#configure/1
#
# We also recommend setting `force_ssl` in your endpoint, ensuring
# no data is ever sent via http, always redirecting to https:
#
# config :milk, MilkWeb.Endpoint,
# force_ssl: [hsts: true]
#
# Check `Plug.SSL` for all available options in `force_ssl`.
# Finally import the config/prod.secret.exs which loads secrets
# and configuration from environment variables.
# import_config "prod.secret.exs"
config/config.exs
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
#
# This configuration file is loaded before any dependency and
# is restricted to this project.
# General application configuration
use Mix.Config
config :milk, ecto_repos: [Milk.Repo]
# Configures the endpoint
config :milk, MilkWeb.Endpoint,
url: [host: "localhost"],
secret_key_base: "EBeu358sy8Bi+OLxOAee44nMrRCj/iwRKq5NUls46hBMwnqVhNOhl7qcw0d1REjZ",
render_errors: [view: MilkWeb.ErrorView, accepts: ~w(html json)]
# Configures Elixir's Logger
config :logger, :console,
format: "$time $metadata[$level] $message\n",
metadata: [:request_id]
# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason
# Import environment specific config. This must remain at the bottom
# of this file so it overrides the configuration defined above.
import_config "#{Mix.env()}.exs"
config :milk, Milk.UserManager.Guardian,
issuer: "milk",
secret_key: "ucwM9beYUEgWdkHoZ5kXflOMW8wZSEVwheR3PuUVROQrl3uymZL/qtRbHs+V3BN4",
serializer: Milk.UserManager.GuardianSerializer,
ttl: {24, :hour}
config :milk, Milk.UserManager.Pipeline,
module: Milk.UserManager.Guardian,
error_handler: Milk.UserManager.ErrorHandler
config/release.exs
# In this file, we load production configuration and secrets
# from environment variables. You can also hardcode secrets,
# although such is generally not recommended and you have to
# remember to add this file to your .gitignore.
import Config
database_url =
System.get_env("DATABASE_URL") ||
raise """
environment variable DATABASE_URL is missing.
For example: ecto://USER:PASS@HOST/DATABASE
"""
config :milk, Milk.Repo,
adapter: Ecto.Adapters.Postgres,
#ssl: true,
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
database: "milk"
secret_key_base =
System.get_env("SECRET_KEY_BASE") ||
raise """
environment variable SECRET_KEY_BASE is missing.
You can generate one by calling: mix phx.gen.secret
"""
config :milk, MilkWeb.Endpoint,
http: [:inet6, port: String.to_integer(System.get_env("PORT") || "4000")],
secret_key_base: secret_key_base
# ## Using releases (Elixir v1.9+)
#
# If you are doing OTP releases, you need to instruct Phoenix
# to start each relevant endpoint:
#
# config :milk, MilkWeb.Endpoint, server: true
#
# Then you can assemble a release by calling `mix release`.
# See `mix help release` for more information.
With those files, I got an error when I attempt running docker-compose build
.
Step 13/23 : RUN mix ecto.create
---> Running in 760fc7c73107
14:40:27.994 [error] GenServer #PID<0.271.0> terminating
** (DBConnection.ConnectionError) tcp connect (db:5432): non-existing domain - :nxdomain
(db_connection) lib/db_connection/connection.ex:87: DBConnection.Connection.connect/2
(connection) lib/connection.ex:622: Connection.enter_connect/5
(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: nil
** (Mix) The database for Milk.Repo couldn't be created: killed
ERROR: Service 'app' failed to build : The command '/bin/sh -c mix ecto.create' returned a non-zero code: 1
Concerning docker-compose, I think the host (db:5432) is correct. But my terminal shows an error.
I don’t know where to fix at all. Help me!