
Docker simplifies the process of managing application processes in containers. While containers are similar to virtual machines in certain ways, they are more lightweight and resource-friendly. This allows developers to break down an application environment into multiple isolated services.
For applications depending on several services, orchestrating all the containers to start up, communicate, and shut down 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 build fully customizable environments with multiple containers that can share networks and data volumes.
In this guide, you’ll learn how to install Docker Compose on Ubuntu and get started using this tool.
Simplify deploying applications to servers with DigitalOcean App Platform. Deploy directly from GitHub in minutes.
/usr/local/bin with executable permissions.docker-compose.yml YAML file that specifies services, networks, volumes, and port mappings.docker-compose up -d to start services, docker-compose ps to check status, and docker-compose down to stop and remove containers.docker compose (without hyphen) as a CLI plugin, while v1 uses docker-compose (with hyphen); this tutorial covers v1 installation.To follow this article, you will need:
Note: This tutorial covers installing Docker Compose v1, which uses docker-compose. Docker Compose v2 uses the compose CLI plugin command (documented in our Ubuntu 22.04 version of this tutorial). The main difference is v2 uses docker compose (without hyphen) instead of docker-compose. For compatibility details, see the official Docker documentation.
The following table compares Docker Compose v1 and v2 to help you choose the right version:
| Feature | Docker Compose v1 | Docker Compose v2 |
|---|---|---|
| Command Syntax | docker-compose (with hyphen) |
docker compose (without hyphen, as CLI plugin) |
| Installation Method | Standalone binary downloaded from GitHub | Installed as Docker CLI plugin via Docker Desktop or Docker Engine package manager |
| Architecture | Separate Python-based binary | Integrated into Docker CLI as a plugin |
| Performance | Slower startup time | Faster startup and execution |
| Compatibility | Works with older Docker versions | Requires Docker 20.10.13+ or Docker Desktop |
| docker-compose.yml | Fully compatible | Fully compatible (same file format) |
| Command Compatibility | Original command set | Most commands work the same, some enhancements |
| Updates | Manual updates required | Updates with Docker Desktop or Docker Engine |
| Status | Still supported but in maintenance mode | Actively developed and recommended |
| When to Use | Legacy systems, older Docker versions, or when you need the standalone binary | New installations, modern Docker setups, better performance |
Key Differences:
docker-compose up, v2 uses docker compose upFor most new installations, Docker Compose v2 is recommended. However, this tutorial focuses on v1 for systems that require the standalone binary or compatibility with older Docker versions.
Download Docker Compose from its official GitHub repository.
First, visit the releases page and note the latest version number (e.g., 1.29.2). Replace 1.29.2 in the command below with the latest version number you found.
The following command downloads the release and saves the executable to /usr/local/bin/docker-compose, making it globally accessible:
- sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
Set executable permissions for the docker-compose command:
- sudo chmod +x /usr/local/bin/docker-compose
Verify the installation:
- docker-compose --version
You’ll see output similar to this:
Outputdocker-compose version 1.29.2, build 5becea4c
Docker Compose is now installed. Next, you’ll set up a docker-compose.yml file and run a containerized environment.
docker-compose.yml FileCreate a web server environment using the official Nginx image from Docker Hub to demonstrate Docker Compose. This environment serves a single static HTML file.
Create a new directory in your home folder and navigate into it:
- mkdir ~/compose-demo
- cd ~/compose-demo
Create an application folder to serve as the document root for your Nginx environment:
- mkdir app
Create a new index.html file in the app folder:
- nano app/index.html
Place the following content into 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. In nano, press CTRL+X, then Y, then ENTER.
Next, create the docker-compose.yml file:
- nano docker-compose.yml
Insert the following content in your docker-compose.yml file:
version: '3.7'
services:
web:
image: nginx:alpine
ports:
- "8000:80"
volumes:
- ./app:/usr/share/nginx/html
The docker-compose.yml file starts with a version definition specifying the Compose file format version. Version '3.7' is compatible with Docker Compose v1. In newer Docker Compose versions, this field is optional, but including it ensures compatibility.
The services block defines the services in this environment. Here, a single web service uses the nginx:alpine image. The ports directive maps port 8000 on the host to port 80 in the container where Nginx runs.
The volumes directive creates a shared volume between the host and container, mounting the local app folder to /usr/share/nginx/html inside the container, replacing Nginx’s default document root.
Save and close the file.
You’ve set up a demo page and docker-compose.yml file. Next, start the containerized environment with Docker Compose.
With the docker-compose.yml file in place, start the environment. This command downloads necessary Docker images, creates a container for the web service, and runs it in the background:
- docker-compose up -d
Docker Compose checks for the image locally first, then downloads from Docker Hub if needed. You’ll see output like this:
OutputCreating network "compose-demo_default" with the default driver
Pulling web (nginx:alpine)...
alpine: Pulling from library/nginx
cbdbe7a5bc2a: Pull complete
10c113fb0c77: Pull complete
9ba64393807b: Pull complete
c829a9c40ab2: Pull complete
61d685417b2f: Pull complete
Digest: sha256:57254039c6313fe8c53f1acbf15657ec9616a813397b74b063e32443427c5502
Status: Downloaded newer image for nginx:alpine
Creating compose-demo_web_1 ... done
Note: If you encounter a permission error regarding the Docker socket, complete Step 2 of How To Install and Use Docker on Ubuntu to enable running Docker commands without sudo.
The environment is running in the background. Verify the container is active:
- docker-compose ps
This shows information about running containers, their state, and port mappings:
Output Name Command State Ports
----------------------------------------------------------------------------------
compose-demo_web_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:8000->80/tcp
Access the demo application at localhost:8000 on a local machine, or your_server_domain_or_IP:8000 on a remote server.
You’ll see a page like this:

The shared volume keeps your app folder files in sync with the container’s document root. Changes to index.html are automatically reflected when you reload the page.
Next, manage your containerized environment with Docker Compose commands.
Use Docker Compose commands to manage and interact with your containerized environment.
Check logs from your Nginx container:
- docker-compose logs
You’ll see output similar to this:
OutputAttaching to compose-demo_web_1
web_1 | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
web_1 | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
web_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
web_1 | 10-listen-on-ipv6-by-default.sh: Getting the checksum of /etc/nginx/conf.d/default.conf
web_1 | 10-listen-on-ipv6-by-default.sh: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
web_1 | /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
web_1 | /docker-entrypoint.sh: Configuration complete; ready for start up
web_1 | 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" "-"
Pause the environment without changing container state:
- docker-compose pause
OutputPausing compose-demo_web_1 ... done
Resume execution after pausing:
- docker-compose unpause
OutputUnpausing compose-demo_web_1 ... done
Stop containers without destroying data:
- docker-compose stop
OutputStopping compose-demo_web_1 ... done
Remove containers, networks, and volumes:
- docker-compose down
OutputRemoving compose-demo_web_1 ... done
Removing network compose-demo_default
This doesn’t remove the base image (nginx:alpine). Running docker-compose up again will be faster since the image remains on your system.
To remove the base image:
- docker image rm nginx:alpine
OutputUntagged: nginx:alpine
Untagged: nginx@sha256:b89a6ccbda39576ad23fd079978c967cecc6b170db6e7ff8a769bf2259a71912
Deleted: sha256:7d0cdcc60a96a5124763fddf5d534d058ad7d0d8d4c3b8be2aefedf4267d0270
Deleted: sha256:05a0eaca15d731e0029a7604ef54f0dda3b736d4e987e6ac87b91ac7aac03ab1
Deleted: sha256:c6bbc4bdac396583641cb44cd35126b2c195be8fe1ac5e6c577c14752bbe9157
Deleted: sha256:35789b1e1a362b0da8392ca7d5759ef08b9a6b7141cc1521570f984dc7905eb6
Deleted: sha256:a3efaa65ec344c882fe5d543a392a54c4ceacd1efd91662d06964211b1be4c08
Deleted: sha256:3e207b409db364b595ba862cdc12be96dcdad8e36c59a03b7b3b61c946a5741a
Note: For more Docker commands, see How to Install and Use Docker on Ubuntu.
docker-compose: command not foundThis error indicates docker-compose is not in your system’s PATH, usually due to an incomplete installation.
Fix by either adding the directory to your PATH or using the full path. If docker-compose is in /usr/local/bin, run:
/usr/local/bin/docker-compose
Permission issues occur when your user lacks permissions to run Docker commands.
Fix by either running with sudo or adding your user to the docker group. To use sudo:
sudo docker-compose
To add your user to the docker group:
sudo usermod -aG docker $USER
Remember to log out and log back in for the changes to take effect.
Docker Compose is a tool for defining and running multi-container Docker applications. It allows you to define multi-container applications in a YAML file and start all services with a single command.
For example, you can define a service for a web server and another for a database, and Docker Compose will handle the creation and linking of these services.
Check the Docker Compose releases page for the latest version.
Run:
docker-compose --version
This displays the installed Docker Compose version.
No, Docker Compose requires Docker to be installed and running on your system. Docker Compose is a tool that builds on top of Docker, so Docker must be installed first.
Since this tutorial installs via binary download, remove it manually:
sudo rm /usr/local/bin/docker-compose
If you installed via APT, use sudo apt-get purge docker-compose.
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’ve also seen how to manage this environment using Compose commands.
For a complete reference of all available docker-compose commands, check the official documentation.
If you’re interested in more usages of Docker Compose, check out the following tutorials:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
I help Businesses scale with AI x SEO x (authentic) Content that revives traffic and keeps leads flowing | 3,000,000+ Average monthly readers on Medium | Sr Technical Writer @ DigitalOcean | Ex-Cloud Consultant @ AMEX | Ex-Site Reliability Engineer(DevOps)@Nutanix
Building future-ready infrastructure with Linux, Cloud, and DevOps. Full Stack Developer & System Administrator. Technical Writer @ DigitalOcean | GitHub Contributor | Passionate about Docker, PostgreSQL, and Open Source | Exploring NLP & AI-TensorFlow | Nailed over 50+ deployments across production environments.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
the version number (1.27.4) is missing a leading “v”, i.e. “v1.27.4”.
This command worked better for me, FYI:
platform=$(uname -s) ; sudo curl -L “https://github.com/docker/compose/releases/download/v2.11.2/docker-compose-${platform,,}-$(uname -m)” -o /usr/local/bin/docker-compose
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.