Running OpenWrt in a Docker container

oh... thanks you so much...

does the script work with one or more ethernet ports?
I didin't used your script because I thought it only worked for an ethernet port ..

If you follow the logic of the script, it's not difficult to add support for an additional interface.
You can full on either set the namespace of the interface as is done with the Wi-Fi (using ip link commands instead of iw phy), or alternatively create a vitualized macvlan interface as is done with the WAN.

Read more about Docker macvlan networking here: https://docs.docker.com/network/network-tutorial-macvlan/

Without being familiar with your network topology, it's difficult to diagnose, but my first guess would be that setting NET_ADMIN without configuring your network interface means OpenWrt defaulted to setting a static IP address of 192.168.1.1/24 on the LAN interface.

The docker-openwrt run script does more than setting NET_ADMIN. It also configures networking for the Docker container in a way that is suitable to running OpenWrt.

Are you using the script or running the OpenWrt container directly from the command-line?

I tried to run the dock container directly using the Portainer. I have cloned your script and found that the my USB dongle(only 2.4) worked from the Container generated from your script. You have already done great work laying the foundation for the project and I would like to seek your permission to fork you script to further customize and develop.

I have a small ITX x64 build with dual Gibit ethernet. My objective is to setup a docked OpenWRT that uses connects to the 2 ethernet to the physical network(1WAN and 1 LAN). Cheers.

Hey
I am new to OpenWrt and Docker both :see_no_evil:
I am running
docker run -it -p 80:80 openwrtorg/rootfs
any packages i install or changes in config don't persist on restarting the container.
Can anyone help me with this ?

After running docker restart the changes you have made to the container should still be there. But if you delete the container and recreate it then the changes are gone. I guess you could build your own image based on openwrtorg/rootfs (using a Dockerfile and docker build or docker-compose.yml and docker-compose).

1 Like

thank you!
this worked, I was initiating a new container every time like you had mentioned!

I've added some automated builds for various Raspberry Pi versions. I'd be grateful if someone could test them out and let me know if it works for them (or not).

Details in the readme.

1 Like

@oofnik did you get a chance to test your setup with RPi4? I'm wondering how your comment on "or a very slow main router" holds with the real Gigabit Ethernet powered by USB 3 bus.

I did! The gigabit port isn't the limiting factor. Wired routing worked great at near-Gigabit speeds between the onboard NIC and a USB3 NIC. The onboard wi-fi was the limiting factor. I was unable to push it past 60-70 Mbps if I remember correctly.

1 Like

Thanks for replying. My use case would be to use it as a router/firewall for my home, but wireless will be handled by a dedicated Access Point. From your reply, sound like this could work just fine then! I'll give it a try

@oofnik hi, I'm trying to use my home server as a router to manage my home network. At the moment I'm using a separate router/wifi and the server is running a lot of services under docker with compose.
I would like to use the home server (it's a VivoMini UN65U with an i5 7200U under the hood) to manage the WAN and work as a router while still running all it's docker services.

  • Use the server with dockerized OpenWRT
  • Bridge the connection to the host so the other containers can access the network
  • Attach an external AP to enable WiFi access.

Do you thin kis possible and how you would do it?

Thank you very much for your script and repository, it's really useful!

It's absolutely possible. You exactly described my own setup at home.
Running additional services on the same physical host which is running the OpenWrt container is simply a matter of configuring your service to be attached to the openwrt-lan network bridge. Have a look at how this is done in https://github.com/oofnikj/docker-openwrt/tree/master/monitoring which provides a working example of running Grafana and InfluxDB in a way that is accessible to all LAN clients. You can of course create firewall rules to limit access if needed.

You can even omit the ports: section as port forwarding to the Docker host is not necessary; the container is accessible directly to all other hosts on the LAN.

I've updated the readme to better explain how to set this up. Please let me know if anything is unclear.

Cheers

1 Like

Be aware that running OpenWrt in a container (and not using full system emulation, like kvm) means that the host system needs to provide all kernel facilities expected by OpenWrt's userland and in a compatible ABI version. While this may work in practice, it is a fragile setup which can break easily (and OpenWrt as an integrated system does not expect to be running in such a situation).

It's Linus Torvald's top priority for the Linux kernel to be backward compatible. Is that not the case with OpenWrt's kernel?

1 Like

Things like the libc expect a minimum kernel version, so do other userland tools (iproute2, …) - then you have new features like wireguard (which was only merged mainline with kernel v5.6) or modules where the defaults have been changed intentionally (e.g. sysctl valuesm tunables you can modifiy on any kernel, but OpenWrt expect to rely on its modified defaults). All of this can work (with some aspects requiring manual -undocumented- configuration on the host), but it doesn't need to - and issues can vary between subtle[0] and quite major.

It's not so much OpenWrt not adhering to kernel ABI rules (ignoring out-of-tree modules that aren't mainline yet, e.g. wireguard in kernels <v5.6), but that it has more expectations about the kernel facilities provided by the host system than many other "applications" that are to be containerized.

--
[0] e.g. firewall rules being ignored, if the host system doesn't provide the necessary facilties. netifd expects to handle IPv6 RA in userspace (odhcpd), but the container can't disable the host kernel's own handling from inside the container, …

1 Like

The current stable OpenWrt version uses 4.14.195. Even Ubuntu 18.04 uses a higher kernel version than that (4.15.0.124).

The wireguard driver is currently included in the default Ubuntu 18.04 kernel anyway. (It was added in June or July.)

So they aren't set in some file in /etc/sysctl.d/ such as /etc/sysctl.d/10-default.conf, which seems to be a good place to put default values?

If OpenWrt came with a warranty, I'm pretty sure running it in a container wouldn't be covered.

That being said, I've been running my home router like this for the better part of a year with no major issues. There are a couple sysctls I set in the run script to for conntrack, ipv6, etc. Other than that there are a few minor tweaks I've done for certain packages that depend on kernel modules (they must be loaded manually on the host) and porting a patch for ath10k so I can have 5GHz Wi-Fi. But I've tested the base system on a range of kernels from 4.15 all the way up to 5.10 with no hiccups.

1 Like

Thank you for the fast response! I'm going by trial and error. I think I've almost got it now, I need to think how to add it to my ansible playbook.
What are you using as WiFi AP? I don't think my "NUC" WiFi card is enough to manage all the clients I have around the house.

You won't know until you try :slight_smile:

I'm running on a NUC as well (5th gen Celeron). I swapped the Intel WiFi card with an Atheros model since Intel chips do not allow broadcasting on 5GHz bands.

1 Like