Last active
July 3, 2017 11:27
-
-
Save ellispritchard/fcd15c97be4f83ec66e7d74c6a8793e3 to your computer and use it in GitHub Desktop.
Mix task to build docker image, and supporting files
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
defmodule Mix.Tasks.Docker.Build do | |
use Mix.Task | |
@shortdoc "Prepare a docker release image" | |
@moduledoc """ | |
Runs system-independent tasks, such as npm install, and then builds a tagged docker image. | |
## Configuration | |
Add the `docker` configuration to your Mix.Project to specify the target `repo`; the | |
image will be tagged with the repo and `Mix.Project.version`: | |
``` | |
def project do | |
[app: :myapp, | |
version: "0.0.1", | |
docker: [repo: "nexus.in.ft.com:5000/group/myapp"], | |
...] | |
end | |
``` | |
This would create an image tagged with `nexus.in.ft.com:5000/group/myapp:0.0.1` | |
You can override the repo using the `--repo` parameter, or the the whole image tag using `--tag` | |
parameter, or just the version using `--version`, e.g. | |
``` | |
mix docker.build --tag nexus.in.ft.com:5000/group/myapp:1.0.1 | |
# is same as | |
mix docker.build --repo nexus.in.ft.com:5000/group/myapp --version 1.0.1 | |
``` | |
> Note that `--version` does not set the `Mix.Project.version`, just the docker tag. | |
""" | |
@switches [tag: :string, repo: :string, version: :string] | |
def run(args) do | |
config = Mix.Project.config[:docker] || [] | |
{opts, _argv} = OptionParser.parse!(args, strict: @switches) | |
version = opts[:version] || Mix.Project.config[:version] | |
tag = opts[:tag] | |
repo = config[:repo] || opts[:repo] || if(not tag, do: Mix.raise("Need project docker repo config, or --repo or --tag option")) | |
tag = case tag do | |
nil -> "#{repo}:#{version}" | |
tag -> tag | |
end | |
Mix.shell.info("Building image tagged with #{tag} version #{version}") | |
with pwd <- System.cwd!(), | |
release_dir <- "#{pwd}/.docker.build", | |
{:ok, _} <- File.rm_rf(release_dir), | |
:ok <- File.mkdir_p(release_dir), | |
:ok <- Mix.Task.run("deps.get"), | |
0 <- Mix.shell.cmd("cd assets && npm install && ./node_modules/.bin/brunch build --production"), | |
0 <- Mix.shell.cmd("mix phx.digest"), | |
{uid, 0} <- System.cmd("id", ["-u"]), | |
{gid, 0} <- System.cmd("id", ["-g"]), | |
chown <- String.trim(uid) <> ":" <> String.trim(gid), | |
0 <- Mix.shell.cmd("docker run --rm -v #{pwd}:/project -v #{release_dir}:/release --env CHOWN=#{chown} --env MIX_ENV=docker --env APP_VERSION=#{version} nexus.in.ft.com:5000/membership/elixir-build:latest /project/rel/docker-build.sh"), | |
:ok <- File.cp("rel/Dockerfile", "#{release_dir}/Dockerfile"), | |
0 <- Mix.shell.cmd("cd #{release_dir} && docker build . -t #{tag}") do | |
Mix.shell.info("Built docker image #{tag}.") | |
else | |
code -> Mix.shell.error("Build failed: #{inspect code}") | |
end | |
end | |
end |
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
environment :docker do | |
set dev_mode: false | |
set include_erts: true | |
set include_src: false | |
set cookie: :crypto.hash(:sha256, :crypto.rand_bytes(25)) |> Base.encode16 |> String.to_atom | |
set output_dir: "/release" | |
end |
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
#!/bin/ash | |
# Used to do build inside Docker build container | |
cd /project | |
mix release --env=${MIX_ENV} | |
if [ "${CHOWN}" ] ; then | |
# fix for CI where Docker runs as root | |
echo "chown-ing /project/_build/${MIX_ENV}" | |
chown -R ${CHOWN} /project/_build/${MIX_ENV} | |
echo "chown-ing /release/*" | |
chown -R ${CHOWN} /release/* | |
fi | |
du -hs /release |
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 alpine:3.6 | |
RUN apk --no-cache update && apk --no-cache upgrade && apk --no-cache add ncurses-libs | |
ENV REFRESHED_AT=2017-05-30 | |
RUN adduser -D app | |
WORKDIR /opt/app | |
COPY . . | |
USER app | |
# # Runtime Environment | |
RUN mkdir /tmp/myapp | |
ENV RELEASE_MUTABLE_DIR /tmp/myapp | |
ENV START_ERL_DATA /tmp/myapp/start_erl.data | |
CMD ["/opt/app/bin/myapp", "foreground"] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment