Dockerfile Deployment
New
Introduced in 0.3.15
While Dokku normally defaults to using Heroku buildpacks for deployment, you can also use Docker's native Dockerfile
system to define a container.
Info
Dockerfile support is considered a power user feature. By using Dockerfile-based deployment, you agree that you will not have the same comfort as that enjoyed by buildpack users, and Dokku features may work differently. Differences between the two systems will be documented here.
Usage
Detection
This builder will be auto-detected in the following case:
- A
Dockerfile
exists in the root of the app repository.
Dokku will only select the dockerfile
builder if both the herokuish
and pack
builders are not detected and a Dockerfile exists. For more information on how those are detected, see the following links:
Switching from buildpack deployments
If an application was previously deployed via buildpacks, the following commands should be run before a Dockerfile deploy will succeed:
Build-time configuration variables
For security reasons - and as per Docker recommendations - Dockerfile-based deploys have variables available only during runtime.
For users that require customization in the build
phase, you may use build arguments via the docker-options plugin:
The location of the Dockerfile
may also be specified. If the location is changed, the repository must also have a Dockerfile
in the root directory in order to trigger a dockerfile-based deploy.
Once set, the Dockerfile usage would be as follows:
FROM ubuntu:18.04
# set the argument default
ARG NODE_ENV=production
# use the argument
RUN echo $NODE_ENV
You may also set the argument as an environment variable
FROM ubuntu:18.04
# set the argument default
ARG NODE_ENV=production
# assign it to an environment variable
# we can wrap the variable in brackets
ENV NODE_ENV ${NODE_ENV}
# or omit them completely
# use the argument
RUN echo $NODE_ENV
Building images with Docker Buildkit
If your Dockerfile is using Docker engine's buildkit (not to be confused with buildpacks), then the DOCKER_BUILDKIT=1
environment variable needs to be set. One way to do this is to edit /etc/environment
on your dokku host and reboot your instance. Note, for complete build log output, you should also set BUILDKIT_PROGRESS=plain
in the same file.
Buildkit directory caching
Buildkit implements the RUN --mount
option, enabling mount directory caches for RUN
directives. The following is an example that mounts debian packaging related directories, which can speed up fetching of remote package data.
FROM debian:latest
RUN --mount=target=/var/lib/apt/lists,type=cache \
--mount=target=/var/cache/apt,type=cache \
apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
git
Mount cache targets may vary depending on the tool in use, and users are encouraged to investigate the directories that apply for their language and framework.
You would adjust the cache directory for whatever application cache you have, e.g. /root/.pnpm-store/v3
for pnpm, $HOME/.m2
for maven, or /root/.cache
for golang.
Customizing the run command
By default no arguments are passed to docker run
when deploying the container and the CMD
or ENTRYPOINT
defined in the Dockerfile
are executed. You can take advantage of docker ability of overriding the CMD
or passing parameters to your ENTRYPOINT
setting $DOKKU_DOCKERFILE_START_CMD
. Let's say for example you are deploying a base Node.js image, with the following ENTRYPOINT
:
You can do:
To tell Docker what to run.
Setting $DOKKU_DOCKERFILE_CACHE_BUILD
to true
or false
will enable or disable Docker's image layer cache. Lastly, for more granular build control, you may also pass any docker build
option to docker
, by setting $DOKKU_DOCKER_BUILD_OPTS
.
Procfiles and multiple processes
New
Introduced in 0.5.0
You can also customize the run command using a Procfile
, much like you would on Heroku or
with a buildpack deployed app. The Procfile
should contain one or more lines defining process types and associated commands.
When you deploy your app, a Docker image will be built. The Procfile
will be extracted from the image
(it must be in the folder defined in your Dockerfile
as WORKDIR
or /app
) and the commands
in it will be passed to docker run
to start your process(es). Here's an example Procfile
:
And Dockerfile
:
When you deploy this app the web
process will automatically be scaled to 1 and your Docker container
will be started basically using the command docker run bin/run-prod.sh
. If you want to also run
a worker container for this app, you can run dokku ps:scale worker=1
and a new container will be
started by running docker run bin/run-worker.sh
(the actual docker run
commands are a bit more
complex, but this is the basic idea). If you use an ENTRYPOINT
in your Dockerfile
, the lines
in your Procfile
will be passed as arguments to the ENTRYPOINT
script instead of being executed.
Exposed ports
See the port management documentation for more information on how Dokku exposes ports for applications and how you can configure these for your app.