Docker + nftables : example with Drone CI – Docker Runner

docker and drone logos

At this time, Docker isn’t compatible with nftables. This is how you can do with an example with Drone CI (Docker Runner).

Docker fix for nftables (systemd way)

We need to fix docker.service using a little fix to disable iptables and fix the IP range used by Docker

mkdir /etc/systemd/system/docker.service.d

cat << EOF > /etc/systemd/system/docker.service.d/nftables-fix.conf
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=false --fixed-cidr=

We need the first ExecStart without nothing to cancel the official ExecStart for docker.service, I don’t replace this file.

nftables rules

I transposed rules from iptables to nftables, you can optimize it and I’ll like to read it.

table ip nat {
     chain PREROUTING {
          fib daddr type local jump DOCKER
     chain POSTROUTING {
          oifname != "docker0" ip saddr masquerade
          ip saddr ip daddr tcp dport 3000 masquerade
     chain OUTPUT {
          ip daddr != fib daddr type local jump DOCKER
     chain DOCKER {
          iifname "docker0" return
          iifname != "docker0" ip daddr tcp dport 3000 dnat to

table ip filter {
     chain INPUT {
          iifname "docker0" accept
     chain FORWARD {
          oifname "docker0" ct state established,related accept
          oifname "docker0" jump DOCKER
          iifname "docker0" oifname != "docker0" accept
          iifname "docker0" oifname "docker0" accept
          jump DOCKER-USER
     chain DOCKER-USER {
     chain DOCKER {
          iifname != "docker0" oifname "docker0" ip daddr tcp dport 3000 accept
          iifname "docker0" oifname != "docker0" jump DOCKER-ISOLATION-STAGE-2
          oifname "docker0" drop return

How to start successfully the container

I use the easiest fix: fixed IP

docker run -d --ip \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DRONE_RPC_PROTO=https \
-e DRONE_RPC_HOST=drone.lina.local \
-e DRONE_RUNNER_NAME=runner1 \
-p \
--restart always \
--name runner \

Right now, you have your Docker Runner running with success


It’s strange to use fixed IP where Docker is for “automated” and “magic” deployment but it’s the only way to use it with nftables.

It’s a fix for now and I’m impatient to migrate from Docker to Podman (used to run Drone Server) but I need to wait, not my CI/CD.