How to Install Docker Compose on Rocky Linux 10

Install Docker Compose on Rocky Linux 10 with Docker Engine, the Compose plugin, a private test stack, verification, and common VPS fixes today.
A polished 3D server rack with glowing container blocks and a subtle deep-red accent on a midnight-blue background.

Install Docker Compose on Rocky Linux 10 by adding Docker’s Rocky repository, installing the Compose CLI plugin, and starting a private test container. You can finish the setup and confirm a working Compose project in about ten minutes.

Prerequisites

  • A 64-bit Rocky Linux 10 VPS with at least 2 GB of RAM and 10 GB of free disk space.
  • SSH access as root, or a normal Linux account with working sudo privileges.
  • Outbound HTTPS access to Docker’s package repository and image registry.
  • A VPSLake Linux VPS if you need a Rocky Linux server with root access.
  • No domain is required for this private test. Use a domain later if you place a public application behind a TLS reverse proxy.

The commands use sudo for a regular SSH account. Rocky Linux 10 uses DNF 5 and firewalld; do not substitute Ubuntu’s apt or ufw commands.

Step 1: Confirm Rocky Linux 10 and update the host

Checking the release and architecture first prevents you from installing packages for the wrong Enterprise Linux version.

~~~bash . /etc/os-release printf ‘%s\n’ “$PRETTY_NAME” printf ‘Version: %s\n’ “$VERSION_ID” uname -m sudo dnf upgrade -y ~~~

The first lines should identify Rocky Linux 10 and a supported 64-bit architecture:

~~~text Rocky Linux 10.x (Red Quartz) Version: 10.x x86_64 ~~~

The minor release and number of upgraded packages will vary. Fix any DNS, mirror, or GPG-signature error before adding Docker’s repository.

Step 2: Remove conflicting container packages

Rocky Linux may arrive with Podman or an older Docker package. Removing conflicting runtimes on a new server avoids a package transaction that leaves Docker partially installed.

Run this only on a fresh or disposable host. If the server already runs Podman containers, inspect and migrate those workloads before removing Podman.

~~~bash sudo dnf remove -y docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine \ podman \ runc ~~~

DNF may say that some packages are not installed. This command does not remove Docker images, containers, or volumes stored under /var/lib/docker.

Step 3: Add Docker’s Rocky Linux repository

The Rocky-specific repository provides EL10 builds of Docker Engine, Buildx, and the Compose plugin, while leaving DNF able to receive future updates.

~~~bash sudo dnf install -y dnf-plugins-core ca-certificates sudo dnf config-manager –add-repo https://download.docker.com/linux/rocky/docker-ce.repo sudo dnf makecache dnf repolist –enabled | grep -i docker ~~~

The last command should show Docker’s stable repository, usually named docker-ce-stable. Docker documents the repository approach in its RHEL installation guide, and the official repository publishes a separate Rocky Linux 10 package stream.

Step 4: Install Docker Engine and the Compose plugin

Compose v2 is a Docker CLI plugin, so install it with Engine instead of downloading the old hyphenated docker-compose binary.

~~~bash sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin sudo systemctl enable –now docker sudo systemctl is-active docker sudo docker version –format ‘Client {{.Client.Version}} / Server {{.Server.Version}}’ sudo docker compose version ~~~

A successful check prints an active service and version strings. Exact versions change as Docker releases updates:

~~~text active Client 29.x / Server 29.x Docker Compose version vX.Y.Z ~~~

Run Docker’s disposable smoke test. It pulls a small image, prints a confirmation, and removes the stopped container.

~~~bash sudo docker run –rm hello-world ~~~

Near the end, expect:

~~~text Hello from Docker! Your installation appears to be working correctly. ~~~

Step 5: Let your SSH account run Docker

The Docker socket is root-owned by default. Add only the account that will administer containers; membership in the docker group provides root-equivalent control of the host.

Replace YOUR_LINUX_USER with the username used for SSH:

~~~bash sudo usermod -aG docker YOUR_LINUX_USER ~~~

Log out of SSH and reconnect so the new group membership is loaded. Then verify non-root access:

~~~bash id -nG docker info –format ‘Server {{.ServerVersion}}’ ~~~

The group list should contain docker, and docker info should print the Engine version. You can run newgrp docker for a one-shell test, or keep using sudo docker compose if you do not want permanent group access. Docker explains the security implications in its Linux post-installation guide.

Step 6: Create a private Compose test project

This small Apache service proves that Compose can read a YAML file, mount a host directory with an SELinux label, and publish a web response only on the server’s loopback address.

~~~bash mkdir -p ~/compose-rocky10/site cd ~/compose-rocky10 printf ‘%s\n’ ‘Rocky Linux 10 Docker Compose is working.’ > site/index.html ~~~

Create compose.yaml:

~~~yaml services: web: image: httpd:2.4-alpine restart: unless-stopped ports:

  • “127.0.0.1:8085:80” volumes:
  • ./site:/usr/local/apache2/htdocs:ro,Z

~~~

The :Z suffix gives SELinux a private label for the bind mount. The 127.0.0.1 binding makes Apache reachable on the VPS itself but not directly from the public network, so this test needs no new firewalld rule.

Step 7: Render and start the project

Render the configuration before startup so YAML errors are caught without creating a container.

~~~bash docker compose config –quiet docker compose pull docker compose up -d docker compose ps ~~~

config --quiet should be silent and return status 0. After the image downloads, the service should show as running:

~~~text NAME IMAGE SERVICE STATUS PORTS compose-rocky10-web-1 httpd:2.4-alpine web Up 127.0.0.1:8085->80/tcp ~~~

The generated container name can differ if you use another directory or set a Compose project name.

Verify Docker Compose on Rocky Linux 10

Use an HTTP request, an Apache configuration check, and the Compose status table to prove that the plugin controls the service and the bind mount is readable.

~~~bash curl –fail –silent –show-error http://127.0.0.1:8085 docker compose exec -T web httpd -t docker compose ps ~~~

The first two commands should include:

~~~text Rocky Linux 10 Docker Compose is working. Syntax OK ~~~

Because the example listens on loopback, a browser on your workstation cannot reach it directly. To view the page locally, create an SSH tunnel from your workstation with ssh -L 8085:127.0.0.1:8085 USER@SERVER_IP, then open http://127.0.0.1:8085.

Troubleshooting

No match for argument: docker-ce

DNF is not reading Docker’s Rocky repository, or its metadata refresh failed. Confirm the repository and rebuild the cache:

~~~bash sudo dnf repolist –enabled | grep -i docker sudo dnf makecache dnf list –showduplicates docker-ce ~~~

The package list should contain an EL10 build. If the first command returns nothing, repeat the repository command from Step 3 and make sure the server can resolve download.docker.com.

docker: 'compose' is not a docker command

The Compose plugin is missing or the Docker packages came from a different repository. Install the plugin from Docker’s repository and check the subcommand again:

~~~bash sudo dnf makecache sudo dnf install -y docker-compose-plugin docker compose version ~~~

Use docker compose with a space. The legacy docker-compose executable is not required for this setup.

permission denied while trying to connect to the Docker daemon socket

The current SSH session still has its old group list, or usermod was run for a different account. Reconnect, confirm that id -nG includes docker, and retry. sudo docker compose ... is a temporary workaround.

Apache returns 403 Forbidden or cannot read the mounted site

SELinux is usually blocking an unlabeled bind mount. Confirm the Compose file contains :Z on the site mount, then recreate the service:

~~~bash docker compose up -d –force-recreate web docker compose logs –tail=30 web ~~~

Keep SELinux enabled; fixing the mount label is safer than disabling the policy.

Hardening

  • Keep test services on 127.0.0.1. For a real public website, put a TLS reverse proxy in front of the application and allow only the required services in firewalld:

~~~bash sudo firewall-cmd –permanent –add-service=http sudo firewall-cmd –permanent –add-service=https sudo firewall-cmd –reload ~~~

  • Never publish the Docker API or a database port to the public network. Use Compose’s private network for service-to-service traffic.
  • Keep the docker group limited to trusted administrators, store secrets outside public repositories, and review image tags before production deployments.
  • Back up persistent application data before running docker compose down -v, because -v removes named volumes.

FAQ

Can I install Compose without installing Docker Engine?

You can install the plugin package by itself, but Compose needs the Docker CLI and a reachable Engine to start containers. Installing the Engine and plugin together avoids an incomplete setup.

Why does this guide use docker compose instead of docker-compose?

The space-separated command is Compose v2, which Docker distributes as a CLI plugin and updates through the package repository. The hyphenated command is the older standalone installation kept mainly for compatibility.

Does the test project need a firewall rule?

No. Its port is bound to 127.0.0.1, so it is available only on the VPS and through an SSH tunnel. If you later bind a reverse proxy publicly, add only the HTTP and HTTPS services required by that proxy.

Is membership in the docker group safe for every user?

No. A user who can access the Docker socket can start privileged containers and control host filesystems, which is effectively root-level access. Add only trusted administrators, or keep using sudo and consider rootless Docker for stronger separation.

Samrat Ghosh
Written by

Samrat Ghosh

Founder & Infrastructure Engineer

Samrat Ghosh is the founder of VPSLake, where he builds and runs the remote desktop and VPS hosting infrastructure the company is built on. He writes hands-on guides about RDP, Windows Server, VPS management and secure remote access - the practical documentation he wishes had…

Previous Article

MT4 EA Not Working on VPS? 9 Fixes

Next Article

How to Install Docker Compose on Rocky Linux 8

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *

Subscribe to our Newsletter

Subscribe to our email newsletter to get the latest posts delivered right to your email.
Pure inspiration, zero spam ✨