Docker simplifies the process of managing containerized application processes. While containers are similar to virtual machines in certain ways, they are lighter and easier to use resources. This allows developers to divide an application environment into several isolated services.
For applications that rely on multiple services, orchestrating all containers to start, communicate, and close together can quickly become unwieldy. Docker Compose is a tool that allows you to run multi-container application environments based on definitions set in a YAML file. It uses service definitions to create fully customizable environments with multiple containers that can share networks and data volumes.
In this guide, you will demonstrate how to install Docker Compose on an Ubuntu 20.04 server and how to get started using this tool.
To follow this article, you will need:
- Access to a local Ubuntu 20.04 development machine or development server as a non-root user with sudo privileges. If you are using a remote server, it is recommended to have an active firewall installed. To configure them, see our Initial Server Setup Guide for Ubuntu 20.04.
- Docker installed on your local server or machine, following steps 1 and 2 of How to install and use Docker on Ubuntu 20.04.
Step 1 — Installing
To ensure you get the most up-to-date stable version of Docker Compose, you’ll download this software from its official Github repository
First, confirm the latest version available on your release page. At the time of writing, the most current stable version is 1.29.2.
The following command will download version 1.29.2 and save the
executable file to /usr/local/bin/docker-compose, making this software globally accessible as docker-compose: sudo curl -L “https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-
- $(uname -m)” -o /usr/local/bin/
Next, set the correct permissions to make the docker-compose command executable:
- sudo chmod +x /usr/local/bin/
To verify that the installation was successful, you can run
: docker-compose -version
You will see output similar to the following:
version 1.29.2, build 5becea4c
Docker Compose has now been successfully installed on your system. In the next section, you’ll see how to set up a docker-compose.yml file and get a containerized environment up and running with this tool.
Step 2 — Setting
up a docker-compose.yml file
To demonstrate how to set up a docker-compose.yml file and work with Docker Compose, you’ll create a web server environment using the official Nginx image of Docker Hub, Docker’s public registry. This containerized environment will serve a single static HTML file.
Start by creating a new directory in your home folder
and then go to it
: mkdir ~/compose-demo
- cd ~/compose-demo
In this directory, configure an application folder to serve as the document root for your Nginx environment
- MKDIR App
Using your preferred text editor, create a new file .html index inside the application folder
- nano app/index.html
Place the following content in this file:
<!doctype html> <html lang=”en”> <head> <meta charset=”utf-8″> <title>Docker Compose Demo</title> <link rel=”stylesheet” href=”https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.min.css”> </head> <body> <h1>This is a Docker Compose Demo Page.</h1> <p>This content is being served by an Nginx container.</p > </body> </html>
Save and close the file when you are finished. If you are using nano, you can do so by typing CTRL+X, then Y and ENTER to confirm.
Next, create the docker-compose.yml file: nano docker-compose.yml Insert the following content into the docker-compose.yml file: Version: ‘3.7’ Services: Web: Image: Nginx:Alpine Ports: – “8000:80” Volumes: – ./app:/usr/share/nginx/html The
typically starts with the version definition. This will tell Docker Compose which configuration version you are using.
have the service block, where you configure the services that are part of this environment. In your case, you have a single service called web. This service uses the nginx:alpine image and configures port forwarding with the port policy. All requests on port 8000 of the host machine (the system from where you are running Docker Compose) will be redirected to the web container on port 80, where Nginx will run.
The volume policy will create a shared volume between the host computer and the container. This will share the local application folder with the container, and the volume will be located at /usr/share/nginx/html inside the container, which will then overwrite the default document root for Nginx.
Save and close the file.
You have set up a demo page and a docker-compose.yml file to create a containerized web server environment that will serve you. In the next step, you will create this environment with Docker Compose.
: Run Docker Compose
With the docker-compose.yml file in place, you can now run Docker Compose to activate your environment. The following command will download the required Docker images, create a container for the web service, and run the containerized environment in background mode:
- docker-compose up -d
Compose will first search for the defined image on the local system, and if it cannot locate the image, download the image from Docker Hub. You’ll see output like this
: OutputCreating network “compose-demo_default” with default Pulling web handler (nginx:alpine)… Alpine: Library Extract / nginx cbdbe7a5bc2a: Full Extract 10c113fb0c77: Full Extract 9ba64393807b: Full Extract c829a9c40ab2: Full Extract 61d685417b2f: Full Extract Abstract: sha256:57254039c6313fe8c53f1acbf15657ec9616a813397b74b063e32443427c5502 Status: Downloaded Latest image for nginx:alpine Creating compose-demo_web_1 … done
Your environment is now running in the background. To verify that the container is active, you can run
: docker-compose ps
This command will show you information about the running containers and their status, as well as any port forwarding currently in place:
Output name Command status ports –
/docker-entrypoint.sh ngin… Up to 0.0.0.0:8000->80/tcp You can now access the demo application by pointing your browser to localhost:8000 if you are running this demo on
your local machine, or your_server_domain_or_IP:8000 if you are running this demo on a remote server.
You’ll see a page like this:
<img src="https://assets.digitalocean.com/articles/docker_compose_ubuntu2004/demo_page.png" alt="Docker Compose Demo Page" />
The shared volume you’ve set up in the docker-compose.yml file keeps the files in the application folder synchronized with the document root of the container. If you make any changes to the file .html index, the container will automatically pick it up and therefore reflect it in your browser when you reload the page.
In the next step, you’ll see how to manage your containerized environment with Docker Compose commands.
Step 4 — Familiarize yourself with Docker Compose commands
You’ve seen how to set up a docker-compose.yml file and open your environment with docker-compose up. Now you’ll see how to use Docker Compose commands to manage and interact with your containerized environment.
To check the logs produced by your Nginx container, you can use the logs
: docker-compose logs command
You will see output similar to this:
- compose-demo_web_1 web_1
| /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, it will attempt to perform the configuration web_1 | /docker-entrypoint.sh: Searching for shell scripts in /docker-entrypoint.d/ web_1 | /docker-entrypoint.sh: Start /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh web_1 | 10-listen-on-ipv6-by-default.sh: Get the checksum of /etc/nginx/conf.d/default.conf web_1 | 10-listen-on-ipv6-by-default.sh: IPv6 listening enabled in /etc/nginx/conf.d/default.conf web_1 | /docker-entrypoint.sh: Start /docker-entrypoint.d/20-envsubst-on-templates.sh web_1 | /docker-entrypoint.sh: Full configuration; Ready for web_1 commissioning | 172.22.0.1 – – [02/Jun/2020:10:47:13 +0000] “GET/HTTP/1.1″ 200 353″-” “Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36” “-”
If you want to pause the execution of the environment without changing the current state of your containers, you can use:
- docker-compose pause OutputPausing compose-demo_web_1
To resume execution after pause:
- docker-compose unpause OutputUnpausing compose-demo_web_1
The stop command will terminate container execution, but will not destroy any data associated with its containers:
- docker-compose stop OutputStopping compose-demo_web_1
If you want to remove the containers, networks, and volumes associated with this containerized environment, use the down command:
- docker-compose down OutputRemoving compose-demo_web_1
… done Network compose-demo_default removal
Note that this will not delete the base image used by Docker Compose to activate your environment (in your case, nginx:alpine). This way, every time you reopen your environment with a docker composition, the process will be much faster since the image is already on your system.
In case you also want to delete the base image from your system, you can use
: docker rm image nginx:alpine OutputUntagged:
Untagged: nginx@sha256:b89a6ccbda39576ad23fd079978c967cecc6b170db6e7ff8a769bf2259a71912 Deleted: sha256:7d0cdcc60a96a5124763fddf5d534d058ad7d0d8d4c3b8be2aefedf4267d0270 Deleted: sha256:05a0eaca15d731e0029a7604ef54f0dda3b736d4e987e6ac87b91ac7aac03ab1 Deleted: sha256: c6bbc4bdac396583641cb44cd35126b2c195be8fe1ac5e6c577c14752bbe9157 Erased: sha256:35789b1e1a362b0da8392ca7d5759ef08b9a6b7141cc1521570f984dc7905eb6 Removed: sha256:a3efaa65ec344c882fe5d543a392a54c4ceacd1efd91662d06964211b1be4c08 Removed: sha256:3e207b409db364b595ba862cdc12be96dcdad8e36c59a03b7b3b61c946a5741a
In this guide, you’ve seen how to install Docker Compose and set up a containerized environment based on an Nginx web server image. You have also seen how to manage this environment by using the Compose commands.
For a complete reference of all available docker-compose commands, see the official documentation.
If you’re interested in more uses of Docker Compose, check out How to install WordPress with Docker Compose and
also How to secure a node in containers.js Application with Nginx, Let’s Encrypt, and Docker Compose.