What is the difference between Dockerfile and docker-compose.yml files?

What is the difference between these two types of configuration files and how are they used together? We explain it here.

What is the difference between Dockerfile and docker-compose.yml files? What is the difference between these two types of configuration files and how are they used together? We explain it here.

So you need to deploy containers. Where do you begin? You could certainly do this from the command line, deploying each container via a long string of command options, every time. Or you could make use of a tool that allows you to carefully construct the deployment within a configuration file, and then deploy the container with a simple command.

But which configuration file do you use? Which method of deployment do you use? You can go with docker-compose or docker. Your choice could all hinge on the complexity of the application/service you plan on deploying. And that all boils down to using either a Dockerfile or a docker-compose.yml.

Or both.

SEE: Hiring kit: Database administrator (TechRepublic Premium)

You see? It gets complicated because you can use docker-compose.yml in such a way that it will call upon a Dockerfile to allow you to create even more complex container rollouts.

Let's see how these two are used in conjunction.

Before we get into this, make sure to read the following pieces:

Dockerfile

So let's say we want to create a Dockerfile that will use the latest NGINX image, but install php and php-fpm. The file is named Dockerfile and we'll house it in a new directory called dockerbuild. Create that new directory with the command:

mkdir ~/dockerbuild

Within ~/dockerbuild, create the Dockerfile with the command:

nano Dockerfile

In that file, paste the following:

FROM nginx:latest
MAINTAINER NAME EMAIL

RUN apt-get -y update && apt-get -y upgrade && apt-get install -y php-fpm

Where NAME is the name to be used as the maintainer and EMAIL is the maintainer's email address.

This Dockerfile will pull the latest version of the official NGINX image and then build a new image based on it, and also upgrade the platform and install the php-fpm package and its dependencies (which includes PHP). It's an incredibly simple example, but one that's easy to follow.

You could then run the docker build command with that Dockerfile, like so:

docker build -t "webdev:Dockerfile" .

But we want to integrate that file into docker-compose.yml. 

The docker-compose.yml file

Now let's craft a docker-compose.yml file which uses that Dockerfile, but also adds a database to the stack. This docker-compose.yml file might look like:

version: '3'
services:
  web:
    build: .
    ports:
     - "8080:80"
  db:
    image: mysql
    ports:
    - "3306:3306"
    environment:
    - MYSQL_ROOT_PASSWORD=password
    - MYSQL_USER=user
    - MYSQL_PASSWORD=password
    - MYSQL_DATABASE=demodb

The important section here is web:. It is in the web section that we instruct the docker-compose command to use the Dockerfile in the same directory (the . indicates to run the build command in the current working directory). If we wanted to house our Dockerfile in a completely separate directory, it would be declared here. Say, for example, the docker-compose.yml file is in ~/dockerbuild and the Dockercompose file is in ~/nginxbuild, you could declare that with the line:

build: ~/nginxbuild

Save and close the file. You could then deploy the new container with the command (run from within the directory housing the docker-compose.yml file):

docker-compose up

The command would first build the NGINX container from the Dockerfile and then deploy the db container as defined in the db: section.

Of course, you could also define everything within the docker-compose.yml file, but making use of both Dockerfile and docker-compose.yml makes for a much more flexible and efficient system. Why? Say you've defined a very complex Dockerfile for an NGINX container and you want to reuse that in a container deployment within a complete stack. Why go through all the trouble of re-defining the NGINX container within docker-compose.yml when you can simply repurpose the Dockerfile.

Write once, use often

With this system, you can write once and use often. So craft a Dockerfile for a part of the stack and re-use it for multiple stacks, by way of docker-compose.yml. Remember, docker-compose.yml files are used for defining and running multi-container Docker applications, whereas Dockerfiles are simple text files that contain the commands to assemble an image that will be used to deploy containers. 

So the workflow looks like this:

  1. Create Dockerfiles to build images. 
  2. Define complex stacks (comprising of individual containers) based on those Dockerfile images from within docker-compose.yml. 
  3. Deploy the entire stack with the docker compose command.

And that is the fundamental difference between Dockerfile and docker-compse.yml files.

Also see

dockerhero.jpg

Image: Docker

By Jack Wallen

Jack Wallen is an award-winning writer for TechRepublic and Linux.com. He’s an avid promoter of open source and the voice of The Android Expert. For more news about Jack Wallen, visit his website jackwallen.com.