Config Edeliver build in docker and deploy as docker?

I am looking at using the new edeliver Docker features

building locally in Docker is relatively easy, great, easy peasy.


Build as a docker container I am unsure of

I am stuck on the .edeliver/config needed build a production image to a private repo on dockerhub

Is this a supported use case?

If you use a private repo, you must be authenticated at your local docker daemon, e.g. using docker login with user name and password or e.g. gcloud auth login for a private google container registry. No further configuration should be needed in the .edeliver/config, it just allows edeliver to push the local image if the --push flag is set. The local image can always be built without authentication, it is only required when pushing it to a private repo.

1 Like

thanks for replying


#!/usr/bin/env bash

# .deliver/config
APP="myapp" # name of your release
BUILD_HOST="docker" # host where to build the release
BUILD_USER="root" # local user at build host
BUILD_AT="/opt/myapp/builds" # build directory on build host

when I run
local machine

docker login
mix edeliver build release --push

errors with

----> Pusing release image to registry
"docker push" requires exactly 1 argument.
See 'docker push --help'.
Usage:  docker push [OPTIONS] NAME[:TAG]
Push an image or a repository to a registry
Command 'docker push '
failed with status code 1!
Error output is displayed above.
Stopping build container 534fbafd297732980f88e987d6d97f146f204027928d6c7991b4745ed9877b8d

Thanks for providing your config.
edeliver provides two new docker features:

  1. building in a docker container, which makes the need of a build host obsolete and …
  2. building a docker image which contains the release and can run the release as a docker container.

For building (1.) you need to set the BUILD_HOST="docker" and optionally the DOCKER_BUILD_IMAGE which will be pulled an used to build the release, similar to a build host, which you did correctly.

If you also want to embed your built release into a docker image (2.), you need to tell edeliver to use a docker registry as release store and set it e.g. like this:

Edeliver then pulls a (runtime) base image from DOCKER_RELEASE_BASE_IMAGE (which defaults to edeliver/release-base:1.0), copies the release into it and commits a new docker image as niccolox/functionalelixir-release:<release-version>-<git-rev> which can be pushed manually to the registry or automatically with the --push flag. This is the image which can be deployed and started on your hosts.

These are two new but separate edeliver docker features, building in a container instead of on a build host and embedding the release into a docker image which also can be used independently. So in short:

  1. building in docker: BUILD_HOST="docker" and optional DOCKER_BUILD_IMAGE, which defaults to elixir:1.13.3 and needs to contain all build tools

  2. building as docker image: RELEASE_STORE="docker://<your-registry>" and an optional DOCKER_RELEASE_BASE_IMAGE, which needs to contain only the runtime requirements. E.g. the edeliver default release base image looks like this:

FROM ubuntu:focal-20220113

RUN apt update \
 && apt install -y libssl1.1 locales \
 && apt clean

RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && locale-gen

I will add a warning that --push will fail without a release store being configured as a docker registry instead of showing the misleading error above.

1 Like

cool, thanks for this, I get local build inside the container and then released to a container like this below

On my Ubuntu 20 laptop, it begins

docker -v
Docker version 20.10.7, build 20.10.7-0ubuntu5~20.04.2
niccolox@niccolox-xps:~/Projects/my-phx-app$ docker image ls
niccolox@niccolox-xps:~/Projects/my-phx-app$ docker ps

in Phoenix project with .config/edeliver

#!/usr/bin/env bash
# .deliver/config

APP="mycoolapp" # name of your release


BUILD_HOST="docker" # host where to build the release
BUILD_USER="root" # local user at build host
BUILD_AT="/opt/mycoolapp/builds" # build directory on build host


when I run mix edeliver

mix edeliver build release --push

I get success below

-----> Removing build container
niccolox@niccolox-xps:~/Projects/phx-app$ docker ps --all
CONTAINER ID   IMAGE                       COMMAND   CREATED          STATUS    PORTS     NAMES
2f71f8853bc4   edeliver/release-base:1.0   "bash"    54 minutes ago   Created             serene_engelbart
niccolox@niccolox-xps:~/Projects/phx-app$ docker image ls
REPOSITORY                          TAG             IMAGE ID       CREATED          SIZE
niccolox/functionalelixir-release   0.1.0-ea635b6   541ab1860e57   54 minutes ago   312MB
niccolox/functionalelixir-release   0.1.0-latest    541ab1860e57   54 minutes ago   312MB
niccolox/functionalelixir-release   0.1.0-master    541ab1860e57   54 minutes ago   312MB
niccolox/functionalelixir           latest          668de37ba999   2 days ago       848MB
edeliver/release-base               1.0             f5266b26ceda   8 weeks ago      131MB

Open questions

  1. how do I push to Dockerhub (I’ll experiment with that next)
  2. would you consider using Debian Slim rather than Ubuntu Focal as your echo release image? I think the Elixir images use Debian and not Ubuntu
  3. would you consider adding NodeJS 16 TLS to your echo image? Unfortunately its practically impossible to not use NodeJS

Thanks again, I’ll focus on deployment to Dockerhub next

actually, the configuration above does push the release image to dockerhub

docker login
mix edeliver build release --push


big thank you @bharendt

thanks for your work on edeliver docker and also thanks for your help getting a working config

1 Like

@niccolox I added a wiki page about building and using docker releases with edeliver, maybe the deploying and running sections could be helpful to proceed with the docker release.

To your questions:

Yes, makes sense to use a very basic and small image as release base image, thanks for the suggestion. Maybe alpine is even smaller and we could also provide also a small set of images which can be used as DOCKER_RELEASE_BASE_IMAGE.

If node js is a build requirement you can use any existing public docker image with node js and erlang + elixir as DOCKER_BUILD_IMAGE or build your own one. It don’t have to be pushed, just needs to be available locally when the release is built.

1 Like

thanks again for working with me on this

I think working examples of config for the 2 or 3 scenarios you outlined are extremely useful and an important complement to the general explanation you give.

please give me some time to unpack your responses

1 Like