DockerBuild
Library for building docker images.
Installation
If available in Hex, the package can be installed
by adding docker_build to your list of dependencies in mix.exs:
def deps do
[
{:docker_build, "~> 0.1.0", runtime: false, only: :dev}
]
end
You also need to add distillery to your project. Normally this is done with:
def deps do
[
{:distillery, "~> 2.1"},
]
end
Then run mix distillery.init to create an initially distillery configuration file.
Basic Use
Add configuration
Create the following entries in config/dev.exs. As you will run the mix tasks in the
development environment you should only add them here. This assumes that
you are using webpack to compile assets.
# config/dev.exs
config :docker_build, DockerBuild.Build,
plugins: [DockerBuild.Plugins.Webpack],
app_name: :my_project,
elixir_version: "1.8.1",
docker_image: "docker.registry.url/my_project:production"
Build docker image
To build a release docker image:
mix docker.build
The task generates a .dockerignore file in the root of the project so you will probably
want to add this to .gitignore.
Run docker image
The build image can be run with
docker run docker.registry.url/my_project:production
However, this will probably fail if your project relies on environment variables at runtime.
Advanced usage
Additional configuration
The following additional config values are available:
:assets_path- path the assets within your project. Defaults toassets.:umbrella_apps- list of apps in an umbrella project. If not set then the project is assumed to be a non-umbrella project.
Plugin System
A plugin system is available to extend the dockerfile that is generated via various callbacks.
In the config a list of plugins can be given. Each item can either be the module name (if no configuration is required), or a tuple of the plugin and a keyword list of config values to provide a list of config values to the plugin:
# config/dev.exs
config :docker_build, DockerBuild.Build,
plugins: [PluginModule1, {PluginModule2, foo1: :bar1, foo2: :bar2}`, PluginModule3],
...
If complex config is required the plugin can just be listed with its module name in the
:plugins config key and separate config can be given for the module:
# config/dev.exs
config :docker_build, DockerBuild.Build,
plugins: [PluginModule1, PluginModule2, PluginModule3],
...
config :docker_build, PluginModule2,
foo1: :bar1,
foo2: :bar2
There are several plugins already included in the project.
Troubleshooting
The webserver does not start
Ensure that you have set server: true in you endpoint:
# config/prod.exs
config :my_app, MyApp.Endpoint,
server: true
Design Decisions
Selection of environment
The environment to build under (i.e. what MIX_ENV is set to in Docker) is set from the command line. This has the following advantage over taking the current value of MIX_ENV when invoking the task:
When building a
prodrelease the project and dependencies do not need to be compiled locally withMIX_ENV=prodjust to run the mix task.The configuration for the build can be placed in
config/dev.exsand so will not be included insys.configwhen the release is built by Distillery. You may have secrets in here you do not want in your final docker image.
TODO
Check mandatory config params
Currently a protocol error is shown if the config is missing.
Optional Assets
Either:
- Add assets as a plugin, and have some plugin hierarchy, deps resolution or be able to set
plugin config options from another plugin - e.g.
assets_compile_command:from webpack/brunch plugin. - Make
assets_path:config option mandatory so this can be used for apps without assets.