Writing a Dockerfile

Writing a Dockerfile for your app

A Dockerfile is a text document that contains all the instructions required to build your app’s source code into a Docker image. Maestro uses the Docker image format, and thus all code must be built into images before it can be used.

The “build” process uses the set of instructions in the Dockerfile to build up a container image (in much the same way as a shell file executes a series of Linux tasks). Because Maestro handles the entire container lifecycle on your behalf, a Dockerfile is an absolute requirement.

If you don’t have a Dockerfile in your repo, we will analyze your code and suggest a Dockerfile for your app. If that file is unsuitable, use one of the guides below to write your own.

How-To Guides by framework

Click on the link for your app’s language or framework for a detailed guide on writing your own Dockerfile:

Important Dockerfile principles

When images are built from Dockerfiles, each line of instructions is laid down as a layer in the image, and each line that comes after it is a separate layer built “on top” of it. These layers are immutable - once they have been laid down they do not change. This has some important consequences:

Caching & build speed

When they are built, Docker images are cached by layer. If, when the image is rebuilt, any of the layers have changed, all of the layers above are also rebuilt from scratch.

This is why our default Dockerfiles tend to add the source code to the image as late as possible (i.e. in the “highest” possible layer) - because that layer is likely to change the most often. This means that only the last few layers need to be rebuilt each time you deploy. This can save a lot of time over hundreds (or thousands) of build cycles.

Putting a Dockerfile in a sub-directory

If for some reason you need to put a Dockerfile in a sub-directory - for example you have multiple services in a single repo - you can specify this in your app’s service configuration (i.e. the service.yml file).

For example, this service.yml configures two services (“buyer” & “seller”), each with their own Dockerfiles:

services:
 seller:
  git_url: https://github.com/cloud66-samples/acme.git
  git_branch: master
  dockerfile_path: "./Dockerfile"
  build_root: seller
 buyer:
  git_url: https://github.com/cloud66-samples/acme.git
  git_branch: master
  dockerfile_path: "./Dockerfile"
  build_root: buyer

This tells Maestro to look for Dockerfiles in the following places:

./seller/Dockerfile

./buyer/Dockerfile

The directory is specified under build_root and the dockerfile_path is relative to that directory.

More help