Install and Use Docker on Rocky Linux 9

06 Jul 2023 - rich

This is a brief description of how to get docker installed and how to use it on Rocky Linux 9. This should work as well on Alma.
I’m assuming here that all software packages (except docker) are installed or, if the are not, that they can be easily installed.
This document will also go through the steps to insure that docker can be run without having root access or sudo access.

Install Docker


Using DNF

update the package database

$ sudo dnf check-update

Last metadata expiration check: 0:02:16 ago on Thu 06 Jul 2023 02:54:18 PM EDT.

ImageMagick.x86_64                                 epel
ImageMagick-devel.x86_64                           epel
ImageMagick-libs.x86_64                            epel
ModemManager.x86_64                    1.20.2-1.el9                         baseos
ModemManager-glib.x86_64               1.20.2-1.el9                         baseos

add Centos docker registry

Rocky and Alma are based on Centos Linux code. There are no Docker/Rocky repos but you should be able to use either Centos or (maybe) Fedora. Add the Docker repo using the Centos bits…

$ sudo dnf config-manager –add-repo

[sudo] password for xxxxx:
Adding repo from:

Install Docker for Rocky using Centos

$ sudo dnf install docker-ce docker-ce-cli

Last metadata expiration check: 0:01:28 ago on Thu 06 Jul 2023 02:54:18 PM EDT.
Dependencies resolved.

 Package                                                    Architecture               Version          
Installing:                                                x86_64                1.6.21-3.1.el9    
     replacing  runc.x86_64 4:1.1.3-2.el9_0
 docker-ce                                                    x86_64                3:24.0.3-1.el9    
 docker-ce-cli                                                x86_64                1:24.0.3-1.el9    
 buildah                                                      x86_64                1:1.29.1-2.el9_2  
Installing dependencies:
 docker-ce-rootless-extras                                    x86_64                24.0.3-1.el9      
Installing weak dependencies:
 docker-buildx-plugin                                         x86_64                0.11.1-1.el9      
 docker-compose-plugin                                        x86_64                2.19.1-1.el9     

Transaction Summary
Install  6 Packages
Upgrade  1 Package

Total download size: 101 M
Is this ok [y/N]: y
Downloading Packages:

Start and Enable Docker daemon

$ sudo systemctl start docker

[sudo] password for xxxxx:

$ sudo systemctl enable docker

Created symlink /etc/systemd/system/ → /usr/lib/systemd/system/docker.service.

Check Docker is running

$ sudo systemctl status docker

● docker.service - Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
     Active: active (running) since Thu 2023-07-06 16:43:48 EDT; 16s ago
TriggeredBy: ● docker.socket
   Main PID: 1215167 (dockerd)
      Tasks: 8
     Memory: 31.2M
        CPU: 167ms
     CGroup: /system.slice/docker.service
             └─1215167 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Jul 06 16:43:36 rocky9-cloneme systemd[1]: Starting Docker Application Container Engine...
Jul 06 16:43:36 rocky9-cloneme dockerd[1215167]: time="2023-07-06T16:43:36.787570198-04:00" level=info msg="Starting up"
Jul 06 16:43:36 rocky9-cloneme dockerd[1215167]: time="2023-07-06T16:43:36.811787843-04:00" level=info msg="Loading containers: start."
Jul 06 16:43:48 rocky9-cloneme dockerd[1215167]: time="2023-07-06T16:43:48.535813414-04:00" level=info msg="Firewalld: interface docker0 already part of docker zone, returning"
Jul 06 16:43:48 rocky9-cloneme dockerd[1215167]: time="2023-07-06T16:43:48.654968687-04:00" level=info msg="Loading containers: done."
Jul 06 16:43:48 rocky9-cloneme dockerd[1215167]: time="2023-07-06T16:43:48.667577271-04:00" level=info msg="Docker daemon" commit=1d9c861 graphdriver=overlay2 version=24.0.3
Jul 06 16:43:48 rocky9-cloneme dockerd[1215167]: time="2023-07-06T16:43:48.667677375-04:00" level=info msg="Daemon has completed initialization"
Jul 06 16:43:48 rocky9-cloneme dockerd[1215167]: time="2023-07-06T16:43:48.686395040-04:00" level=info msg="API listen on /run/docker.sock"
Jul 06 16:43:48 rocky9-cloneme systemd[1]: Started Docker Application Container Engine.

Run Docker without sudo

docker requires root privileges. without creating and adding users to a docker group, they would need to type sudo before the docker command they want to run this would also assume that they have sudo access to do this.

Add user(s) to Docker group

$ sudo usermod -aG docker $(whoami)

Docker Commands

To see if docker is working, you have docker group access, and to get a list of docker commands, type:

$ docker

Usage:  docker [OPTIONS] COMMAND

A self-sufficient runtime for containers

Common Commands:
  run         Create and run a new container from an image
  exec        Execute a command in a running container
  ps          List containers
  build       Build an image from a Dockerfile
  pull        Download an image from a registry
  push        Upload an image to a registry
  images      List images
  login       Log in to a registry
  logout      Log out from a registry
  search      Search Docker Hub for images
  version     Show the Docker version information
  info        Display system-wide information

Management Commands:
  builder     Manage builds
  buildx*     Docker Buildx (Docker Inc., v0.11.1)
  compose*    Docker Compose (Docker Inc., v2.19.1)
  container   Manage containers
  context     Manage contexts
  image       Manage images
  manifest    Manage Docker image manifests and manifest lists
  network     Manage networks
  plugin      Manage plugins
  system      Manage Docker
  trust       Manage trust on Docker images
  volume      Manage volumes

Swarm Commands:
  swarm       Manage Swarm

  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  events      Get real time events from the server
  export      Export a container's filesystem as a tar archive
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Return low-level information on Docker objects
  kill        Kill one or more running containers
  load        Load an image from a tar archive or STDIN
  logs        Fetch the logs of a container
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  rmi         Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

Global Options:
      --config string      Location of client config files (default "/home/richg/.docker")
  -c, --context string     Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
  -D, --debug              Enable debug mode
  -H, --host list          Daemon socket to connect to
  -l, --log-level string   Set the logging level ("debug", "info", "warn", "error", "fatal") (default "info")
      --tls                Use TLS; implied by --tlsverify
      --tlscacert string   Trust certs signed only by this CA (default "/home/richg/.docker/ca.pem")
      --tlscert string     Path to TLS certificate file (default "/home/richg/.docker/cert.pem")
      --tlskey string      Path to TLS key file (default "/home/richg/.docker/key.pem")
      --tlsverify          Use TLS and verify the remote
  -v, --version            Print version information and quit

Run 'docker COMMAND --help' for more information on a command.

For more help on how to use Docker, head to

get docker info from your system

$ docker info

Client: Docker Engine - Community
 Version:    24.0.3
 Context:    default
 Debug Mode: false
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.11.1
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.19.1
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

 Containers: 0
  Running: 0
  Paused: 0
  Stopped: 0
 Images: 0
 Server Version: 24.0.3
 Storage Driver: overlay2
  Backing Filesystem: xfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 3dce8eb055cbb6872793272b4f20ed16117344f8
 runc version: v1.1.7-0-g860f061
 init version: de40ad0
 Security Options:
   Profile: builtin
 Kernel Version: 5.14.0-70.26.1.el9_0.x86_64
 Operating System: Rocky Linux 9.0 (Blue Onyx)
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 3.636GiB
 Name: rocky9-cloneme
 ID: 6108b274-799f-4fb1-ba89-f85a08ce32ec
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
 Live Restore Enabled: false


Docker Images

Access and Download test image from Docker Hub

$ docker run hello-world

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
719385e32844: Pull complete
Digest: sha256:a13ec89cdf897b3e551bd9f89d499db6ff3a7f44c5b9eb8bca40da20eb4ea1fa
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:

For more examples and ideas, visit:

Search Docker Images

$ docker search rockylinux

NAME                                                DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
rockylinux                                          The official build of Rocky Linux.              161       [OK]
rockylinux/rockylinux                                                                               60
kasmweb/rockylinux-9-desktop                        Rocky Linux 9 desktop for Kasm Workspaces       0

$ docker search jenkins

NAME                           DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
jenkins                        DEPRECATED; use "jenkins/jenkins:lts" instead   5632      [OK]
jenkins/jenkins                The leading open source automation server       3594
jenkins/jnlp-slave             a Jenkins agent which can connect to Jenkins…   156                  [OK]
jenkins/ssh-agent              Docker image for Jenkins agents connected ov…   40
jenkins/inbound-agent                                                          105
jenkins/slave                  base image for a Jenkins Agent, which includ…   49                   [OK]
jenkins/jnlp-agent-maven       A JNLP-based agent with Maven 3 built in        9
bitnami/jenkins                Bitnami Docker Image for Jenkins                63                   [OK]
jenkins/ssh-slave              A Jenkins slave using SSH to establish conne…   38                   [OK]
jenkins/agent                                                                  56
jenkins/jnlp-agent-ruby                                                        1
jenkins/jnlp-agent-docker                                                      8
jenkins/jnlp-agent-node                                                        1
jenkins/jnlp-agent-python      A JNLP-based agent with Python built in         3

Pull Docker Images

$ docker pull jenkins/jenkins:latest

latest: Pulling from jenkins/jenkins
93c2d578e421: Already exists
77b97c2ff987: Pull complete
1536c617ae13: Pull complete
24565670b535: Pull complete
3a5e4d5386c8: Pull complete
7fdd59a5bf10: Pull complete
a410f8c85e5b: Pull complete
422a17265fab: Pull complete
d64be9b34ff6: Pull complete
6f269ecf918f: Pull complete
7442d1d88c7b: Pull complete
295549a93c31: Pull complete
d29ce47fca97: Pull complete
Digest: sha256:c9a1bba477d3b9f29c27337d7d537c0926168ab8073b07067a42dda1a35b07f4
Status: Downloaded newer image for jenkins/jenkins:latest

list docker images

$ docker image ls

REPOSITORY        TAG       IMAGE ID       CREATED        SIZE
jenkins/jenkins   latest    e38af11ce616   2 days ago     462MB
jenkins/jenkins   lts       825c3e86c65d   8 days ago     471MB
hello-world       latest    9c7a54a9a43c   2 months ago   13.3kB

Running Docker


docker run command

$ docker run –help

Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Create and run a new container from an image

  docker container run, docker run

      --add-host list                  Add a custom host-to-IP mapping (host:ip)
      --annotation map                 Add an annotation to the container (passed through to the OCI runtime) (default map[])
  -a, --attach list                    Attach to STDIN, STDOUT or STDERR
      --blkio-weight uint16            Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
      --blkio-weight-device list       Block IO weight (relative device weight) (default [])
      --cap-add list                   Add Linux capabilities
      --cap-drop list                  Drop Linux capabilities
      --cgroup-parent string           Optional parent cgroup for the container
      --cgroupns string                Cgroup namespace to use (host|private)
                                       'host':    Run the container in the Docker host's cgroup namespace
                                       'private': Run the container in its own private cgroup namespace
                                       '':        Use the cgroup namespace as configured by the
                                                  default-cgroupns-mode option on the daemon (default)
      --cidfile string                 Write the container ID to the file
      --cpu-period int                 Limit CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int                  Limit CPU CFS (Completely Fair Scheduler) quota
      --cpu-rt-period int              Limit CPU real-time period in microseconds
      --cpu-rt-runtime int             Limit CPU real-time runtime in microseconds
  -c, --cpu-shares int                 CPU shares (relative weight)
      --cpus decimal                   Number of CPUs
      --cpuset-cpus string             CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string             MEMs in which to allow execution (0-3, 0,1)
  -d, --detach                         Run container in background and print container ID
      --detach-keys string             Override the key sequence for detaching a container
      --device list                    Add a host device to the container
      --device-cgroup-rule list        Add a rule to the cgroup allowed devices list
      --device-read-bps list           Limit read rate (bytes per second) from a device (default [])
      --device-read-iops list          Limit read rate (IO per second) from a device (default [])
      --device-write-bps list          Limit write rate (bytes per second) to a device (default [])
      --device-write-iops list         Limit write rate (IO per second) to a device (default [])
      --disable-content-trust          Skip image verification (default true)
      --dns list                       Set custom DNS servers
      --dns-option list                Set DNS options
      --dns-search list                Set custom DNS search domains
      --domainname string              Container NIS domain name
      --entrypoint string              Overwrite the default ENTRYPOINT of the image
  -e, --env list                       Set environment variables
      --env-file list                  Read in a file of environment variables
      --expose list                    Expose a port or a range of ports
      --gpus gpu-request               GPU devices to add to the container ('all' to pass all GPUs)
      --group-add list                 Add additional groups to join
      --health-cmd string              Command to run to check health
      --health-interval duration       Time between running the check (ms|s|m|h) (default 0s)
      --health-retries int             Consecutive failures needed to report unhealthy
      --health-start-period duration   Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)
      --health-timeout duration        Maximum time to allow one check to run (ms|s|m|h) (default 0s)
      --help                           Print usage
  -h, --hostname string                Container host name
      --init                           Run an init inside the container that forwards signals and reaps processes
  -i, --interactive                    Keep STDIN open even if not attached
      --ip string                      IPv4 address (e.g.,
      --ip6 string                     IPv6 address (e.g., 2001:db8::33)
      --ipc string                     IPC mode to use
      --isolation string               Container isolation technology
      --kernel-memory bytes            Kernel memory limit
  -l, --label list                     Set meta data on a container
      --label-file list                Read in a line delimited file of labels
      --link list                      Add link to another container
      --link-local-ip list             Container IPv4/IPv6 link-local addresses
      --log-driver string              Logging driver for the container
      --log-opt list                   Log driver options
      --mac-address string             Container MAC address (e.g., 92:d0:c6:0a:29:33)
  -m, --memory bytes                   Memory limit
      --memory-reservation bytes       Memory soft limit
      --memory-swap bytes              Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --memory-swappiness int          Tune container memory swappiness (0 to 100) (default -1)
      --mount mount                    Attach a filesystem mount to the container
      --name string                    Assign a name to the container
      --network network                Connect a container to a network
      --network-alias list             Add network-scoped alias for the container
      --no-healthcheck                 Disable any container-specified HEALTHCHECK
      --oom-kill-disable               Disable OOM Killer
      --oom-score-adj int              Tune host's OOM preferences (-1000 to 1000)
      --pid string                     PID namespace to use
      --pids-limit int                 Tune container pids limit (set -1 for unlimited)
      --platform string                Set platform if server is multi-platform capable
      --privileged                     Give extended privileges to this container
  -p, --publish list                   Publish a container's port(s) to the host
  -P, --publish-all                    Publish all exposed ports to random ports
      --pull string                    Pull image before running ("always", "missing", "never") (default "missing")
  -q, --quiet                          Suppress the pull output
      --read-only                      Mount the container's root filesystem as read only
      --restart string                 Restart policy to apply when a container exits (default "no")
      --rm                             Automatically remove the container when it exits
      --runtime string                 Runtime to use for this container
      --security-opt list              Security Options
      --shm-size bytes                 Size of /dev/shm
      --sig-proxy                      Proxy received signals to the process (default true)
      --stop-signal string             Signal to stop the container
      --stop-timeout int               Timeout (in seconds) to stop a container
      --storage-opt list               Storage driver options for the container
      --sysctl map                     Sysctl options (default map[])
      --tmpfs list                     Mount a tmpfs directory
  -t, --tty                            Allocate a pseudo-TTY
      --ulimit ulimit                  Ulimit options (default [])
  -u, --user string                    Username or UID (format: <name|uid>[:<group|gid>])
      --userns string                  User namespace to use
      --uts string                     UTS namespace to use
  -v, --volume list                    Bind mount a volume
      --volume-driver string           Optional volume driver for the container
      --volumes-from list              Mount volumes from the specified container(s)
  -w, --workdir string                 Working directory inside the container

Note –rm

when you exit the container it will continue running… this is fine if your expectation is that this is a long running container.

if you want to remove the container upon exist, you need to specify –rm or remove the container manually after you exit.

run docker container detached

$ docker container run -d –rm jenkins/jenkins:latest

run docker interactive terminal

$ docker container run -it jenkins:jenkins:latest

Running from: /usr/share/jenkins/jenkins.war
webroot: /var/jenkins_home/war
2023-07-07 03:01:07.922+0000 [id=1]	INFO	winstone.Logger#logInternal: Beginning extraction from war file

Docker Containers


Listing Docker Containers

$ docker container ps

CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS          PORTS                 NAMES
55cc8e718642   jenkins/jenkins:latest   "/usr/bin/tini -- /u…"   21 minutes ago   Up 21 minutes   8080/tcp, 50000/tcp   sad_noyce

to view all containers

$ docker container ps -a

CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS                        PORTS                 NAMES
55cc8e718642   jenkins/jenkins:latest   "/usr/bin/tini -- /u…"   21 minutes ago   Up 21 minutes                 8080/tcp, 50000/tcp   sad_noyce
f78c338d94e2   jenkins/jenkins:latest   "/usr/bin/tini -- /u…"   27 minutes ago   Exited (130) 26 minutes ago                         affectionate_roentgen
44e6db87a486   jenkins/jenkins:latest   "/usr/bin/tini -- /u…"   28 minutes ago   Exited (130) 27 minutes ago                         nervous_swirles
c4025bd99246   hello-world              "/hello"                 7 hours ago      Exited (0) 7 hours ago                              relaxed_wilbur

Stopping running / active containers

Since this container was run using the –rm flag, when you stop it the container will be removed.

for the container id, the entire string does not need to be specified, just the first several characters to insure that it is unique

$ docker container stop 55cc


Listing all the containers shows that this container has been removed (it is no longer present / listed)

$ docker container ps -a

CONTAINER ID   IMAGE                    COMMAND                  CREATED          STATUS                        PORTS     NAMES
f78c338d94e2   jenkins/jenkins:latest   "/usr/bin/tini -- /u…"   32 minutes ago   Exited (130) 31 minutes ago             affectionate_roentgen
44e6db87a486   jenkins/jenkins:latest   "/usr/bin/tini -- /u…"   34 minutes ago   Exited (130) 32 minutes ago             nervous_swirles
c4025bd99246   hello-world              "/hello"                 7 hours ago      Exited (0) 7 hours ago                  relaxed_wilbur

Removing Docker Containers

$ docker container rm c4025


$ docker container ps -a

CONTAINER ID   IMAGE                    COMMAND                  CREATED             STATUS                           PORTS     NAMES
f78c338d94e2   jenkins/jenkins:latest   "/usr/bin/tini -- /u…"   About an hour ago   Exited (130) About an hour ago             affectionate_roentgen
44e6db87a486   jenkins/jenkins:latest   "/usr/bin/tini -- /u…"   About an hour ago   Exited (130) About an hour ago             nervous_swirles

Pushing Docker Images

(perhaps later)