[OpenWrt Wiki] OpenWrt as Docker container host (https://openwrt.org/lib/exe/opensearch.php) (OpenWrt Wiki) (https://openwrt.org/) (https://openwrt.org/docs/guide-user/virtualization/docker_host?do=index) (Sitemap) (Recent Changes) (https://openwrt.org/feed.php) (Current namespace) (https://openwrt.org/feed.php?mode=list&ns=docs:guide-user:virtualization) (Plain HTML) (https://openwrt.org/_export/xhtml/docs/guide-user/virtualization/docker_host) (Wiki Markup) (https://openwrt.org/_export/raw/docs/guide-user/virtualization/docker_host) (https://openwrt.org/docs/guide-user/virtualization/docker_host) (https://openwrt.org/es/docs/guide-user/virtualization/docker_host) (https://openwrt.org/docs/guide-user/virtualization/docker_host) (https://openwrt.org/start) (OpenWrt Wiki) (OpenWrt Wiki) OpenWrt Wiki (Search) ([F]) (Search) (https://openwrt.org/docs/guide-user/virtualization/docker_host) Tools (https://openwrt.org/docs/guide-user/virtualization/docker_host) (Translations of this page) Translations of this page (https://openwrt.org/docs/guide-user/virtualization/docker_host?do=login§ok=) (Log In) Log In You are here (https://openwrt.org/start) (start) Home (https://openwrt.org/docs/start) (docs:start) Documentation (https://openwrt.org/docs/guide-user/start) (docs:guide-user:start) User guide (https://openwrt.org/docs/guide-user/virtualization/start) (docs:guide-user:virtualization:start) Virtualization (https://openwrt.org/docs/guide-user/virtualization/docker_host) (docs:guide-user:virtualization:docker_host) OpenWrt as Docker container host Learn about OpenWrt Learn about OpenWrt (https://openwrt.org/supported_devices) (supported_devices) Supported devices (https://openwrt.org/packages/start) (packages:start) Packages (https://openwrt.org/downloads) (downloads) Downloads (https://openwrt.org/docs/start) (docs:start) Documentation (https://openwrt.org/docs/guide-quick-start/start) (docs:guide-quick-start:start) Quick start guide (https://openwrt.org/docs/guide-user/start) (docs:guide-user:start) User guide (https://openwrt.org/docs/guide-developer/start) (docs:guide-developer:start) Developer guide (https://openwrt.org/docs/guide-developer/security) (docs:guide-developer:security) Security (https://openwrt.org/faq) (faq) FAQ (https://forum.openwrt.org/) (https://forum.openwrt.org/) Forum Contributing (https://openwrt.org/submitting-patches) (submitting-patches) Submitting patches (https://openwrt.org/bugs) (bugs) Reporting bugs (https://openwrt.org/wiki/wikirules) (wiki:wikirules) Contributing to wiki Project (https://openwrt.org/about) (about) About OpenWrt (https://openwrt.org/rules) (rules) Rules (https://openwrt.org/infrastructure) (infrastructure) Infrastructure (https://openwrt.org/donate) (donate) Donate (https://openwrt.org/merchandise) (merchandise) Merchandise (https://openwrt.org/wiki/start) (wiki:start) Website (https://openwrt.org/trademark) (trademark) Trademark policy (https://openwrt.org/license) (license) License (https://openwrt.org/contact) (contact) Contacts (https://openwrt.org/docs/guide-user/virtualization/docker_host?do=edit) (Show pagesource [v]) Show pagesource (https://openwrt.org/docs/guide-user/virtualization/docker_host?do=revisions) (Old revisions [o]) Old revisions (https://openwrt.org/docs/guide-user/virtualization/docker_host?do=backlink) (Backlinks) Backlinks (Back to top [t]) Back to top (Table of Contents) Table of Contents OpenWrt as Docker container host Prerequisites Docker Community Edition Adding images Configure the Docker daemon Native OpenWrt tools Install packages Create veth pair for container Creating an OCI run-time bundle Import a OCI runtime container Podman OpenWrt as Docker container host (https://docs.docker.com/get-started/docker-overview/#docker-architecture) (https://docs.docker.com/get-started/docker-overview/#docker-architecture) Docker uses OS -level virtualization to deliver software in packages called containers. This is used to automate deployment of applications so that they work efficiently in different environments in isolation. To run containers, users may install Docker Community Edition, use native OpenWrt tools, or Podman. While Docker CE is perhaps the most typical method, this guide covers several options. Prerequisites For devices with small flash partitions you may need to add (https://openwrt.org/docs/guide-user/storage/usb-drives) (docs:guide-user:storage:usb-drives) external storage for the containers and data. Also in many cases you will be running the container as a specific user that will need access to some folder outside the container for its configuration and data. So you will probably need to (https://openwrt.org/docs/guide-user/additional-software/create-new-users) (docs:guide-user:additional-software:create-new-users) create new users and groups for applications, create folders, and then change the owner of these folders to the user who will run the container. Docker Community Edition First install dockerd, opkg install dockerd . This daemon provides the (https://docs.docker.com/engine/api/) (https://docs.docker.com/engine/api/) Docker Engine API and manages Docker objects such as images, containers, networks, and volumes. Then you need a client, e.g. docker, opkg install docker to connect to the daemon and start containers. This client is command line based. For a LuCI web client install luci-app-dockerman, opkg install luci-app-dockerman . This package will also install dockerd and docker-compose as dependencies. It can work with dockerd on local and remote hosts. The default folder for docker in dockerman is /opt/docker/ so mount your storage at /opt or change the folder in Docker > Overview > Docker Root Dir then restart the dockerd service. Adding images Search for an image on (https://hub.docker.com/) (https://hub.docker.com/) Docker Hub , then copy the image name from the Docker Pull Command text box. For example, if the text is docker pull linuxserver/transmission , then copy linuxserver/transmission . In Luci go to Docker > Images and paste that text in the Pull Image box, then click Pull . The page will show the download progress. Note for larger container pulls LuCI could timeout, so you will need to use the command line. For example, Unifi-network-application includes java runtime environment and approaches 500MB. For this use SSH and enter: docker pull lscr.io/linuxserver/unifi-network-application:latest . Once you have your images, in Luci go to Docker > Containers > Add . In the new container page select the docker image from the Docker Image menu, then set all other parameters (usually the available/useful parameters are described in the description of the container on Docker Hub), then press Submit to create the container. Configure the Docker daemon Config is located in /etc/config/dockerd . data_root a folder where to store images and containers. It's also mounted by a docker. You may want to change it to a USB disk. It's file system can't be fat or ntfs. By default /opt/docker/ log_level Default warn . hosts an API listener. By default is used a UNIX socket /var/run/docker.sock . iptables Enable iptables rules. Default 1 bip network bridge IP . Default 172.18.0.1/24 fixed_cidr Allocate IPs from a range. Default 172.17.0.0/16 fixed_cidr_v6 same as fixed_cidr for IPv6 . Default 'fc00:1::/80' ipv6 Enable IPv6 networking. Default 1 ip Default ::ffff:0.0.0.0 dns DNS Servers. Default 172.17.0.1 registry_mirrors URL of a registries. Default (https://hub.docker.com/) (https://hub.docker.com) https://hub.docker.com The following settings require a restart of docker to take full effect, A reload will only have partial or no effect: bip blocked_interfaces extra_iptables_args device Native OpenWrt tools Instead of running Docker CE users may want to use the procd init system which supports Open Container Initiative Runtime Specification set by (https://opencontainers.org/) (https://opencontainers.org/) Opencontainers.org . This extends its slim containers ('ujail') capability. The uxc command line tool handles the basic operations on containers as defined by the spec . This allows to use it as a drop-in replacement for Docker's 'runc' (or 'crun') on OpenWrt hosts with a reduced footprint. Detailed but possibly outdated info available on (https://gitlab.com/prpl-foundation/prplos/prplos/-/wikis/uxc) (https://gitlab.com/prpl-foundation/prplos/prplos/-/wikis/uxc) https://gitlab.com/prpl-foundation/prplos/prplos/-/wikis/uxc Install packages Install the following: opkg install kmod-veth uxc procd-ujail procd-ujail-console Create veth pair for container uci batch <), change your additionalimagestores back to [], disable podman service, and make sure, podman service doesn't start by creation/start of containers during boot. Then you remove all files, from /srv/.podman/images: rm -rf /srv/.podman/images reboot again, and begin this again from start of this section of guide. Pod We will start by creating a pod. Pod can hold multiple containers, they share some attributes, such as ip address. As we are trying to build a web server setup, we want IP address to be always same for this pod. I have created a script /srv/create.sh to construct this pod: #!/bin/sh podman pod create \ --replace \ --name servers \ --hostname srv \ --ip 10.129.0.2   podman pod start servers This creates, or replaces if one exists, pod named servers, gives it a hostname srv (not important) and a static IP address 10.129.0.2. Containers All configurations and statically exported data is also in /srv. In /srv/caddy I have all needed to build my caddy container, such as configurations and what ever caddy container of your choice needs. I also have a build script there, /srv/caddy/create.sh: #!/bin/sh podman create \ --name caddy \ --pod servers \ --replace \ --systemd false \ --label app =caddy \ --volume / srv/ caddy/ conf/ :/ etc/ caddy/ :Z,rw \ --volume / srv/ caddy/ htdocs/ :/ var/ htdocs/ :z,rw \ --volume / srv/ caddy/ logs/ :/ var/ log/ :z,rw \ --volume / dev/ log:/ dev/ log:Z,rw \ --mount ="type=bind,src=/etc/acme/domain.tld_ecc/domain.tld.cer,dst=/etc/caddy/ssl/server.pem,ro=true,idmap=uids=0-82-1;gids=0-82-1" \ --mount ="type=bind,src=/etc/acme/domain.tld_ecc/domain.tld.key,dst=/etc/caddy/ssl/server.key,ro=true,idmap=uids=0-82-1;gids=0-82-1" \ docker.io/ me/ my_caddy_image:latest   podman start caddy In this guide I do not review configuration of Caddy, look it up from caddy's docs. My caddy is set to run as user www:www-data which in that setup are uid 82 and gid 82, acme is used to fetch certificates, but user www(82) cannot read root owned files, so we use idmapping to map those 2 files for user www:www-data. There are multiple ways to do this, this is just one approach. You could also setup a system that chmod's those files to be available for reading to everyone, or at least for user and/or group 82. Or copy them locally and chown them in that location statically. And I have a similar script for nginx: #!/bin/sh podman create \ --name nginx \ --pod servers \ --replace \ --systemd false \ --label app =nginx \ --volume / srv/ nginx/ conf/ :/ etc/ nginx/ :Z,rw \ --volume / srv/ nginx/ logs/ :/ var/ log/ nginx/ :Z,rw \ --volume / srv/ nginx/ htdocs/ :/ var/ htdocs/ :z,rw \ --volume / dev/ log:/ dev/ log:Z,rw \ docker.io/ me/ my_nginx_image:latest   podman start nginx Now after you have configured properly your caddy and nginx, we should have a server properly running. We need to setup redirections from wan. Expose to wan Now that we have caddy serving at 10.129.0.2, ports 80 and 443, we edit /etc/config/firewall again: config redirect option name 'Allow-HTTP' option src 'wan' option dest 'podman' option src_dport '80' option dest_ip '10.129.0.2' option dest_port '80' option proto 'tcp' option reflection '0' option target 'DNAT' option enabled '1' config redirect option name 'Allow-HTTPS' option src 'wan' option dest 'podman' option src_dport '443' option dest_ip '10.129.0.2' option dest_port '443' option proto 'tcp' option reflection '0' option target 'DNAT' option enabled '1' Automation Finally, we want our pod and containers to build and start during boot, we also have acme handling our certificates, so we want to restart caddy when certificates are renewed. I added /srv/scripts directory, and added there file restart_caddy.sh: #!/bin/sh / etc/ init.d/ podman enabled || exit logger -t acme -p daemon.info "SSL certificates renewed, restarting container servers:caddy" podman stop caddy sleep 1 podman start caddy And then rest is handled by /etc/rc.local: # Put your custom commands here that should be executed once # the system init finished. By default this file does nothing. add_podman_trigger( ) { local counter =10 local running =0 [ -x "/etc/init.d/acme" ] || exit / etc/ init.d/ acme enabled || exit while [ "$counter " -gt 0 ] ; do [ "$(service podman status) " = "running" ] && { running =1 counter =0 } || { sleep 1 counter =$( ( $counter -1 ) ) } done [ "$running " -eq 1 ] && { ubus call service set '{ "name": "podman", "triggers": [[ "acme.renew", [[ "run_script", "/srv/scripts/restart_caddy.sh" ]], 2000 ]], "data": {}}' logger -t podman -p daemon.info "podman: added service trigger for acme.renew event to restart servers:caddy" } } start_podman_services( ) { / etc/ init.d/ podman enabled && { [ -f / tmp/ .podman_created ] || { touch / tmp/ .podman_created sleep 1 / srv/ create.sh sleep 2 / srv/ caddy/ create.sh sleep 2 / srv/ nginx/ create.sh   add_podman_trigger & } } } This is why starting podman service with /etc/init.d/podman comes handy, we can ignore all container related during boot, by just simply disabling service as nothing podman related is started if service is disabled. This builds our pod and both containers and then adds a trigger for podman service to restart caddy when SSL certificates are renewed. There's a routine that checks if podman service has started, because trigger must be added AFTER podman service has started. This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.OK (https://en.wikipedia.org/wiki/HTTP_cookie) More information about cookies Last modified: (2025/05/07 16:41) 2025/05/07 16:41 by phinn Self-registration in the wiki has been disabled.If you want to contribute to the OpenWrt wiki, please post (https://forum.openwrt.org/t/applying-for-openwrt-wiki-account/101671) (https://forum.openwrt.org/t/applying-for-openwrt-wiki-account/101671) HERE in the forum or ask on IRC for access. (https://creativecommons.org/licenses/by-sa/4.0/deed.en) (CC Attribution-Share Alike 4.0 International) (cc) (by) (sa) Except where otherwise noted, content on this wiki is licensed under the following license:(https://creativecommons.org/licenses/by-sa/4.0/deed.en) (CC Attribution-Share Alike 4.0 International) CC Attribution-Share Alike 4.0 International (skip to content)