Docker: Multiple Dockerfiles in project
DockerDocker Problem Overview
How do you organize the Dockerfiles belonging to a project when you have one Dockerfile for the database, one for the application server, and so on? Do you create some sort of hierachy in the source? A big enterprise project can't consist of only one Dockerfile?
Docker Solutions
Solution 1 - Docker
In newer versions(>=1.8.0) of docker, you can do this
docker build -f Dockerfile.db .
docker build -f Dockerfile.web .
A big save.
EDIT: update versions per raksja's comment
EDIT: comment from @vsevolod: it's possible to get syntax highlighting in VS code by giving files .Dockerfile extension(instead of name) e.g. Prod.Dockerfile, Test.Dockerfile etc.
Solution 2 - Docker
docker-compose
and multiple Dockerfile
in separate directories
Use > Don't rename your Dockerfile
to Dockerfile.db
or Dockerfile.web
, it may not be supported by your IDE and you will lose syntax highlighting.
As Kingsley Uchnor said, you can have multiple Dockerfile
, one per directory, which represent something you want to build.
I like to have a docker
folder which holds each applications and their configuration. Here's an example project folder hierarchy for a web application that has a database.
docker-compose.yml
docker
├── web
│ └── Dockerfile
└── db
└── Dockerfile
docker-compose.yml
example:
version: '3'
services:
web:
# will build ./docker/web/Dockerfile
build: ./docker/web
ports:
- "5000:5000"
volumes:
- .:/code
db:
# will build ./docker/db/Dockerfile
build: ./docker/db
ports:
- "3306:3306"
redis:
# will use docker hub's redis prebuilt image from here:
# https://hub.docker.com/_/redis/
image: "redis:alpine"
docker-compose
command line usage example:
# The following command will create and start all containers in the background
# using docker-compose.yml from current directory
docker-compose up -d
# get help
docker-compose --help
In case you need files from previous folders when building your Dockerfile
You can still use the above solution and place your Dockerfile
in a directory such as docker/web/Dockerfile
, all you need is to set the build context
in your docker-compose.yml
like this:
version: '3'
services:
web:
build:
context: .
dockerfile: ./docker/web/Dockerfile
ports:
- "5000:5000"
volumes:
- .:/code
This way, you'll be able to have things like this:
config-on-root.ini
docker-compose.yml
docker
└── web
├── Dockerfile
└── some-other-config.ini
and a ./docker/web/Dockerfile
like this:
FROM alpine:latest
COPY config-on-root.ini /
COPY docker/web/some-other-config.ini /
Here are some quick commands from tldr docker-compose. Make sure you refer to official documentation for more details.
Solution 3 - Docker
Author's Note
This answer is out of date. Fig no longer exists and has been replaced by Docker compose. Accepted answers cannot be deleted.
Docker Compose supports the building of project hierachy. So it's now easy to support a Dockerfile in each sub directory.
├── docker-compose.yml
├── project1
│ └── Dockerfile
└── project2
└── Dockerfile
Original answer
I just create a directory containing a Dockerfile for each component. Example:
When building the containers just give the directory name and Docker will select the correct Dockerfile.
Solution 4 - Docker
In Intellij, I simple changed the name of the docker files to *.Dockerfile, and associated the file type *.Dockerfile to docker syntax.
Solution 5 - Docker
Add an abstraction layer, for example, a YAML file like in this project https://github.com/larytet/dockerfile-generator which looks like
centos7:
base: centos:centos7
packager: rpm
install:
- $build_essential_centos
- rpm-build
run:
- $get_release
env:
- $environment_vars
A short Python script/make can generate all Dockerfiles from the configuration file.
Solution 6 - Docker
When working on a project that requires the use of multiple dockerfiles, simply create each dockerfile in a separate directory. For instance,
app/ db/
Each of the above directories will contain their dockerfile. When an application is being built, docker will search all directories and build all dockerfiles.