I have a Phoenix 1.6 app deployed on fly.io, I followed the official guides by fly and the new 1.6 docs to deploy to fly.io. I have also integrated tailwindcss
and custom fonts on the pipeline. The deploy fails at assets.deploy
because it then checks for runtime secrets that are not present in the builder that fly.io uses.
Here is my Dockerfile
###
### Fist Stage - Building the Release
###
FROM hexpm/elixir:1.12.1-erlang-24.0.1-alpine-3.13.3 AS build
# install build dependencies
RUN apk add --no-cache build-base npm
# prepare build dir
WORKDIR /app
# extend hex timeout
ENV HEX_HTTP_TIMEOUT=20
# install hex + rebar
RUN mix local.hex --force && \
mix local.rebar --force
# set build ENV as prod
ENV MIX_ENV=prod
ENV SECRET_KEY_BASE=nokey
# Copy over the mix.exs and mix.lock files to load the dependencies. If those
# files don't change, then we don't keep re-fetching and rebuilding the deps.
COPY mix.exs mix.lock ./
COPY config config
RUN mix deps.get --only prod && \
mix deps.compile
# install npm dependencies
COPY assets/package.json assets/package-lock.json ./assets/
RUN npm --prefix ./assets ci --progress=false --no-audit --loglevel=error
COPY priv priv
COPY assets assets
# NOTE: If using TailwindCSS, it uses a special "purge" step and that requires
# the code in `lib` to see what is being used. Uncomment that here before
# running the npm deploy script if that's the case.
COPY lib lib
# build assets
# RUN npm run --prefix ./assets deploy
# RUN mix phx.digest
RUN mix assets.deploy
# copy source here if not using TailwindCSS
COPY lib lib
# compile and build release
COPY rel rel
RUN mix do compile, release
###
### Second Stage - Setup the Runtime Environment
###
# prepare release docker image
FROM alpine:3.13.3 AS app
RUN apk add --no-cache libstdc++ openssl ncurses-libs
WORKDIR /app
RUN chown nobody:nobody /app
USER nobody:nobody
COPY --from=build --chown=nobody:nobody /app/_build/prod/rel/indie_paper ./
ENV HOME=/app
ENV MIX_ENV=prod
ENV SECRET_KEY_BASE=nokey
ENV PORT=4000
CMD ["bin/indie_paper", "start"]
Here is my runtime config file
if config_env() == :prod do
database_url =
System.get_env("DATABASE_URL") ||
raise "
environment variable DATABASE_URL is missing.
For example: ecto://USER:PASS@HOST/DATABASE
"
config :indie_paper, IndiePaper.Repo,
# ssl: true,
socket_options: [:inet6],
url: database_url,
pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")
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
"
app_name =
System.get_env("FLY_APP_NAME") ||
raise "FLY_APP_NAME not available"
config :indie_paper, IndiePaperWeb.Endpoint,
server: true,
url: [host: "#{app_name}.fly.dev", port: 80],
http: [
ip: {0, 0, 0, 0, 0, 0, 0, 0},
port: String.to_integer(System.get_env("PORT") || "4000")
],
secret_key_base: secret_key_base
Here is my updated parts of the mix.exs
file
defp aliases do
[
setup: ["deps.get", "ecto.setup", "cmd --cd assets npm install"],
"ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
"ecto.reset": ["ecto.drop", "ecto.setup"],
test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"],
"assets.deploy": [
"cmd --cd assets npm run deploy",
"esbuild default --minify",
"phx.digest"
]
]
end
The build command fails at esbuild
during the build phase with the following error. This might be because fly.io uses a separate build machine that builds the image and then pushes it onto the machine with the secrets. How do I fix this ?
Step 16/30 : RUN mix assets.deploy
---> Running in c2f024ff203d
> @ deploy /app/assets
> NODE_ENV=production postcss css/app.css -o ../priv/static/assets/app.css
warn - You have enabled the JIT engine which is currently in preview.
warn - Preview features are not covered by semver, may introduce breaking changes, and can change at any time.
Compiling 34 files (.ex)
Generated indie_paper app
** (RuntimeError) environment variable DATABASE_URL is missing.
For example: ecto://USER:PASS@HOST/DATABASE
(stdlib 3.15) erl_eval.erl:685: :erl_eval.do_apply/6
(stdlib 3.15) erl_eval.erl:446: :erl_eval.expr/5
(stdlib 3.15) erl_eval.erl:123: :erl_eval.exprs/5
(elixir 1.12.1) lib/code.ex:656: Code.eval_string_with_error_handling/3
(elixir 1.12.1) lib/config.ex:258: Config.__eval__!/3
(elixir 1.12.1) lib/config/reader.ex:86: Config.Reader.read!/2
Error error building: error rendering build status stream: The command '/bin/sh -c mix assets.deploy' returned a non-zero code: 1
If I disable the esbuild
step the deployment succeeds.