Skip to content
Search RunEntLinux

Searches general documentation on RunEntLinux. Each distribution has its own documentation search.

    Browse this documentation

    Docker Installation and Usage

    Docker provides an official repository for enterprise Linux. The following steps apply to RHEL, CentOS Stream, AlmaLinux, Rocky Linux, and other EL-based distributions.

    Terminal window
    # Install the DNF plugin that provides config-manager
    sudo dnf install -y dnf-plugins-core
    # RHEL uses Docker's rhel repository (not the centos one)
    sudo dnf config-manager --add-repo \
    https://download.docker.com/linux/rhel/docker-ce.repo
    1. Install Docker Engine, CLI, and container runtime:

      Terminal window
      sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
    2. Start Docker and enable it at boot:

      Terminal window
      sudo systemctl enable --now docker
    3. Verify the installation:

      Terminal window
      sudo docker version
      sudo docker run hello-world
    4. (Optional) Add the current user to the docker group to avoid using sudo every time:

      Terminal window
      sudo usermod -aG docker $(whoami)

      Log out and log back in for the change to take effect.

    Terminal window
    # Pull images from Docker Hub
    docker pull nginx:latest
    docker pull almalinux:9
    # Search for images
    docker search mariadb
    # View local images
    docker images
    Terminal window
    # Run in the foreground, automatically remove on exit
    docker run --rm -it almalinux:9 /bin/bash
    # Run Nginx in the background
    docker run -d --name my-nginx -p 80:80 nginx:latest
    # Run MariaDB with environment variables and volume mounts
    docker run -d --name my-db \
    -p 3306:3306 \
    -e MYSQL_ROOT_PASSWORD=your_password \
    -v /data/mysql:/var/lib/mysql \
    mariadb:10.11
    Terminal window
    # View running containers
    docker ps
    # View all containers
    docker ps -a
    # View container logs
    docker logs my-nginx
    docker logs -f --tail 100 my-nginx
    # View container details
    docker inspect my-nginx
    # View container resource usage
    docker stats
    Terminal window
    # Stop a container
    docker stop my-nginx
    # Start a stopped container
    docker start my-nginx
    # Restart a container
    docker restart my-nginx
    # Remove a stopped container
    docker rm my-nginx
    # Force remove a running container
    docker rm -f my-nginx
    # Remove all stopped containers
    docker container prune
    # Remove unused images
    docker image prune -a
    Terminal window
    # Enter a container with an interactive terminal
    docker exec -it my-nginx /bin/bash
    # Execute a command inside a container
    docker exec my-nginx nginx -t

    Docker Compose is used to define and manage multi-container applications. Docker CE includes the docker compose subcommand (V2) out of the box.

    Create docker-compose.yml:

    services:
    web:
    image: nginx:latest
    ports:
    - "80:80"
    - "443:443"
    volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf:ro
    - ./html:/usr/share/nginx/html:ro
    - certbot_data:/etc/letsencrypt:ro
    depends_on:
    - app
    restart: unless-stopped
    app:
    build: ./app
    expose:
    - "8000"
    environment:
    - DATABASE_URL=mysql://root:changeme@db:3306/myapp
    depends_on:
    - db
    restart: unless-stopped
    db:
    image: mariadb:10.11
    environment:
    MYSQL_ROOT_PASSWORD: changeme
    MYSQL_DATABASE: myapp
    volumes:
    - db_data:/var/lib/mysql
    restart: unless-stopped
    redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
    db_data:
    certbot_data:
    Terminal window
    # Start all services (in the background)
    docker compose up -d
    # View service status
    docker compose ps
    # View logs
    docker compose logs -f
    # View logs for a specific service only
    docker compose logs -f app
    # Rebuild and start
    docker compose up -d --build
    # Stop all services
    docker compose down
    # Stop and remove data volumes
    docker compose down -v
    # Scale service instances
    docker compose up -d --scale app=3
    FROM almalinux:9-minimal
    RUN microdnf install -y python3 python3-pip && \
    microdnf clean all
    WORKDIR /app
    COPY requirements.txt .
    RUN pip3 install --no-cache-dir -r requirements.txt
    COPY . .
    EXPOSE 8000
    USER 1001
    CMD ["python3", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
    Terminal window
    # Build the image
    docker build -t my-app:v1 .
    # Tag the image
    docker tag my-app:v1 registry.example.com/my-app:v1
    # Push to a private registry
    docker push registry.example.com/my-app:v1

    Docker uses the overlay2 storage driver by default on EL systems, which is the recommended option.

    Terminal window
    docker info | grep "Storage Driver"

    Edit or create /etc/docker/daemon.json:

    {
    "storage-driver": "overlay2",
    "data-root": "/data/docker",
    "log-driver": "json-file",
    "log-opts": {
    "max-size": "100m",
    "max-file": "3"
    },
    "registry-mirrors": [
    "https://mirror.example.com"
    ]
    }

    Restart Docker to apply the configuration:

    Terminal window
    sudo systemctl restart docker

    To migrate Docker data from the default /var/lib/docker to a new location:

    1. Stop Docker:

      Terminal window
      sudo systemctl stop docker
    2. Copy existing data:

      Terminal window
      sudo rsync -aP /var/lib/docker/ /data/docker/
    3. Set data-root in /etc/docker/daemon.json:

      {
      "data-root": "/data/docker"
      }
    4. Start Docker and verify:

      Terminal window
      sudo systemctl start docker
      docker info | grep "Docker Root Dir"
    5. After confirming everything works, remove the old directory:

      Terminal window
      sudo rm -rf /var/lib/docker

    Docker manages its own iptables rules. When firewalld is running, Docker automatically creates a docker zone (target=ACCEPT) and adds bridges such as docker0 to it, so you do not need to add docker0 to the trusted zone by hand — that is an old workaround and conflicts with Docker’s own rules.

    Terminal window
    # Confirm Docker's own zone and which bridges belong to it
    sudo firewall-cmd --get-zones | tr ' ' '\n' | grep -x docker
    sudo firewall-cmd --zone=docker --list-all
    Terminal window
    # View Docker disk usage
    docker system df
    # Comprehensive cleanup of unused resources
    docker system prune -a --volumes
    # Export a container as an image
    docker commit my-nginx my-nginx-backup:latest
    # Export/import image files
    docker save -o nginx-backup.tar nginx:latest
    docker load -i nginx-backup.tar