Candid photograph of a Linux server terminal with a soft olive-green glow against a dark slate background, conveying a calm technical atmosphere.

Step-by-step guides for system administrators — covering command-line basics, web server setup, and preparation material for technical interviews.

Browse Tutorials

Installing and configuring Docker on RHEL 9

Installing Docker on RHEL 9 gives system administrators a consistent engine for building, running and maintaining containers. It suits self-managed hosts, CI workers and hybrid estates where services must start predictably after a reboot.

RHEL 9 already includes Podman, which provides daemonless and rootless container operation. Docker remains useful where administrators need the Docker CLI, Compose plugin, familiar image workflows or compatibility with existing CI pipelines and registries.

This guide uses Docker Engine on an existing RHEL 9 system. Commands should be run with sudo until the service account has appropriate access, while production changes should follow the host’s patching, firewall and change-management procedures.

Prepare the RHEL 9 host

Start by confirming the RHEL entitlement, system architecture and available disk space. An active Red Hat subscription is required for the base RHEL repositories, while Docker Engine comes from Docker’s separate repository.

sudo subscription-manager status
uname -m
df -h /var/lib

Install the DNF plugin and add the official Docker repository for RHEL 9.

sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo \
  https://download.docker.com/linux/rhel/docker-ce.repo

Check for packages that provide the docker command before installation. Run rpm -q podman-docker; if it is installed but unused, sudo dnf remove podman-docker avoids a command conflict. The Linux commands collection provides useful references for inspecting packages, services and running processes.

Install Engine and confirm operation

Docker Engine is the appropriate choice for a managed RHEL server, while Podman remains attractive for rootless, daemonless workflows. Docker Desktop targets developer workstations rather than production RHEL hosts.

Runtime Service model Best suited to Main consideration
Docker CE dockerd managed by systemd RHEL servers, CI and existing Docker workflows Administrators maintain packages, storage and firewall rules
Podman Daemonless and rootless RHEL-native administration and Kubernetes Docker compatibility is close but not identical
Docker Desktop VM-backed developer engine Workstations running Linux, macOS or Windows Licensing terms apply; it is not a server installation

Install the engine, command-line client, container runtime, Buildx and Compose plugins.

sudo dnf install -y \
  docker-ce \
  docker-ce-cli \
  containerd.io \
  docker-buildx-plugin \
  docker-compose-plugin

Enable the daemon and run a disposable test container.

sudo systemctl enable --now docker
sudo docker run --rm hello-world

Administrators can then join the docker group with sudo usermod -aG docker "$USER". Log out and back in before testing without sudo. Membership grants root-equivalent control over the host, so limit it to trusted operators.

Configure daemon, storage and security

Begin with a small daemon.json that explicitly bounds container log growth. Merge these values into any existing configuration rather than discarding unrelated settings.

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

Validate the configuration before restarting the service.

sudo dockerd --validate --config-file=/etc/docker/daemon.json
sudo systemctl restart docker
sudo docker info

The logging limits apply to newly created containers, so recreate existing containers during the next planned rollout. Docker stores its data under /var/lib/docker by default; provision sufficient space and inodes for images, writable layers and volumes.

RHEL 9 commonly uses XFS, and the overlay2 storage driver requires XFS with ftype=1. Check the root filesystem with xfs_info / | grep ftype=1 before relocating Docker data. Leave SELinux enforcing: use the :Z suffix for a bind mount intended for one container, or :z for shared access between containers.

Operational checks for Australian deployments

Australian estates often combine AWS regions in Sydney and Melbourne with on-premises systems in Brisbane or Perth. Local managed-service providers, cloud marketplaces, Australian-dollar invoices and data-residency requirements all affect the buying decision, so compute, backups and network egress should be costed together.

Local operations language is equally practical: when an Australian sysadmin says “Docker’s up”, it may mean a test container ran rather than merely that the daemon process exists. Confirm both with docker info and docker ps. For archived business software, assess DOS4GW compatibility before assuming a Linux container is the appropriate migration path.

Before deployment

Before production sign-off

Establish a repeatable production baseline

Keep the Compose file or systemd unit, environment definitions and deployment scripts under version control. Use immutable image references, mount only required paths and run containers with a dedicated unprivileged account. Limit access to the root-equivalent docker group.

For scheduled exports or cleanup jobs, use a systemd unit instead of maintaining a long-running container. The systemd timer guide explains timer and cron patterns, including timezone handling. Set TZ=Australia/Sydney where daylight-saving changes apply, or TZ=Australia/Brisbane for Brisbane’s fixed offset, provided the image contains the required timezone data.

Record package versions, daemon.json, firewall decisions and image digests in the host change record. The next action in that record is a post-change validation: restart Docker, run docker run --rm hello-world, and attach the output to the change ticket.