How to install Docker CE on RHEL 8 - LinuxConfig.org

The latest release of the Red Hat Enterprise Linux distribution 8 does not officially support Docker. Red Hat has built its own tools, buildah and podman, which aim to be compatible with existing docker images and work without relying on a daemon, allowing the creation of containers as normal users, without the need of special permissions (with some limitations: e.g. at the moment of writing, it's still not possible to map host ports to the container without privileges).
This is a companion discussion topic for the original entry at https://linuxconfig.org/how-to-install-docker-in-rhel-8

Your article was very useful for me. It explained why it isn’t yet possible do install docker in CentOS 8. Clever solution, by the way!

But then “Hey, lets solve the docker networking problem by disabling the firewall entirely”. Dude… what?.. so much effort in the article (very complete, by the way) and then you just disable the one protection that’s obviously indispensable for a Linux system?

Happy and thankful for the article, but very disappointed security-wise. You could at least indicate a firewall alternative that works or some firewalld configuration that would work.

Thank you for your comment. What you say is right, but I never suggested to disable the firewall, I just stated that doing so would resolve the dns resolution problem, but at the same time, I presented the problem as critical:

[…] as long as firewalld, the system firewall manager is enabled, DNS resolution inside docker containers does not work.

This is, of course a critical problem. However, if you still want to proceed with the installation, here are the possible methods that can be used to avoid the dependencies issues:[…]

I guess that this critical issue could be highlighted more, so thanks for your suggestion, I’ll keep it in mind.

Is there a reason why Red Hat decided to NOT support docker original and created its own tools??

I tried the first way and installed docker-ce-3:18.09.1-3.el7 on my CentOS 8, but failed to start docker.service whatever I enable/disable firewalld,

Here’s the error I found in /var/log/messages, any help is appreciated.

Nov 14 02:16:13 angel-d systemd[1]: Starting Docker Application Container Engine…
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.829690273-08:00” level=info msg=“parsed scheme: “unix”” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.829756654-08:00” level=info msg=“scheme “unix” not registered, fallback to default scheme” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.829795110-08:00” level=info msg=“parsed scheme: “unix”” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.829803059-08:00” level=info msg=“scheme “unix” not registered, fallback to default scheme” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.829812548-08:00” level=info msg=“ccResolverWrapper: sending new addresses to cc: [{unix:///run/containerd/containerd.sock 0 }]” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.829842481-08:00” level=info msg=“ClientConn switching balancer to “pick_first”” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.829885243-08:00” level=info msg=“pickfirstBalancer: HandleSubConnStateChange: 0xc4202363f0, CONNECTING” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.829897195-08:00” level=info msg=“ccResolverWrapper: sending new addresses to cc: [{unix:///run/containerd/containerd.sock 0 }]” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.829931111-08:00” level=info msg=“ClientConn switching balancer to “pick_first”” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.830028778-08:00” level=info msg=“pickfirstBalancer: HandleSubConnStateChange: 0xc4202363f0, READY” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.830061258-08:00” level=info msg=“pickfirstBalancer: HandleSubConnStateChange: 0xc4206e0010, CONNECTING” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.830066982-08:00” level=info msg=“blockingPicker: the picked transport is not ready, loop back to repick” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.830306464-08:00” level=info msg=“pickfirstBalancer: HandleSubConnStateChange: 0xc4206e0010, READY” module=grpc
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.831805145-08:00” level=info msg="[graphdriver] using prior storage driver: overlay2"
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.833618771-08:00” level=info msg=“Graph migration to content-addressability took 0.00 seconds”
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.834261507-08:00” level=info msg=“Loading containers: start.”
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.918598251-08:00” level=info msg=“stopping event stream following graceful shutdown” error="" module=libcontainerd namespace=moby
Nov 14 02:16:13 angel-d dockerd[8571]: Error starting daemon: Error initializing network controller: error obtaining controller instance: failed to create NAT chain DOCKER: iptables failed: iptables -t nat -N DOCKER: iptables v1.8.2 (nf_tables): CHAIN_ADD failed (No such file or directory): chain PREROUTING
Nov 14 02:16:13 angel-d dockerd[8571]: (exit status 4)
Nov 14 02:16:13 angel-d dockerd[8571]: time=“2019-11-14T02:16:13.918850632-08:00” level=info msg=“stopping event stream following graceful shutdown” error=“context canceled” module=libcontainerd namespace=plugins.moby
Nov 14 02:16:13 angel-d systemd[1]: docker.service: Main process exited, code=exited, status=1/FAILURE

i think Red-hat 8 they create there own

Just wanted to say thanks this worked for me

Thanks for the article, but NEVER EVER disable the firewall.

To get DNS resolution working, simply enable Masquerading:

firewall-cmd --zone=public  --add-masquerade --permanent
firewall-cmd --reload

Hi robos,
You are right, disabling the firewall is never a good idea. By the way, I never suggested to do so, but simply confirmed that with the firewall disabled the dns resolution was working. At the time of writing I didn’t know the one you suggested could be a fix to the problem. I recently wrote an article about solving the same problem on Fedora 32, you can read it here if you want. In the article I suggest another possible solution: putting the docker0 interface under the trusted zone:

$ sudo firewall-cmd --permanent --zone=trusted  --add-interface=docker0 && sudo firewall-cmd --reload

By the way, your comment reminded me to update this article, thank you.

After much frustration trying to get podman to work (“Oh, it’s a drop-in replacement for docker, seamless, we promise”) this article finally got me sorted. Thank you so much.

1 Like

Why everybody still believes that the only possible Home network configuration is standalone computer connected to the wall? Today ISP supply Linux based routers or mesh kits with their own iptables based firewall, own port forwarding, and NAT and other networking packages. In other words, the popular network layout looks like:
PoP -> broadbend internet -> Linux on Router -> Windows -> WSL Linux distro. With duble firewall, double NAT, double port forwarding, double DNZ, etc.
I hope to hack my router inspite of reistance of my ISP and install recent OpenWRT version with all missed packages. There is plenty of Linux distros for budget ARM to put them in front of PC.

Hi EgDoc,

I checked the two fixes with busybox container .
The masquerade fix is fine with both “docker” and “docker-compose”
But the add-interface way can only work with “docker”

There seems to be another variation that worked well for me:

  • Disable firewalld and then enable nftables.

nftables on Centos 8 seems to expose an iptables interface for backwards compatibility, and Docker will use it automatically when it starts (like it would on a host running just iptables before nftables) to add the masquerade and filtering rules that Docker needs to function normally.

These are the steps I took.

Disable Firewalld
# systemctl disable --now firewalld
# systemctl mask firewalld
# reboot

Enable the default nftables filter
# vi /etc/sysconfig/nftables.conf
and uncomment the following line:
include "/etc/nftables/main.nft"

Enable nftables
# systemctl enable --now nftables

Restart Docker
# systemctl restart docker

Check that Docker added nftable rules using iptables
# nft list ruleset

NOTE: the initial nftables ruleset in /etc/nftables/main.nft also recognizes a more compact (and for me, more readable) format similar to the original iptables notation. An example (of what used to be the default) iptables ruleset converted to nftables (which can be directly substituted for the default content in /etc/nftables/main.nft) is:

# Translated by iptables-restore-translate v1.8.4 on Sat Aug  8 03:20:21 2020
add table ip filter
add chain ip filter INPUT { type filter hook input priority 0; policy drop; }
add chain ip filter FORWARD { type filter hook forward priority 0; policy drop; }
add chain ip filter OUTPUT { type filter hook output priority 0; policy accept; }
add rule ip filter INPUT ct state related,established  counter accept
add rule ip filter INPUT ip protocol icmp counter accept
add rule ip filter INPUT iifname "lo" counter accept
add rule ip filter INPUT ct state new tcp dport { ssh, 9090} counter accept
add rule ip filter INPUT counter reject with icmp type host-prohibited
add rule ip filter FORWARD counter reject with icmp type host-prohibited

If you want to allow all local traffic (e.g. 172.16.1.0/24) to the Docker host, insert another INPUT filter:
add rule ip filter INPUT ip saddr 172.16.1.0/24 ct state new counter accept

In my case (running latest Centos8 AMI on AWS as of 10.2020) installing nftables didn’t work.
To install docker on a fresh Centos8 install i had to:

dnf -y install iptables --nobest 
dnf -y install iptables-services --nobest 
systemctl enable iptables.service 
systemctl enable ip6tables.service 
systemctl start iptables.service 
systemctl start ip6tables.service 
dnf -y install docker-ce --nobest 
systemctl enable --now docker 
systemctl restart --now docker

Docker released a CentOS8 specific containerd package. So it is not required to install the CentOS7 Docker package anymore:

sudo yum install -y yum-utils
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install containerd.io --nobest
sudo dnf install docker-ce
sudo systemctl enable docker --now

As said before: Do not disable the firewalld firewall. Instead either place the docker interface into the trusted zone or (as I recommend), pre-create the DOCKER-USER and DOCKER chains in firewalld and use firewalld direct rules to configure what is allowed from public to the containers before starting docker:

systemctl stop docker
firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER
firewall-cmd --permanent --direct --add-chain ipv4 filter DOCKER-USER
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -m comment --comment 'Allow docker containers to connect to the outside world'
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j RETURN -s 172.16.0.0/16 -m comment --comment 'allow internal docker communication'
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j RETURN -s 172.17.0.0/16 -m comment --comment 'allow internal container communication'
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j RETURN -s 172.18.0.0/16 -m comment --comment 'allow internal container communication'
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j RETURN -s 172.19.0.0/16 -m comment --comment 'allow internal container communication'
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j RETURN -s 172.20.0.0/16 -m comment --comment 'allow internal container communication'
# Allowed for public
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -p tcp -m multiport --dports 80,443 -j ACCEPT -m comment --comment 'Allow HTTP / HTTPS for public'
# Reject all other
firewall-cmd --permanent --direct --add-rule ipv4 filter DOCKER-USER 0 -j REJECT -m comment --comment 'reject all other traffic to DOCKER-USER'
firewall-cmd --reload

systemctl start docker