The problem was that I was using System.fetch_env!/1
, so all env vars weren’t loading on compile time… Changing to System.get_env/2
solved the issue!
However I’m getting two new problem now:
1 - When I create a release with MIX_ENV=prod mix release
and then run _build/prod/rel/conts/bin/conts eval Conts.Release.migrate
I get the following error:
** (RuntimeError) connect raised KeyError exception: key :database not found.
This is my runtime.exs
:
import Config
secret_key_base = System.get_env("SECRET_KEY_BASE")
session_cookie_name = System.get_env("SESSION_COOKIE_NAME")
session_cookie_signing_salt = System.get_env("SESSION_COOKIE_SIGNING_SALT")
session_cookie_encryption_salt = System.get_env("SESSION_COOKIE_ENCRYPTION_SALT")
app_port = String.to_integer(System.get_env("PORT", "4000"))
app_hostname = System.get_env("HOST", "localhost")
db_url = System.get_env("DB_URL")
pool_size = String.to_integer(System.get_env("POOL_SIZE", "10"))
config :conts, Conts.Repo,
adapter: Ecto.Adapters.Postgres,
url: db_url,
pool_size: pool_size,
ssl: false
config :conts, ContsWeb.Endpoint,
load_from_system_env: true,
http: [:inet6, port: {:system, "PORT"}],
secret_key_base: secret_key_base,
session_cookie_name: session_cookie_name,
session_cookie_signing_salt: session_cookie_signing_salt,
session_cookie_encryption_salt: session_cookie_encryption_salt
config :conts,
app_port: app_port
config :conts,
app_hostname: app_hostname
The strange part is that if I set :show_sensitive_data_on_connection_error
to true, this is the output:
** (KeyError) key :database not found in: [pool_index: 1, types: Postgrex.DefaultTypes, hostname: "localhost", username: "matthew", port: 5432, repo: Conts.Repo, telemetry_prefix: [:conts, :repo], otp_app: :conts, timeout: 15000, adapter: Ecto.Adapters.Postgres, show_sensitive_data_on_connection_error: true, ssl: false, pool_size: 2, pool: DBConnection.ConnectionPool]
Why the :username
is getting my system’s username? I don’t even set that anywhere…
2 - When I run mix test
, I got this error on controllers: ** (ArgumentError) cookie store expects conn.secret_key_base to be set
However, on test env
the secret_key_base
wasn’t set by default?
this is my 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 :conts,
ecto_repos: [Conts.Repo],
generators: [binary_id: true]
# Configures the endpoint
config :conts, ContsWeb.Endpoint,
url: [host: "localhost"],
secret_key_base: "JqlSibgU/Ykrwvzz1ByJn2xayNDJlXkuBzmqHIW2yILDXSI3IHB2VbTqde/sIQw4",
render_errors: [view: ContsWeb.ErrorView, accepts: ~w(html json), layout: false],
pubsub_server: Conts.PubSub,
live_view: [signing_salt: "LvrsHaeP"]
# 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
if Mix.env() != :prod do
config :git_hooks,
auto_install: true,
verbose: true,
hooks: [
pre_commit: [
tasks: [
{:cmd, "mix format"},
{:cmd, "mix credo --strict"}
]
],
pre_push: [
verbose: false,
tasks: [
{:cmd, "mix dialyzer"},
{:cmd, "mix test"},
{:cmd, "echo 'success!'"}
]
]
]
end
# Mailing configs
email_domain = "boosting.tech"
config :conts, Conts.Mailing,
adapter: Bamboo.LocalAdapter,
open_email_in_browser_url: "http://localhost:4000/sent_emails"
# Pow
config :conts, :pow,
user: Conts.Accounts.User,
repo: Conts.Repo,
extensions: [PowResetPassword, PowEmailConfirmation],
web_module: ContsWeb,
controller_callbacks: Pow.Extension.Phoenix.ControllerCallbacks,
mailer_backend: Conts.Mailing,
web_module_mailer: Conts
# Conts custom configs
config :conts, mailing_default_from_name: "Sistema Conts"
config :conts, mailing_default_from_email: "noreplyconts@boosting.tech"
# 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"
Other files:
Dockerfile
:
# Set global arg for multistage
ARG DB_URL
FROM elixir:1.11.2-alpine AS builder
RUN apk add --no-cache yarn build-base
RUN mkdir /app
WORKDIR /app
ARG DB_URL
ARG SECRET_KEY_BASE
ARG SESSION_COOKIE_NAME
ARG SESSION_COOKIE_SIGNING_SALT
ARG SESSION_COOKIE_ENCRYPTION_SALT
# Mix env
ENV MIX_ENV=prod \
DB_URL=$DB_URL \
SECRET_KEY_BASE=$SECRET_KEY_BASE \
SESSION_COOKIE_NAME=$SESSION_COOKIE_NAME \
SESSION_COOKIE_SIGNING_SALT=$SESSION_COOKIE_SIGNING_SALT \
SESSION_COOKIE_ENCRYPTION_SALT=$SESSION_COOKIE_ENCRYPTION_SALT
# Cache elixir deps
ADD mix.exs mix.lock ./
RUN mix local.rebar
RUN mix local.hex --force
RUN mix do deps.get, deps.compile
# Same with node deps
COPY assets assets
RUN yarn --cwd assets
COPY lib lib
COPY config config
COPY priv priv
# Run frontend build, compile, and digest assets
RUN yarn --cwd assets deploy && \
cd - && \
mix do compile, phx.digest
RUN mix release
# ---- Application Stage ----
FROM alpine AS app
ARG DB_URL
ENV MIX_ENV=prod \
DB_URL=$DB_URL \
SHELL=/bin/fish
# Intall needed packages
RUN apk --no-cache upgrade && \
apk add --no-cache openssl \
ncurses-libs postgresql-client fish
# Copy over the build artifact from the previous step and create a non root user
RUN adduser -D -h /home/app app
WORKDIR /home/app
COPY --from=builder /app/_build .
RUN chown -R app: ./prod
USER app
COPY entrypoint.sh .
# Run the Phoenix app
CMD ["./entrypoint.sh"]
entrypoint.sh
:
#!/bin/sh
# Docker entrypoint script.
# Wait until Postgres is ready
while ! pg_isready -q -d $DB_URL
do
echo "$(date) - waiting for database to start"
sleep 2
done
echo "Connected to the database"
./prod/rel/conts/bin/conts eval Conts.Release.migrate
./prod/rel/conts/bin/conts start