Virtualization

Install Docker Compose on a Linux VPS in 2026

You have a fresh Ubuntu 24.04 VPS, Docker Engine is running, and now you need Docker Compose to spin up a multi-container stack. The quickest way to install Docker Compose on a Linux VPS is to enable the official Docker Compose plugin, which the apt package docker-compose-plugin installs for you. No manual downloads, no permission headaches, no guessing which binary is current. This guide walks through the install on Ubuntu 24.04 LTS, verifies every step, and fixes the two mistakes that break Compose for most people: a missing plugin and a wrong executable path.

Prerequisites

  • A Linux VPS running Ubuntu 24.04 LTS (the commands also work on Debian 12, but paths and package names stay Ubuntu-specific here).
  • A non-root user with sudo privileges. If you only have root, create one first: adduser deploy && usermod -aG sudo deploy.
  • Docker Engine already installed and the docker service enabled. If not, install it from the official Docker apt repository, not from Ubuntu's universe.
  • A domain or application stack that actually needs Compose. Single-container apps do not justify the extra layer.

Why use Docker Compose v2 instead of the standalone binary

Docker Compose v2 is a plugin to the Docker CLI, not a separate Python script. The old docker-compose (v1) is end-of-life and receives no security updates. The plugin ships as docker compose (no hyphen), installs from the same apt repository as Docker Engine, and tracks the Engine version. That means one source of truth for updates: apt upgrade updates both. On a VPS where you manage everything yourself, this matters. You do not want a hand-placed binary in /usr/local/bin going stale while the Engine moves on. The plugin also parses the same compose.yaml files, supports all the v2 features (profiles, include, watch), and gives you the same output format. There is no reason to install the standalone binary in 2026.

Step 1 - Installing Docker Engine from the official repository

Docker Compose will not install cleanly unless Docker Engine itself comes from the official Docker apt source. Ubuntu's own docker.io package works, but the Compose plugin version may lag behind. Set up the official repository first. This is the same procedure documented by Docker, and it is the only path that keeps Engine and plugin in sync.

sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

The signed-by option pins the repository to the GPG key you just placed in /etc/apt/keyrings. Without it, apt accepts any key that signs the repo, which is a weaker trust model. The $(. /etc/os-release && echo "$VERSION_CODENAME") substitution resolves to noble on Ubuntu 24.04, so the repository line points at the correct release. Now install the Engine plus the Compose plugin together.

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Note the docker-compose-plugin package. That is what pulls in Compose v2. If you are upgrading an existing install, run the same command; apt will upgrade the plugin to the current version.

Verify that the Docker daemon is active before continuing.

sudo systemctl status docker --no-pager

Expected output: active (running). If it is not, start it with sudo systemctl enable --now docker and check the logs with journalctl -u docker -n 50.

Step 2 - Verifying the Compose plugin installation

With the plugin installed, the command is docker compose, not docker-compose. Check the version to confirm everything matches.

docker compose version

Expected output should look like Docker Compose version v2.29.7 or a newer v2 release. If you see docker-compose version 1.29.2, you have the legacy standalone binary in your PATH, and it is shadowing the plugin. Remove it before going further:

sudo rm /usr/local/bin/docker-compose
hash -r
docker compose version

The hash -r clears the shell's command lookup cache, which otherwise keeps pointing at the deleted binary. This is the classic trap: people install the plugin, run docker-compose out of habit, and get an old v1 prompt. Train your muscle memory now. The hyphen is gone.

Step 3 - Testing Compose with a real stack

Version output proves the binary exists, but it does not prove Compose can talk to the daemon. Run a minimal two-service stack to exercise the full path. Create a project directory and a compose.yaml file.

mkdir -p ~/compose-test && cd ~/compose-test
cat > compose.yaml <<'EOF'
services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
  redis:
    image: redis:alpine
EOF

This stack declares an Nginx container publishing port 8080 and a Redis container with no published ports. Start it in detached mode.

docker compose up -d

You should see Container compose-test-web-1 Started and Container compose-test-redis-1 Started. Verify both containers are running and check the exposed port.

docker compose ps
curl -I http://localhost:8080

The curl should return HTTP/1.1 200 OK. If the port is closed, check whether a firewall is blocking it. On Ubuntu, sudo ufw status shows the rules; allow the port with sudo ufw allow 8080/tcp if needed. Now tear the stack down so it does not linger.

docker compose down

This removes the containers but keeps the project directory and the compose.yaml file. You can reuse the directory for real projects.

Step 4 - Running Compose without sudo (permission fix)

Every docker command prefixing with sudo gets old fast, and it causes file permission mismatches in bind mounts. Fix it by adding your user to the docker group. This is the standard approach on a single-user VPS where you trust the only account that logs in.

sudo usermod -aG docker $USER
newgrp docker
docker compose version

The newgrp docker command applies the group change to the current session without logging out. Test that the daemon accepts your user directly.

docker info | grep -i "permissions\|rootless"

If the command returns without a permission error, your user can talk to the daemon. One security note: membership in the docker group is equivalent to root access, because the group can mount host directories and run privileged containers. Only add accounts you trust completely. If you want stronger isolation, look into rootless Docker, but that is a separate setup with its own trade-offs and it does not play well with all Compose features yet.

Troubleshooting common Compose install problems

Two failures cover most support tickets. Here is how to diagnose and fix both.

"docker: command not found" after installing the plugin

You installed docker-compose-plugin by itself on a host that never had Docker Engine. The plugin is just a CLI extension; it needs the docker binary and a running daemon. Install the full set from Step 1, then recheck.

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl enable --now docker
docker compose version

"permission denied while trying to connect to the Docker daemon socket"

Your user is not in the docker group, or the group change has not applied to the current shell. Run the usermod command from Step 4, then either log out and back in or use newgrp docker. Check group membership with groups.

"no configuration file provided: not found"

You ran docker compose up outside the project directory. Compose looks for compose.yaml or docker-compose.yml in the current directory. Run cd into the project folder first, or point Compose at the file explicitly:

docker compose -f ~/compose-test/compose.yaml up -d

If the daemon itself is unhealthy, the fastest diagnostic is journalctl -u docker -n 50 --no-pager, which shows why the service failed to start. Most commonly it is a corrupted daemon.json or a port conflict on the API socket.

FAQ

What is the difference between docker-compose and docker compose?

docker-compose is the legacy standalone binary (v1), now end-of-life. docker compose is the v2 plugin integrated into the Docker CLI. Use the plugin form; it receives updates with Docker Engine and supports all current Compose features.

Do I need to install Docker Compose separately if Docker Engine is installed?

It depends on the install source. The official Docker apt repository offers docker-compose-plugin as a separate package, but it is not pulled in automatically by docker-ce. You must install it explicitly. On desktop installs (Docker Desktop), Compose ships bundled.

Where does the docker compose plugin install on Ubuntu?

The plugin binary installs to /usr/libexec/docker/cli-plugins/docker-compose. The docker CLI finds it there automatically. The legacy binary lives at /usr/local/bin/docker-compose; remove it if it shadows the plugin.

Can I use Docker Compose on a Windows VPS?

Docker Compose runs on Windows Server through Docker Engine in Linux container mode, but it is awkward. The practical pattern is to run your Compose stack on a Linux VPS and reserve a Windows VPS for workloads that genuinely need Windows (ASP.NET with Windows authentication, legacy COM components, RDP-based tools). Mixing both in one Compose file is not supported.

How do I update Docker Compose on a Linux VPS?

Because Compose v2 is an apt package, update it with the rest of the system: sudo apt update && sudo apt upgrade docker-compose-plugin. No manual binary swaps, no version checks against a release page.

Related articles

在 Linux VPS 上安装 Docker Compose

本文介绍如何在 Ubuntu 24.04 VPS 上通过官方 apt 仓库安装 Docker Compose v2 插件,而不是使用已停止维护的独立二进制文件。安装后务必运行 docker compose version 验证,并将当前用户加入 docker 组以避免每次输入 sudo。写 compose.yaml 时要注意端口映射和防火墙规则,推荐使用 docker compose up -d 后台启动。这套方法适用于所有基于 Debian 的 Linux VPS,也适合在越南机房部署多容器应用。

Note: This guide is for general reference. Every system and infrastructure has its own specifics, so test each step in a safe environment and consult a qualified engineer before applying it in production.