To use Docker Engine and docker compose on openEuler while letting package updates be managed by DNF, you can use the CentOS 9 RPMs provided by Docker. This guide first covers a fresh installation, then discusses migration from an existing Moby environment and common issues.
The key point is fixing the repository path to centos/9: openEuler’s $releasever cannot be directly substituted into Docker’s CentOS repository directory. This compatibility method has been validated through actual installation; the upstream platform support scope can be found in the Docker installation documentation.
1. Check if Docker Is Already Installed
type -a docker dockerd
rpm -q docker-ce moby docker-engine podman-docker
It’s normal for new systems to show that commands or packages do not exist. If Docker was previously installed, first confirm which version you’re using: Docker CE can continue using the original repository for updates; Moby users should refer to the migration section below. For statically installed binaries like /usr/local/bin/docker, dockerd, and custom service files, you must handle them first—do not attempt to overlay another installation directly.
This guide assumes a regular user with sudo privileges. Throughout, we use sudo docker—there’s no need to add the current user to the docker group just for installation.
2. Configure Docker CE Repository
Create the repository file for systems without it. If /etc/yum.repos.d/docker-ce.repo or a similar repository ID already exists, check and back up the original file first to avoid duplicate definitions or configuration overrides.
First, write the domestic mirror list:
sudo install -d -m 0755 /etc/dnf/mirrorlists.d
sudo tee /etc/dnf/mirrorlists.d/docker-ce-stable > /dev/null <<'EOF'
https://mirrors.cernet.edu.cn/docker-ce/linux/centos/9/$basearch/stable/
https://mirrors.aliyun.com/docker-ce/linux/centos/9/$basearch/stable/
https://mirrors.tencent.com/docker-ce/linux/centos/9/$basearch/stable/
https://mirrors.huaweicloud.com/docker-ce/linux/centos/9/$basearch/stable/
EOF
Then create the repository configuration, keeping the official Docker URL as baseurl:
sudo tee /etc/yum.repos.d/docker-ce.repo > /dev/null <<'EOF'
[docker-ce-stable]
name=Docker CE Stable - $basearch
mirrorlist=file:///etc/dnf/mirrorlists.d/docker-ce-stable
baseurl=https://download.docker.com/linux/centos/9/$basearch/stable/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.aliyun.com/docker-ce/linux/centos/gpg
EOF
sudo dnf makecache --repo docker-ce-stable
$basearch will be resolved by DNF to either x86_64 or aarch64. The single quotes \u003c\u003c'EOF' preserve it so the shell does not expand it prematurely. When downloading packages from upstream, you can comment out the mirrorlist line; the GPG key can also be changed to the official URL https://download.docker.com/linux/centos/gpg.
3. Install and Start
sudo dnf install docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin curl
When DNF first imports the Docker repository’s GPG key, verify the fingerprint is:
060A 61C5 1B55 8A7F 742B 77AA C52F EB6B 621E 9F35
This fingerprint can be independently verified from the Docker official CentOS installation guide. While image downloads may vary, the RPMs are still signed by Docker’s key—no need to disable gpgcheck.
After installation, start the service and enable it at boot:
sudo systemctl enable --now docker
sudo docker version
sudo docker compose version
sudo docker buildx version
docker version should show both Client and Server. The repository package includes the service file; Compose and Buildx are installed via the RPMs above—no need to manually write docker.service or download plugins separately.
4. Run a Compose Project
For existing projects, enter the directory containing compose.yaml and run as instructed. Below is a brief example using an Nginx service:
mkdir -p "$HOME/docker-ce-demo"
cd "$HOME/docker-ce-demo"
cat > compose.yaml <<'EOF'
services:
web:
image: nginx:stable
ports:
- "127.0.0.1:8080:80"
restart: unless-stopped
EOF
sudo docker compose up -d
sudo docker compose ps
curl -f http://127.0.0.1:8080/
If the container runs and returns the Nginx welcome page, the basic installation is complete. If image pull times out, refer to the following sections on image or daemon proxy configuration, then retry docker compose up -d.
Port 8080 is bound only to the loopback address of the machine running Docker; curl executes on the server when accessed via SSH. Compose automatically creates a network for the project. restart: unless-stopped ensures containers restart with Docker unless manually stopped. The Compose command itself does not need to run continuously.
When no longer needed, run sudo docker compose down in the project directory. No need to reboot the entire machine immediately after installation; after maintenance window restarts, use sudo docker compose ps to verify project recovery.
Common Needs and Issues
Container Shows Up, but Service Is Unreachable
Run sudo docker compose logs --tail=50 web in the project directory to check if the application has started. “Up” only means the container process is running—not that the application is ready. For example, some Alpine-based Nginx images attempt to access the Alpine package repository in their entrypoint script. This access bypasses DNF and is unaffected by Docker Hub mirror settings. This guide uses the Debian-based nginx:stable image as an example.
Slow or Failed Pulls from Docker Hub
The software mirror used by DNF for RPMs is unrelated to the container image registry used by docker pull. The previous DNF repository configuration does not accelerate Docker Hub.
You may choose a trusted Docker Hub mirror. Here’s an example using 1ms.run: add the following to /etc/docker/daemon.json:
{
"registry-mirrors": ["https://docker.1ms.run"]
}
Create the directory if it doesn’t exist: sudo install -d -m 0755 /etc/docker, then edit with sudoedit /etc/docker/daemon.json. If the file already exists, merge the field instead of overwriting other options. Then validate and restart:
sudo dockerd --validate --config-file=/etc/docker/daemon.json
sudo systemctl restart docker
sudo docker info --format '{{json .RegistryConfig.Mirrors}}'
Confirm existing services can tolerate interruption before restarting. Public mirror availability may change; if the selected service remains slow, consider switching to https://docker.m.daocloud.io following DaoCloud’s instructions. These settings primarily affect Docker Hub and do not automatically proxy all registries. See Docker Registry mirror documentation.
Terminal Proxy Set, But Docker Still Can’t Pull Images
Images are pulled by the background dockerd, not the current terminal’s docker client. Shell proxy variables are usually not passed to systemd-managed services.
With a working HTTP proxy, run sudo systemctl edit docker and add:
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1,::1"
Replace the address with a proxy reachable from the Docker host. Here, 127.0.0.1 refers to the Docker host itself. Then:
sudo systemctl daemon-reload
sudo systemctl restart docker
Retry the pull. For internal registries, add them to NO_PROXY. Use sudo systemctl show --property=Environment docker to check if the service loaded the settings. If daemon.json already contains proxies, it takes precedence over environment variables—adjust the original config instead. This is a service-level HTTP proxy, not the same as registry-mirrors. See daemon proxy documentation.
Want to Run Docker Without sudo
sudo usermod -aG docker "$USER"
Log out and log back in for changes to take effect. The docker group grants privileges equivalent to root—only add trusted users. This is different from rootless Docker. See post-installation permissions guide.
DNF Downloads Slow or Can’t Find Packages
Check which repository the error corresponds to: openEuler’s OS/update sources handle system dependencies, while docker-ce-stable handles Docker RPMs. If the OS source fails, changing the Docker mirror won’t help.
If a specific mirror in the Docker repository is unreachable or hasn’t synced the latest version, adjust the local mirrorlist and refresh the metadata:
sudo dnf --refresh makecache --repo docker-ce-stable
dnf list --showduplicates docker-ce
Do not substitute openEuler’s version number into centos/9, nor add the entire CentOS system repository.
Migrate from Moby to Docker CE
This is a runtime and package replacement—schedule downtime and ensure recoverable backups. First complete the Docker CE repository setup, but do not run the full installation command yet.
First, record containers, volumes, networks, and data directories. Back up Compose files, bind-mounted data, and application data:
sudo docker ps -a
sudo docker volume ls
sudo docker network ls
DOCKER_ROOT=$(sudo docker info --format '{{.DockerRootDir}}')
Moby may enable live restore by default, so stop containers before stopping the daemon. The following backup example suits test machines with ample storage; production hosts should use appropriate filesystems or storage snapshots:
sudo docker ps -q | xargs -r sudo docker stop
sudo systemctl stop docker.service docker.socket containerd.service
BACKUP_DIR="$HOME/docker-before-ce-$(date +%Y%m%d-%H%M%S)"
sudo install -d -m 0700 "$BACKUP_DIR"
sudo cp -a --reflink=auto "$DOCKER_ROOT" "$BACKUP_DIR/docker-data"
for path in /var/lib/containerd /etc/docker /etc/sysconfig/docker; do
if sudo test -e "$path"; then
sudo cp -a --parents --reflink=auto "$path" "$BACKUP_DIR/"
fi
done
If you previously manually installed Compose, move the plugin to the backup directory to avoid overriding the RPM plugin’s priority:
if [ -e /usr/local/lib/docker/cli-plugins/docker-compose ]; then
sudo mv /usr/local/lib/docker/cli-plugins/docker-compose \
"$BACKUP_DIR/docker-compose.manual"
fi
Then replace packages in a single transaction:
sudo dnf swap moby docker-ce
sudo dnf install docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Review the DNF removal and installation list before committing. Replacing Moby and the distribution’s containerd/runc with corresponding components is expected. If removing unrelated software, cancel and check dependencies first.
Configuration in /etc/docker/daemon.json can be reused, but settings via /etc/sysconfig/docker and service parameters (like journald, live restore) won’t transfer automatically to Docker CE. Merge configurations as needed before starting, and check for old systemd override files.
Keep the original storage backend. Confirm existing data is visible before proceeding—do not combine migration with switching the containerd image store. Then start the service and restore containers in the original project directory:
sudo systemctl enable --now docker
sudo docker info
sudo docker compose up -d
sudo docker compose ps
Previously stopped containers using unless-stopped must be explicitly restored. Keep the backup until application verification completes. Uninstalling RPMs does not automatically clear data directories—but this does not mean you can always revert across arbitrary version gaps. See Docker storage backend documentation.
Logging and Routine Updates
sudo journalctl -b -u docker --no-pager -n 100
sudo docker info
sudo dnf upgrade docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
Check DNF transaction and Docker release notes before upgrading. To make new containers use the built-in local log driver with rotation, merge "log-driver": "local" into daemon.json. Existing containers retain their original log configuration and must be rebuilt according to project plans to adopt the new default. See log driver documentation.
If you encounter SELinux warnings during installation, investigate based on specific rules and service logs—do not disable SELinux outright. During Docker CE 29.8.1 installation, warnings like docker-af-alg-deny.cil and docker-af-vsock-deny.cil were reported. The engine and example containers ran successfully, but these additional deny rules failed to load—assess their security impact separately. Successful operation does not mean these protections are active, nor does it imply the entire container policy is uninstalled.
Verification: The installation method has been tested on openEuler 22.03 LTS SP4 and 24.03 LTS SP3 (x86_64/aarch64) with successful installation, Compose usage, and reboot verification. This update was validated on 24.03 LTS SP3 x86_64 with Docker CE 29.8.1, Compose 5.5.1, and Moby migration. Revision date: 2026-09-20