Last active
April 25, 2022 21:05
-
-
Save linkdd/cd6b0fa44a50563107b31f43c2369120 to your computer and use it in GitHub Desktop.
Example of Dockerfile for an Elixir application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
FROM elixir:1.12-alpine AS builder | |
ARG BUILD_ENV=prod | |
ARG BUILD_REL=my_app | |
# Install system dependencies | |
RUN mix local.hex --force | |
RUN mix local.rebar --force | |
# Add sources | |
ADD . /workspace/ | |
WORKDIR /workspace | |
ENV MIX_ENV=${BUILD_ENV} | |
# Fetch dependencies | |
RUN mix deps.get | |
# Build project | |
RUN mix compile | |
# Run test-suite | |
RUN mix test --cover | |
# Build release | |
RUN mix release ${BUILD_REL} | |
FROM alpine:latest AS runner | |
ARG BUILD_ENV=prod | |
ARG BUILD_REL=my_app | |
# Install system dependencies | |
RUN apk add --no-cache openssl ncurses-libs libgcc libstdc++ | |
# Install release | |
COPY --from=builder /workspace/_build/${BUILD_ENV}/rel/${BUILD_REL} /opt/myapp | |
## Configure environment | |
# We want a FQDN in the nodename | |
ENV RELEASE_DISTRIBUTION="name" | |
# This value should be overriden at runtime | |
ENV RELEASE_IP="127.0.0.1" | |
# This will be the basename of our node | |
ENV RELEASE_NAME="${BUILD_REL}" | |
# This will be the full nodename | |
ENV RELEASE_NODE="${RELEASE_NAME}@${RELEASE_IP}" | |
# If empty, the default cookie generated by `mix release` will be used | |
# OVERRIDE IT!! | |
ENV RELEASE_COOKIE="" | |
ENTRYPOINT ["/opt/myapp/bin/${BUILD_REL}"] | |
CMD ["start"] |
also just fyi: your method of pulling in files can pull in cross-compiled assests if docker host env is different from target env
Hi,
I'll have to check tomorrow for the ENTRYPOINT issue, I usually use a launcher.sh script which uses the RELEASE_NAME
environment variable, so I'm not sure if the ARG is expanded or not.
For the cross-compiled assets, it's not a worry, I use a .dockerignore
file to filter out those assets.
The launcher.sh
script:
#!/bin/sh
set -e
DEFAULT_COOKIE="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 128 | head -n 1)"
export RELEASE_COOKIE="${RELEASE_COOKIE:-"$DEFAULT_COOKIE"}"
export RELEASE_NODE_IP="${RELEASE_NODE_IP:-"127.0.0.1"}"
export RELEASE_DISTRIBUTION="name"
export RELEASE_NODE="${RELEASE_NAME}@${RELEASE_NODE_IP}"
exec /opt/myapp/bin/${RELEASE_NAME} $@
The .dockerignore
:
# The directory Mix will write compiled artifacts to.
/_build/
# If you run "mix test --cover", coverage assets end up here.
/cover/
# The directory Mix downloads your dependencies sources to.
/deps/
# Where third-party dependencies like ExDoc output generated docs.
/doc/
# Ignore .fetch files in case you like to edit your project deps locally.
/.fetch
# If the VM crashes, it generates a dump, let's ignore it too.
erl_crash.dump
# Also ignore archive artifacts (built via "mix archive.build").
*.ez
# Ignore package tarball (built via "mix hex.build").
myapp-*.tar
# Temporary files for e.g. tests
/tmp
# Dockerfiles
/docker/
# some more files depending on the project...
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
doesn't this just hardcode "/opt/myapp/bin/${BUILD_REL}" into the entrypoint ( ie there is no shell ENV evaluation done when setting entrypoint)