No internet access from docker continers hosted on OpenWrt

I'm running OpenWrt 22.03.0 on a x86 Zimaboard with dockerd installed.

Accessing the internet from inside a container e.g. for obtaining a Let's Encrypt certificate or curl any website alwasy ends with a "connection refused" error. I can access the service running inside a container from WAN and LAN interface, but there is no internet access from inside a container.

Firewall settings are unchanged from stock except opening WAN Port 80 and 443.

root@OpenWrt:/etc/config# cat firewall

config defaults
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option synflood_protect '1'

config zone
	option name 'lan'
	list network 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'

config zone
	option name 'wan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'wan'
	list network 'wan6'

config forwarding
	option src 'lan'
	option dest 'wan'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option target 'ACCEPT'
	option family 'ipv4'

config rule
	option name 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-DHCPv6'
	option src 'wan'
	option proto 'udp'
	option dest_port '546'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'wan'
	option dest '*'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config zone 'docker'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	option name 'docker'
	list network 'docker'

config rule
	option name 'Allow-HTTP-WAN'
	list proto 'tcp'
	option src 'wan'
	option dest_port '80'
	option target 'ACCEPT'

config rule
	option name 'Allow-HTTPS-WAN'
	list proto 'tcp'
	option src 'wan'
	option dest_port '443'
	option target 'ACCEPT'

root@OpenWrt:~# netstat -lpn

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      4179/docker-proxy
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      2284/uhttpd
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      3597/dnsmasq
tcp        0      0 192.168.1.1:53          0.0.0.0:*               LISTEN      3597/dnsmasq
tcp        0      0 172.17.0.1:53           0.0.0.0:*               LISTEN      3597/dnsmasq
tcp        0      0 172.18.0.1:53           0.0.0.0:*               LISTEN      3597/dnsmasq
tcp        0      0 172.19.0.1:53           0.0.0.0:*               LISTEN      3597/dnsmasq
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1987/dropbear
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      4135/docker-proxy
tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN      2284/uhttpd
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      4067/docker-proxy
tcp        0      0 192.168.1.1:7681        0.0.0.0:*               LISTEN      2899/ttyd
tcp        0      0 0.0.0.0:9443            0.0.0.0:*               LISTEN      4014/docker-proxy
tcp        0      0 :::80                   :::*                    LISTEN      4185/docker-proxy
tcp        0      0 :::8080                 :::*                    LISTEN      2284/uhttpd
tcp        0      0 fe80::c486:10ff:fe34:928:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::d88a:ecff:fea0:145f:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 2001:a61:13b1:6400::1:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::bc9d:6cff:fe8d:400f:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::8ce3:f8ff:fee9:f33e:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::42:cff:fec9:32b1:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::1045:9bff:fe84:8071:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::3435:a3ff:fe6b:8992:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::42:a6ff:fecc:b077:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::2e0:4cff:fe68:991:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::42:d3ff:fe06:27ac:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::2e0:4cff:fe68:991:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 ::1:53                  :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fd3e:1a65:d719::1:53    :::*                    LISTEN      3597/dnsmasq
tcp        0      0 fe80::2e0:4cff:fe68:990:53 :::*                    LISTEN      3597/dnsmasq
tcp        0      0 :::22                   :::*                    LISTEN      1987/dropbear
tcp        0      0 :::443                  :::*                    LISTEN      4144/docker-proxy
tcp        0      0 :::8443                 :::*                    LISTEN      2284/uhttpd
tcp        0      0 :::8000                 :::*                    LISTEN      4076/docker-proxy
tcp        0      0 :::9443                 :::*                    LISTEN      4026/docker-proxy
udp        0      0 127.0.0.1:53            0.0.0.0:*                           3597/dnsmasq
udp        0      0 192.168.1.1:53          0.0.0.0:*                           3597/dnsmasq
udp        0      0 172.17.0.1:53           0.0.0.0:*                           3597/dnsmasq
udp        0      0 172.18.0.1:53           0.0.0.0:*                           3597/dnsmasq
udp        0      0 172.19.0.1:53           0.0.0.0:*                           3597/dnsmasq
udp        0      0 0.0.0.0:67              0.0.0.0:*                           3597/dnsmasq
udp        0      0 fe80::c486:10ff:fe34:928:53 :::*                                3597/dnsmasq
udp        0      0 fe80::d88a:ecff:fea0:145f:53 :::*                                3597/dnsmasq
udp        0      0 2001:a61:13b1:6400::1:53 :::*                                3597/dnsmasq
udp        0      0 fe80::bc9d:6cff:fe8d:400f:53 :::*                                3597/dnsmasq
udp        0      0 fe80::8ce3:f8ff:fee9:f33e:53 :::*                                3597/dnsmasq
udp        0      0 fe80::42:cff:fec9:32b1:53 :::*                                3597/dnsmasq
udp        0      0 fe80::1045:9bff:fe84:8071:53 :::*                                3597/dnsmasq
udp        0      0 fe80::3435:a3ff:fe6b:8992:53 :::*                                3597/dnsmasq
udp        0      0 fe80::42:a6ff:fecc:b077:53 :::*                                3597/dnsmasq
udp        0      0 fe80::2e0:4cff:fe68:991:53 :::*                                3597/dnsmasq
udp        0      0 fe80::42:d3ff:fe06:27ac:53 :::*                                3597/dnsmasq
udp        0      0 fe80::2e0:4cff:fe68:991:53 :::*                                3597/dnsmasq
udp        0      0 ::1:53                  :::*                                3597/dnsmasq
udp        0      0 fd3e:1a65:d719::1:53    :::*                                3597/dnsmasq
udp        0      0 fe80::2e0:4cff:fe68:990:53 :::*                                3597/dnsmasq
udp        0      0 :::546                  :::*                                5231/odhcp6c
udp        0      0 :::547                  :::*                                2157/odhcpd
raw        0      0 ::%721840896:58         :::*                    58          5231/odhcp6c
raw        0      0 ::%721840896:58         :::*                    58          2157/odhcpd
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node PID/Program name    Path
unix  2      [ ACC ]     STREAM     LISTENING      10673 8339/containerd-shi /run/containerd/s/f3b20ac5af59a53b3a4a23d5b5f2f30274823cc4ada8bf4ab5fc85910a7981a7
unix  2      [ ACC ]     STREAM     LISTENING       3091 1338/ubusd          /var/run/ubus/ubus.sock
unix  2      [ ACC ]     STREAM     LISTENING       2990 4238/containerd-shi /run/containerd/s/0157d2804baee3efb9d20c45f1d9b128a417948cba41b6fd936d6f45cc15a477
unix  2      [ ACC ]     STREAM     LISTENING       6175 4275/containerd-shi /run/containerd/s/335d6e83471f27f732a387fefdf579716171a6f05561d841acc883440f85eb04
unix  2      [ ACC ]     STREAM     LISTENING       4640 4302/containerd-shi /run/containerd/s/40a0ca64535e01852deffebe007c434a8955c2670d66deac20f69a75d01d06ce
unix  2      [ ACC ]     STREAM     LISTENING       3009 4331/containerd-shi /run/containerd/s/beb7426e3aca4f67ce27cc2d716dd42228f8457d83227d22c12a232d40924bc4
unix  2      [ ACC ]     STREAM     LISTENING       3571 2844/dockerd        /var/run/docker.sock
unix  2      [ ACC ]     STREAM     LISTENING       4191 3038/containerd     /var/run/docker/containerd/containerd-debug.sock
unix  2      [ ACC ]     STREAM     LISTENING       4192 3038/containerd     /var/run/docker/containerd/containerd.sock.ttrpc
unix  2      [ ACC ]     STREAM     LISTENING       4193 3038/containerd     /var/run/docker/containerd/containerd.sock
unix  2      [ ACC ]     STREAM     LISTENING       3616 2844/dockerd        /var/run/docker/metrics.sock
unix  2      [ ACC ]     STREAM     LISTENING       1901 2844/dockerd        /var/run/docker/libnetwork/6f64a8c42f04.sock

root@OpenWrt:~# docker ps

CONTAINER ID   IMAGE                                    COMMAND                  CREATED             STATUS          PORTS                                                                                            NAMES
366b8f388ee3   joplin/server:latest                     "tini -- node dist/a…"   About an hour ago   Up 18 seconds                                                                                                    joplin
59bc54a10be6   postgres:13                              "docker-entrypoint.s…"   About an hour ago   Up 5 minutes    5432/tcp                                                                                         joplin_postgres
ca43315d05ce   jwilder/nginx-proxy:alpine               "/app/docker-entrypo…"   About an hour ago   Up 5 minutes    0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp                         nginx-proxy
a99bb9f1988f   jrcs/letsencrypt-nginx-proxy-companion   "/bin/bash /app/entr…"   About an hour ago   Up 5 minutes                                                                                                     nginx-proxy-letsencrypt
693f7b153f73   portainer/portainer-ce                   "/portainer"             About an hour ago   Up 5 minutes    0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp, 9000/tcp   portainer

root@OpenWrt:~# iptables-save -c

# Generated by iptables-save v1.8.7 on Mon Sep 12 09:00:49 2022
*nat
:PREROUTING ACCEPT [1797:463441]
:INPUT ACCEPT [619:41112]
:OUTPUT ACCEPT [440:30589]
:POSTROUTING ACCEPT [87:6386]
:DOCKER - [0:0]
[691:44617] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
[0:0] -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
[0:0] -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
[0:0] -A POSTROUTING -s 172.19.0.0/16 ! -o br-joplin -j MASQUERADE
[0:0] -A POSTROUTING -s 172.18.0.0/16 ! -o br-9fb15ae64b88 -j MASQUERADE
[0:0] -A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 9443 -j MASQUERADE
[0:0] -A POSTROUTING -s 172.17.0.2/32 -d 172.17.0.2/32 -p tcp -m tcp --dport 8000 -j MASQUERADE
[0:0] -A POSTROUTING -s 172.18.0.3/32 -d 172.18.0.3/32 -p tcp -m tcp --dport 443 -j MASQUERADE
[0:0] -A POSTROUTING -s 172.18.0.3/32 -d 172.18.0.3/32 -p tcp -m tcp --dport 80 -j MASQUERADE
[0:0] -A DOCKER -i docker0 -j RETURN
[0:0] -A DOCKER -i br-joplin -j RETURN
[0:0] -A DOCKER -i br-9fb15ae64b88 -j RETURN
[0:0] -A DOCKER ! -i docker0 -p tcp -m tcp --dport 9443 -j DNAT --to-destination 172.17.0.2:9443
[0:0] -A DOCKER ! -i docker0 -p tcp -m tcp --dport 8000 -j DNAT --to-destination 172.17.0.2:8000
[0:0] -A DOCKER ! -i br-9fb15ae64b88 -p tcp -m tcp --dport 443 -j DNAT --to-destination 172.18.0.3:443
[2:80] -A DOCKER ! -i br-9fb15ae64b88 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.18.0.3:80
COMMIT
# Completed on Mon Sep 12 09:00:49 2022
# Generated by iptables-save v1.8.7 on Mon Sep 12 09:00:49 2022
*mangle
:PREROUTING ACCEPT [538320:1213556947]
:INPUT ACCEPT [2311:295367]
:FORWARD ACCEPT [535385:1212898171]
:OUTPUT ACCEPT [1635:333639]
:POSTROUTING ACCEPT [536967:1213228141]
COMMIT
# Completed on Mon Sep 12 09:00:49 2022
# Generated by iptables-save v1.8.7 on Mon Sep 12 09:00:49 2022
*filter
:INPUT ACCEPT [2158:287424]
:FORWARD ACCEPT [535332:1212894502]
:OUTPUT ACCEPT [1598:331316]
:DOCKER - [0:0]
:DOCKER-ISOLATION-STAGE-1 - [0:0]
:DOCKER-ISOLATION-STAGE-2 - [0:0]
:DOCKER-USER - [0:0]
[535332:1212894502] -A FORWARD -j DOCKER-USER
[535332:1212894502] -A FORWARD -j DOCKER-ISOLATION-STAGE-1
[0:0] -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -o docker0 -j DOCKER
[0:0] -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
[0:0] -A FORWARD -i docker0 -o docker0 -j ACCEPT
[0:0] -A FORWARD -o br-joplin -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -o br-joplin -j DOCKER
[0:0] -A FORWARD -i br-joplin ! -o br-joplin -j ACCEPT
[0:0] -A FORWARD -i br-joplin -o br-joplin -j ACCEPT
[0:0] -A FORWARD -o br-9fb15ae64b88 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
[0:0] -A FORWARD -o br-9fb15ae64b88 -j DOCKER
[0:0] -A FORWARD -i br-9fb15ae64b88 ! -o br-9fb15ae64b88 -j ACCEPT
[0:0] -A FORWARD -i br-9fb15ae64b88 -o br-9fb15ae64b88 -j ACCEPT
[0:0] -A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 9443 -j ACCEPT
[0:0] -A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 8000 -j ACCEPT
[0:0] -A DOCKER -d 172.18.0.3/32 ! -i br-9fb15ae64b88 -o br-9fb15ae64b88 -p tcp -m tcp --dport 443 -j ACCEPT
[0:0] -A DOCKER -d 172.18.0.3/32 ! -i br-9fb15ae64b88 -o br-9fb15ae64b88 -p tcp -m tcp --dport 80 -j ACCEPT
[0:0] -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
[0:0] -A DOCKER-ISOLATION-STAGE-1 -i br-joplin ! -o br-joplin -j DOCKER-ISOLATION-STAGE-2
[0:0] -A DOCKER-ISOLATION-STAGE-1 -i br-9fb15ae64b88 ! -o br-9fb15ae64b88 -j DOCKER-ISOLATION-STAGE-2
[535332:1212894502] -A DOCKER-ISOLATION-STAGE-1 -j RETURN
[0:0] -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
[0:0] -A DOCKER-ISOLATION-STAGE-2 -o br-joplin -j DROP
[0:0] -A DOCKER-ISOLATION-STAGE-2 -o br-9fb15ae64b88 -j DROP
[0:0] -A DOCKER-ISOLATION-STAGE-2 -j RETURN
[0:0] -A DOCKER-USER -i eth1.40 -o docker0 -j REJECT --reject-with icmp-port-unreachable
[535332:1212894502] -A DOCKER-USER -j RETURN
COMMIT
# Completed on Mon Sep 12 09:00:49 2022

Thank you for your support

1 Like

Could you run a packet capture with tcpdump to verify that packets are coming out of OpenWrt with the correct masquerade? Firewall seems to be forwarding everything.

A tcpdump -i docker0 and curl www.google.comoutputs nothing at the tcpdump console. The container tells me connection refused.

Maybe it's a general dockerd package issue.
Even after a fresh installation of OpenWrt without any other changes or packages installed I'm getting an error after installing dockerd package.

pkg_run_script: Running script //usr/lib/opkg/info/dockerd.postinst.
uci: Entry not found

What other tcpdumps I can provide to solve the problem?

I think that capturing on docker0 is as far as you can go. If you don't see something there, then nothing is sent from the docker.

Today I recognized all network access from inside a container does not work.

bash-5.1# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.19.0.1      0.0.0.0         UG    0      0        0 eth0
172.19.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0
bash-5.1# traceroute 8.8.8.8
traceroute to 8.8.8.8 (8.8.8.8), 30 hops max, 46 byte packets
 1  172.19.0.1 (172.19.0.1)  0.025 ms  0.017 ms  0.009 ms
 2  172.19.0.1 (172.19.0.1)  0.007 ms  0.016 ms  0.013 ms
bash-5.1# curl www.google.com
curl: (7) Failed to connect to www.google.com port 80 after 2 ms: Connection refused
bash-5.1# curl nyx.lan
curl: (7) Failed to connect to nyx.lan port 80 after 3 ms: Connection refused

It seems to be a problem with docker0 interface. Any suggestions to try or seek?

Thank you

1 Like

see the root cause: Nftables vs dockerd

1 Like

Thank you, this seems to be the same problem.
Unfortunately it seems I missed some step.

I've added uci_quiet set network.@device[-1].bridge_empty='1' # <-- add this new bridge option into the init script and added both config inculed to /etc/config/firewallincluding the two nft files.

Now it looks like

root@OpenWrt:~# nft list chain inet fw4 forward; nft list chain inet fw4 forward_docker; nft list chain inet fw4 accept_to_docker
table inet fw4 {
	chain forward {
		type filter hook forward priority filter; policy drop;
		ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
		iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
		iifname "pppoe-wan6" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
		iifname "docker0" jump forward_docker comment "fix: handle docker forward traffic"
		jump handle_reject
	}
}
table inet fw4 {
	chain forward_docker {
		jump accept_to_wan comment "!fw4: Accept docker to wan forwarding"
		jump accept_to_docker
	}
}
table inet fw4 {
	chain accept_to_docker {
	}
}

The accept_to_docker rule still dies not apply

It seems I've missed something to add.

1. update /etc/init.d/dockerd as per the other thread
2. service dockerd stop
3. service dockerd ucidel docker0
4. service dockerd boot or reboot the router
5. allow docker zone forward to wan
6. service dockerd restart

in theory this would create following rules:
table inet fw4 {
        chain input {
                type filter hook input priority filter; policy accept;
[..]
                iifname "docker0" jump input_docker comment "!fw4: Handle docker IPv4/IPv6 input traffic"
        }

        chain forward {
                type filter hook forward priority filter; policy drop;
[..]    
                iifname "docker0" jump forward_docker comment "!fw4: Handle docker IPv4/IPv6 forward traffic"
                jump handle_reject
        }

        chain output {
                type filter hook output priority filter; policy accept;
[..]
                oifname "docker0" jump output_docker comment "!fw4: Handle docker IPv4/IPv6 output traffic"
        }

        chain prerouting {
                type filter hook prerouting priority filter; policy accept;
[..]
                iifname "docker0" jump helper_docker comment "!fw4: Handle docker IPv4/IPv6 helper assignment"
        }

        chain input_docker {
                jump accept_from_docker
        }

        chain output_docker {
                jump accept_to_docker
        }

        chain forward_docker {
                jump accept_to_wan comment "!fw4: Accept docker to wan forwarding"
                jump accept_to_docker
        }

        chain helper_docker {
        }

        chain accept_from_docker {
                iifname "docker0" counter packets 0 bytes 0 accept comment "!fw4: accept docker IPv4/IPv6 traffic"
        }

        chain accept_to_docker {
                oifname "docker0" counter packets 11 bytes 840 accept comment "!fw4: accept docker IPv4/IPv6 traffic"
        }
}

I did a fresh reinstallation of OpenWRT and dockerd.
Followed your list but docker0 is complete missing in my chains.

After service dockerd ucidel docker0 there is still a docker0 interface, is this correct?

root@OpenWrt:~# service dockerd stop
root@OpenWrt:~# service dockerd ucidel docker0
root@OpenWrt:~# ip addr show docker0
8: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
    link/ether 02:42:1d:1a:8f:af brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:1dff:fe1a:8faf/64 scope link
       valid_lft forever preferred_lft forever
root@OpenWrt:~# service dockerd boot
nft list chain inet fw4 input; nft list chain inet fw4 forward; nft list chain inet fw4 output

table inet fw4 {
	chain input {
		type filter hook input priority filter; policy accept;
		iifname "lo" accept comment "!fw4: Accept traffic from loopback"
		ct state established,related accept comment "!fw4: Allow inbound established and related flows"
		tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
		iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
		iifname "pppoe-wan6" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
	}
}
table inet fw4 {
	chain forward {
		type filter hook forward priority filter; policy drop;
		ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
		iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
		iifname "pppoe-wan6" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
		jump handle_reject
	}
}
table inet fw4 {
	chain output {
		type filter hook output priority filter; policy accept;
		oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
		ct state established,related accept comment "!fw4: Allow outbound established and related flows"
		oifname "br-lan" jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic"
		oifname "pppoe-wan6" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
	}
}

/etc/config/firewall with forwarding

config defaults
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option synflood_protect '1'

config zone
	option name 'lan'
	list network 'lan'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'

config zone
	option name 'wan'
	option input 'REJECT'
	option output 'ACCEPT'
	option forward 'REJECT'
	option masq '1'
	option mtu_fix '1'
	list network 'wan'
	list network 'wan6'

config forwarding
	option src 'lan'
	option dest 'wan'

config rule
	option name 'Allow-DHCP-Renew'
	option src 'wan'
	option proto 'udp'
	option dest_port '68'
	option target 'ACCEPT'
	option family 'ipv4'

config rule
	option name 'Allow-Ping'
	option src 'wan'
	option proto 'icmp'
	option icmp_type 'echo-request'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-IGMP'
	option src 'wan'
	option proto 'igmp'
	option family 'ipv4'
	option target 'ACCEPT'

config rule
	option name 'Allow-DHCPv6'
	option src 'wan'
	option proto 'udp'
	option dest_port '546'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-MLD'
	option src 'wan'
	option proto 'icmp'
	option src_ip 'fe80::/10'
	list icmp_type '130/0'
	list icmp_type '131/0'
	list icmp_type '132/0'
	list icmp_type '143/0'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Input'
	option src 'wan'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	list icmp_type 'router-solicitation'
	list icmp_type 'neighbour-solicitation'
	list icmp_type 'router-advertisement'
	list icmp_type 'neighbour-advertisement'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-ICMPv6-Forward'
	option src 'wan'
	option dest '*'
	option proto 'icmp'
	list icmp_type 'echo-request'
	list icmp_type 'echo-reply'
	list icmp_type 'destination-unreachable'
	list icmp_type 'packet-too-big'
	list icmp_type 'time-exceeded'
	list icmp_type 'bad-header'
	list icmp_type 'unknown-header-type'
	option limit '1000/sec'
	option family 'ipv6'
	option target 'ACCEPT'

config rule
	option name 'Allow-IPSec-ESP'
	option src 'wan'
	option dest 'lan'
	option proto 'esp'
	option target 'ACCEPT'

config rule
	option name 'Allow-ISAKMP'
	option src 'wan'
	option dest 'lan'
	option dest_port '500'
	option proto 'udp'
	option target 'ACCEPT'

config zone 'docker'
	option input 'ACCEPT'
	option output 'ACCEPT'
	option forward 'ACCEPT'
	option name 'docker'
	list network 'docker'

config forwarding
	option src 'docker'
	option dest 'wan'

/etc/init.d/dockerd (partly)

	# Add docker bridge device
        if [ "$(find_network_device "$device")" = "" ]; then
                logger -t "dockerd-init" -p notice "Adding bridge device '${device}' to network config"
                uci_quiet add network device
                uci_quiet set network.@device[-1].type="bridge"
                uci_quiet set network.@device[-1].name="${device}"
                uci_quiet set network.@device[-1].bridge_empty='1' # <-- add this new bridge option
                uci_quiet commit network
	else
		logger -t "dockerd-init" -p notice "Bridge device '${device}' already defined in network config"
	fi
  1. /etc/init.d/dockerd needs two fixes. you did one only. in the same function uciadd please add following too:
uciadd() {
..
reload config
ifup docker <--- fix #2
}
  1. service dockerd ucidel
  2. if previous fails to clear bridge & interface please remove manually both
  3. now in theory service dockerd boot should redo everything needed, but you can also do a reboot instead

I'v added the second fix, now the firewall rules are like you described but I still get a connection refused error.

what's your /etc/config/docker?

I have not changed anything in this file

root@OpenWrt:~# cat /etc/config/dockerd
# The following settings require a restart of docker to take full effect, A reload will only have partial or no effect:
# log_driver
# bip
# blocked_interfaces
# extra_iptables_args
# device

config globals 'globals'
#	option alt_config_file '/etc/docker/daemon.json'
	option data_root '/opt/docker/'
#	option log_driver 'local'
	option log_level 'warn'
	option iptables '1'
#	list hosts 'unix:///var/run/docker.sock'
#	option bip '172.18.0.1/24'
#	option fixed_cidr '172.17.0.0/16'
#	option fixed_cidr_v6 'fc00:1::/80'
#	option ipv6 '1'
#	option ip '::ffff:0.0.0.0'
#	list dns '172.17.0.1'
#	list registry_mirrors 'https://<my-docker-mirror-host>'
#	list registry_mirrors 'https://hub.docker.com'

# Docker doesn't work well out of the box with fw4. This is because Docker relies on a compatibility layer that
# naively translates iptables rules. For the best compatibility replace the following dependencies:
# `firewall4` -> `firewall`
# `iptables-nft` -> `iptables-legacy`
# `ip6tables-nft` -> `ip6tables-legacy`

# Docker undermines the fw3 rules. By default all external source IPs are allowed to connect to the Docker host.
# See https://docs.docker.com/network/iptables/ for more details.

# firewall config changes are only additive i.e firewall will need to be restarted first to clear old changes,
# then docker restarted to load in new changes.
config firewall 'firewall'
	option device 'docker0'
	list blocked_interfaces 'wan'
#	option extra_iptables_args '--match conntrack ! --ctstate RELATED,ESTABLISHED' # allow outbound connections

uncomment this line then restart service

I've tried it allready, same result, connection refused.
I also tried to remove the list blocked_interfaces 'wan'line without luck.

would you mind redo everything from scratch? i.e. delete all docker related packages, re-install, stop docker service, make sure no docker0 exists, change the init file then start.

  1. Rewrote the .img file to EMMC using Ubuntu Live System

  2. Resized Partition 2 to maximum size using gparted

  3. reboot to OpenWrt

  4. Changed IP from 192.168.1.1 to 192.168.10.1 in /etc/config/network

--- network.old 2022-09-15 10:21:07.989998029 +0000
+++ network     2022-09-15 10:21:25.009997497 +0000
@@ -16,7 +16,7 @@
 config interface 'lan'
        option device 'br-lan'
        option proto 'static'
-       option ipaddr '192.168.1.1'
+       option ipaddr '192.168.10.1'
        option netmask '255.255.255.0'
        option ip6assign '60'
  1. Installed bash and diff package
opkg update
opkg install bash diffutils
  1. Set shell for user root to bash
--- passwd.old  2022-09-15 10:31:45.477232349 +0000
+++ passwd      2022-09-15 10:31:55.387474157 +0000
@@ -1,4 +1,4 @@
-root:x:0:0:root:/root:/bin/ash
+root:x:0:0:root:/root:/bin/bash
 daemon:*:1:1:daemon:/var:/bin/false
 ftp:*:55:55:ftp:/home/ftp:/bin/false
 network:*:101:101:network:/var:/bin/false
  1. Installed dockerd and docker related tools
opkg install dockerd docker docker-compose luci-app-dockerman

There is always an error when configuring dockerd

Configuring dockerd.
uci: Entry not found
  1. update /etc/init.d/dockerd
--- dockerd.old 2022-09-15 10:39:25.652272831 +0000
+++ dockerd     2022-09-15 10:41:53.004361977 +0000
@@ -77,6 +77,7 @@
                uci_quiet add network device
                uci_quiet set network.@device[-1].type="bridge"
                uci_quiet set network.@device[-1].name="${device}"
+                uci_quiet set network.@device[-1].bridge_empty='1' # <-- add this new bridge option
                uci_quiet commit network
        else
                logger -t "dockerd-init" -p notice "Bridge device '${device}' already defined in network config"
@@ -101,6 +102,7 @@
                uci_quiet commit firewall
        fi

+        ifup docker
        reload_config
 }
  1. service dockerd stop

9.1 ip link show has a docker0 interface

root@OpenWrt:~# ip link show docker0
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
    link/ether 02:42:33:e3:17:47 brd ff:ff:ff:ff:ff:ff
  1. service dockerd ucidel docker0
root@OpenWrt:~# service dockerd ucidel docker0
uci: Entry not found

after this logread shows

Thu Sep 15 10:47:44 2022 user.notice dockerd-init: Deleting bridge device 'docker0' from network config
Thu Sep 15 10:47:44 2022 user.notice dockerd-init: Deleting interface 'docker' from network config
Thu Sep 15 10:47:44 2022 user.notice dockerd-init: Deleting network interface 'docker' in zone 'docker' from firewall config
Thu Sep 15 10:47:44 2022 user.notice dockerd-init: Deleting firewall zone 'docker' from firewall config

but the interface is still up

root@OpenWrt:~# ip link show docker0
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
    link/ether 02:42:33:e3:17:47 brd ff:ff:ff:ff:ff:ff

there is no docker0 entry in /etc/config/network nor /etc/config/firewall
so only the existing interface has not been shut down.

  1. reboot

11.1 After rebooting there is a docker entry in /etc/config/network and /etc/config/firewall

  1. added docker forwarding to wan to /etc/config/firewall
--- firewall.old        2022-09-15 10:59:28.447909213 +0000
+++ firewall    2022-09-15 11:01:11.539691114 +0000
@@ -126,3 +126,7 @@
        option name 'docker'
        list network 'docker'

+config forwarding
+       option src 'docker'
+       option dest 'wan'
  1. reboot

  2. check firewall

root@OpenWrt:~# nft list chain inet fw4 input; nft list chain inet fw4 forward; nft list chain inet fw4 output; nft list chain inet fw4 prerouting;  nft list chain inet fw4 input_docker;  nft list chain inet fw4 output_docker;  nft list chain inet fw4 forward_docker;  nft list chain inet fw4 helper_docker;  nft list chain inet fw4 accept_from_docker;  nft list chain inet fw4 accept_to_docker
table inet fw4 {
        chain input {
                type filter hook input priority filter; policy accept;
                iifname "lo" accept comment "!fw4: Accept traffic from loopback"
                ct state established,related accept comment "!fw4: Allow inbound established and related flows"
                tcp flags syn / fin,syn,rst,ack jump syn_flood comment "!fw4: Rate limit TCP syn packets"
                iifname "br-lan" jump input_lan comment "!fw4: Handle lan IPv4/IPv6 input traffic"
                iifname "eth1" jump input_wan comment "!fw4: Handle wan IPv4/IPv6 input traffic"
                iifname "docker0" jump input_docker comment "!fw4: Handle docker IPv4/IPv6 input traffic"
        }
}
table inet fw4 {
        chain forward {
                type filter hook forward priority filter; policy drop;
                ct state established,related accept comment "!fw4: Allow forwarded established and related flows"
                iifname "br-lan" jump forward_lan comment "!fw4: Handle lan IPv4/IPv6 forward traffic"
                iifname "eth1" jump forward_wan comment "!fw4: Handle wan IPv4/IPv6 forward traffic"
                iifname "docker0" jump forward_docker comment "!fw4: Handle docker IPv4/IPv6 forward traffic"
                jump handle_reject
        }
}
table inet fw4 {
        chain output {
                type filter hook output priority filter; policy accept;
                oifname "lo" accept comment "!fw4: Accept traffic towards loopback"
                ct state established,related accept comment "!fw4: Allow outbound established and related flows"
                oifname "br-lan" jump output_lan comment "!fw4: Handle lan IPv4/IPv6 output traffic"
                oifname "eth1" jump output_wan comment "!fw4: Handle wan IPv4/IPv6 output traffic"
                oifname "docker0" jump output_docker comment "!fw4: Handle docker IPv4/IPv6 output traffic"
        }
}
table inet fw4 {
        chain prerouting {
                type filter hook prerouting priority filter; policy accept;
                iifname "br-lan" jump helper_lan comment "!fw4: Handle lan IPv4/IPv6 helper assignment"
                iifname "docker0" jump helper_docker comment "!fw4: Handle docker IPv4/IPv6 helper assignment"
        }
}
table inet fw4 {
        chain input_docker {
                jump accept_from_docker
        }
}
table inet fw4 {
        chain output_docker {
                jump accept_to_docker
        }
}
table inet fw4 {
        chain forward_docker {
                jump accept_to_wan comment "!fw4: Accept docker to wan forwarding"
                jump accept_to_docker
        }
}
table inet fw4 {
        chain helper_docker {
        }
}
table inet fw4 {
        chain accept_from_docker {
                iifname "docker0" counter packets 0 bytes 0 accept comment "!fw4: accept docker IPv4/IPv6 traffic"
        }
}
table inet fw4 {
        chain accept_to_docker {
                oifname "docker0" counter packets 5 bytes 480 accept comment "!fw4: accept docker IPv4/IPv6 traffic"
        }
}
  1. Docker ping test
root@OpenWrt:~# docker container run -it alpine /bin/ping -c 2 8.8.8.8
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
213ec9aee27d: Pull complete
Digest: sha256:bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad
Status: Downloaded newer image for alpine:latest
PING 8.8.8.8 (8.8.8.8): 56 data bytes

--- 8.8.8.8 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
  1. All changed files

/etc/config/network

config interface 'loopback'
        option device 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd2d:7171:63c4::/48'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'eth0'

config interface 'lan'
        option device 'br-lan'
        option proto 'static'
        option ipaddr '192.168.10.1'
        option netmask '255.255.255.0'
        option ip6assign '60'

config interface 'wan'
        option device 'eth1'
        option proto 'dhcp'

config interface 'wan6'
        option device 'eth1'
        option proto 'dhcpv6'

config interface 'docker'
        option device 'docker0'
        option proto 'none'
        option auto '0'

config device
        option type 'bridge'
        option name 'docker0'
        option bridge_empty '1'

/etc/config/firewall`

config defaults
        option syn_flood '1'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'REJECT'

config zone
        option name 'lan'
        list network 'lan'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'

config zone
        option name 'wan'
        list network 'wan'
        list network 'wan6'
        option input 'REJECT'
        option output 'ACCEPT'
        option forward 'REJECT'
        option masq '1'
        option mtu_fix '1'

config forwarding
        option src 'lan'
        option dest 'wan'

config rule
        option name 'Allow-DHCP-Renew'
        option src 'wan'
        option proto 'udp'
        option dest_port '68'
        option target 'ACCEPT'
        option family 'ipv4'

config rule
        option name 'Allow-Ping'
        option src 'wan'
        option proto 'icmp'
        option icmp_type 'echo-request'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-IGMP'
        option src 'wan'
        option proto 'igmp'
        option family 'ipv4'
        option target 'ACCEPT'

config rule
        option name 'Allow-DHCPv6'
        option src 'wan'
        option proto 'udp'
        option dest_port '546'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-MLD'
        option src 'wan'
        option proto 'icmp'
        option src_ip 'fe80::/10'
        list icmp_type '130/0'
        list icmp_type '131/0'
        list icmp_type '132/0'
        list icmp_type '143/0'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Input'
        option src 'wan'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        list icmp_type 'router-solicitation'
        list icmp_type 'neighbour-solicitation'
        list icmp_type 'router-advertisement'
        list icmp_type 'neighbour-advertisement'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-ICMPv6-Forward'
        option src 'wan'
        option dest '*'
        option proto 'icmp'
        list icmp_type 'echo-request'
        list icmp_type 'echo-reply'
        list icmp_type 'destination-unreachable'
        list icmp_type 'packet-too-big'
        list icmp_type 'time-exceeded'
        list icmp_type 'bad-header'
        list icmp_type 'unknown-header-type'
        option limit '1000/sec'
        option family 'ipv6'
        option target 'ACCEPT'

config rule
        option name 'Allow-IPSec-ESP'
        option src 'wan'
        option dest 'lan'
        option proto 'esp'
        option target 'ACCEPT'

config rule
        option name 'Allow-ISAKMP'
        option src 'wan'
        option dest 'lan'
        option dest_port '500'
        option proto 'udp'
        option target 'ACCEPT'

config zone 'docker'
        option input 'ACCEPT'
        option output 'ACCEPT'
        option forward 'ACCEPT'
        option name 'docker'
        list network 'docker'

config forwarding
        option src 'docker'
        option dest 'wan'

/etc/init.d/dockerd

#!/bin/sh /etc/rc.common

USE_PROCD=1
START=99

extra_command "uciadd" "<interface> <device> <zone> Add docker bridge configuration to network and firewall uci config"
extra_command "ucidel" "<interface> <device> <zone> Delete docker bridge configuration from network and firewall uci config"

DOCKER_CONF_DIR="/tmp/dockerd"
DOCKERD_CONF="${DOCKER_CONF_DIR}/daemon.json"

uci_quiet() {
        uci -q "${@}" >/dev/null
}

json_add_array_string() {
        json_add_string "" "${1}"
}

find_network_device() {
        local device="${1}"
        local device_section=""

        check_device() {
                local cfg="${1}"
                local device="${2}"

                local type name
                config_get type "${cfg}" type
                config_get name "${cfg}" name

                [ "${type}" = "bridge" ] && [ "${name}" = "${device}" ] \
                        && device_section="${cfg}"
        }

        config_load network
        config_foreach check_device device "${device}"

        echo "${device_section}"
}

boot() {
        uciadd
        rc_procd start_service
}

uciadd() {
        local iface="${1}"
        local device="${2}"
        local zone="${3}"

        [ -z "${iface}" ] && {
                iface="docker"
                device="docker0"
                zone="docker"
        }

        /etc/init.d/dockerd running && {
                echo "Please stop dockerd service first"
                exit 0
        }

        # Add network interface
        if ! uci_quiet get network.${iface}; then
                logger -t "dockerd-init" -p notice "Adding interface '${iface}' to network config"
                uci_quiet add network interface
                uci_quiet rename network.@interface[-1]="${iface}"
                uci_quiet set network.@interface[-1].device="${device}"
                uci_quiet set network.@interface[-1].proto="none"
                uci_quiet set network.@interface[-1].auto="0"
                uci_quiet commit network
        fi

        # Add docker bridge device
        if [ "$(find_network_device "$device")" = "" ]; then
                logger -t "dockerd-init" -p notice "Adding bridge device '${device}' to network config"
                uci_quiet add network device
                uci_quiet set network.@device[-1].type="bridge"
                uci_quiet set network.@device[-1].name="${device}"
                uci_quiet set network.@device[-1].bridge_empty='1' # <-- add this new bridge option
                uci_quiet commit network
        else
                logger -t "dockerd-init" -p notice "Bridge device '${device}' already defined in network config"
        fi

        # Add firewall zone
        if ! uci_quiet get firewall.${zone}; then
                logger -t "dockerd-init" -p notice "Adding firewall zone '${zone}' to firewall config"
                uci_quiet add firewall zone
                uci_quiet rename firewall.@zone[-1]="${zone}"
                uci_quiet set firewall.@zone[-1].input="ACCEPT"
                uci_quiet set firewall.@zone[-1].output="ACCEPT"
                uci_quiet set firewall.@zone[-1].forward="ACCEPT"
                uci_quiet set firewall.@zone[-1].name="${zone}"
                uci_quiet commit firewall
        fi

        # Add interface to firewall zone
        if uci_quiet get firewall.${zone}; then
                uci_quiet del_list firewall.${zone}.network="${iface}"
                uci_quiet add_list firewall.${zone}.network="${iface}"
                uci_quiet commit firewall
        fi

        ifup docker
        reload_config
}

ucidel() {
        local iface="${1}"
        local device="${2}"
        local zone="${3}"

        [ -z "${iface}" ] && {
                iface="docker"
                device="docker0"
                zone="docker"
        }

        /etc/init.d/dockerd running && {
                echo "Please stop dockerd service first"
                exit 0
        }

        # Remove network device
        if uci_quiet delete network.$(find_network_device "${device}"); then
                logger -t "dockerd-init" -p notice "Deleting bridge device '${device}' from network config"
                uci_quiet commit network
        fi

        # Remove network interface
        if uci_quiet get network.${iface}; then
                logger -t "dockerd-init" -p notice "Deleting interface '${iface}' from network config"
                uci_quiet delete network.${iface}
                uci_quiet commit network
        fi

        # Remove interface from firewall zone
        if uci_quiet get firewall.${zone}; then
                logger -t "dockerd-init" -p notice "Deleting network interface '${iface}' in zone '${zone}' from firewall config"
                uci_quiet del_list firewall.${zone}.network="${iface}"
                uci_quiet commit firewall
                # Remove Firewall zone if network is empty
                if ! uci_quiet get firewall.${zone}.network; then
                        logger -t "dockerd-init" -p notice "Deleting firewall zone '${zone}' from firewall config"
                        uci_quiet delete firewall.${zone}
                fi
                uci_quiet commit firewall
        fi

        reload_config
}

process_config() {
        local alt_config_file data_root log_level iptables bip

        [ -f /etc/config/dockerd ] || {
                # Use the daemon default configuration
                DOCKERD_CONF=""
                return 0
        }

        # reset configuration
        rm -fr "${DOCKER_CONF_DIR}"
        mkdir -p "${DOCKER_CONF_DIR}"

        config_load 'dockerd'
        config_get alt_config_file globals alt_config_file
        [ -n "${alt_config_file}" ] && [ -f "${alt_config_file}" ] && {
                ln -s "${alt_config_file}" "${DOCKERD_CONF}"
                return 0
        }

        config_get data_root globals data_root "/opt/docker/"
        config_get log_level globals log_level "warn"
        config_get_bool iptables globals iptables "1"

        # Don't add these options by default
        # omission == docker defaults
        config_get log_driver globals log_driver ""
        config_get bip globals bip ""
        config_get registry_mirrors globals registry_mirrors ""
        config_get hosts globals hosts ""
        config_get dns globals dns ""
        config_get_bool ipv6 globals ipv6 ""
        config_get ip globals ip ""
        config_get fixed_cidr globals fixed_cidr ""
        config_get fixed_cidr_v6 globals fixed_cidr_v6 ""

        . /usr/share/libubox/jshn.sh
        json_init
        json_add_string "data-root" "${data_root}"
        json_add_string "log-level" "${log_level}"
        json_add_boolean "iptables" "${iptables}"
        [ -z "${log_driver}" ] || json_add_string "log-driver" "${log_driver}"
        [ -z "${bip}" ] || json_add_string "bip" "${bip}"
        [ -z "${registry_mirrors}" ] || json_add_array "registry-mirrors"
        [ -z "${registry_mirrors}" ] || config_list_foreach globals registry_mirrors json_add_array_string
        [ -z "${registry_mirrors}" ] || json_close_array
        [ -z "${hosts}" ] || json_add_array "hosts"
        [ -z "${hosts}" ] || config_list_foreach globals hosts json_add_array_string
        [ -z "${hosts}" ] || json_close_array
        [ -z "${dns}" ] || json_add_array "dns"
        [ -z "${dns}" ] || config_list_foreach globals dns json_add_array_string
        [ -z "${dns}" ] || json_close_array
        [ -z "${ipv6}" ] || json_add_boolean "ipv6" "${ipv6}"
        [ -z "${ip}" ] || json_add_string "ip" "${ip}"
        [ -z "${fixed_cidr}" ] || json_add_string "fixed-cidr" "${fixed_cidr}"
        [ -z "${fixed_cidr_v6}" ] || json_add_string "fixed-cidr-v6" "${fixed_cidr_v6}"
        json_dump > "${DOCKERD_CONF}"

        [ "${iptables}" -eq "1" ] && config_foreach iptables_add_blocking_rule firewall
}

start_service() {
        local nofile=$(cat /proc/sys/fs/nr_open)

        process_config

        procd_open_instance
        procd_set_param stderr 1
        if [ -z "${DOCKERD_CONF}" ]; then
                procd_set_param command /usr/bin/dockerd
        else
                procd_set_param command /usr/bin/dockerd --config-file="${DOCKERD_CONF}"
        fi
        procd_set_param limits nofile="${nofile} ${nofile}"
        procd_close_instance
}

reload_service() {
        process_config
        procd_send_signal dockerd
}

service_triggers() {
        procd_add_reload_trigger 'dockerd'
}

iptables_add_blocking_rule() {
        local cfg="${1}"

        local device=""
        local extra_iptables_args=""

        handle_iptables_rule() {
                local interface="${1}"
                local outbound="${2}"
                local extra_iptables_args="${3}"

                local inbound=""

                . /lib/functions/network.sh
                network_get_physdev inbound "${interface}"

                [ -z "${inbound}" ] && {
                        logger -t "dockerd-init" -p notice "Unable to get physical device for interface ${interface}"
                        return
                }

                # Wait for a maximum of 10 second per command, retrying every millisecond
                local iptables_wait_args="--wait 10 --wait-interval 1000"

                # Ignore errors as it might already be present
                iptables ${iptables_wait_args} --table filter --new DOCKER-USER 2>/dev/null
                if ! iptables ${iptables_wait_args} --table filter --check DOCKER-USER --in-interface "${inbound}" --out-interface "${outbound}" ${extra_iptables_args} --jump REJECT 2>/dev/null; then
                        logger -t "dockerd-init" -p notice "Drop traffic from ${inbound} to ${outbound}"
                        iptables ${iptables_wait_args} --table filter --insert DOCKER-USER --in-interface "${inbound}" --out-interface "${outbound}" ${extra_iptables_args} --jump REJECT
                fi
        }

        config_get device "${cfg}" device

        [ -z "${device}" ] && {
                logger -t "dockerd-init" -p notice "No device configured for ${cfg}"
                return
        }

        config_get extra_iptables_args "${cfg}" extra_iptables_args
        config_list_foreach "${cfg}" blocked_interfaces handle_iptables_rule "${device}" "${extra_iptables_args}"
}

stop_service() {
        if /etc/init.d/dockerd running; then
                service_stop "/usr/bin/dockerd"
        fi
}

At last I've edited /etc/config/dockerd added the last line with forwarding. Reboot the system and tried again to ping.
Now this is realy strange...

root@OpenWrt:~# docker container run -it alpine /bin/ping -c 2 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=1 ttl=118 time=29.923 ms


--- 8.8.8.8 ping statistics ---
2 packets transmitted, 1 packets received, 50% packet loss
round-trip min/avg/max = 29.923/29.923/29.923 ms
root@OpenWrt:~# docker container run -it alpine /bin/ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
^C
--- 8.8.8.8 ping statistics ---
26 packets transmitted, 0 packets received, 100% packet loss

The first ping was ok but then all other failed. After rebooting again it even gets stranger

root@OpenWrt:~#
login as: root
  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 22.03.0, r19685-512e76967f
 -----------------------------------------------------
=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@OpenWrt:~# docker container run -it alpine /bin/ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=1 ttl=118 time=47.894 ms
64 bytes from 8.8.8.8: seq=2 ttl=118 time=45.574 ms
64 bytes from 8.8.8.8: seq=3 ttl=118 time=47.268 ms
64 bytes from 8.8.8.8: seq=4 ttl=118 time=47.049 ms
64 bytes from 8.8.8.8: seq=5 ttl=118 time=50.084 ms
64 bytes from 8.8.8.8: seq=6 ttl=118 time=52.016 ms
64 bytes from 8.8.8.8: seq=7 ttl=118 time=56.343 ms
64 bytes from 8.8.8.8: seq=8 ttl=118 time=41.332 ms
64 bytes from 8.8.8.8: seq=9 ttl=118 time=46.947 ms
64 bytes from 8.8.8.8: seq=10 ttl=118 time=51.308 ms
64 bytes from 8.8.8.8: seq=11 ttl=118 time=55.119 ms
64 bytes from 8.8.8.8: seq=12 ttl=118 time=56.868 ms
64 bytes from 8.8.8.8: seq=13 ttl=118 time=38.147 ms
64 bytes from 8.8.8.8: seq=14 ttl=118 time=5.433 ms
64 bytes from 8.8.8.8: seq=15 ttl=118 time=43.690 ms
64 bytes from 8.8.8.8: seq=16 ttl=118 time=45.506 ms
64 bytes from 8.8.8.8: seq=17 ttl=118 time=45.952 ms
64 bytes from 8.8.8.8: seq=18 ttl=118 time=46.500 ms
64 bytes from 8.8.8.8: seq=19 ttl=118 time=47.564 ms
64 bytes from 8.8.8.8: seq=20 ttl=118 time=46.835 ms
^C
--- 8.8.8.8 ping statistics ---
21 packets transmitted, 20 packets received, 4% packet loss
round-trip min/avg/max = 5.433/45.871/56.868 ms
root@OpenWrt:~# docker container run -it alpine /bin/ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
^C
--- 8.8.8.8 ping statistics ---
13 packets transmitted, 0 packets received, 100% packet loss
root@OpenWrt:~#

So it still does not work

    reload_config
    ifup docker

I have in this order whether it makes any difference am not so sure, my guess the logical order is the latter.

nevertheless, it is really strange. having packet lost scaling from 4%-50% is weird. pinging from host (not from docker) is it ok?

but the good thing at least now the nft rules are ok.

pinging from host works 100%. pinging from container now works one time after reboot for 100% (I quit after a sequence of 100), but no second time (100% lost)
Reboot and same game again.

this does not solve it but looks it is a problem in docker maybe (?)