# OpenWrt Docker Build Reference ## Dockerfile Template ```dockerfile FROM openwrt/rootfs:latest # Install LuCI and dependencies. # Build this image with podman (NOT docker buildx) because Podman-backed Docker # seccomp blocks uclient-fetch syscalls at a level BuildKit cannot override. RUN mkdir -p /etc/apk/repositories.d /var/lock /var/run /www && \ printf \ 'https://downloads.openwrt.org/snapshots/targets/x86/64/packages/packages.adb\n\ https://downloads.openwrt.org/snapshots/packages/x86_64/base/packages.adb\n\ https://downloads.openwrt.org/snapshots/packages/x86_64/luci/packages.adb\n\ https://downloads.openwrt.org/snapshots/packages/x86_64/packages/packages.adb\n\ https://downloads.openwrt.org/snapshots/packages/x86_64/routing/packages.adb\n' \ > /etc/apk/repositories.d/distfeeds.list && \ apk add --no-cache --allow-untrusted \ luci-base luci-mod-admin-full luci-proto-ppp \ uhttpd uhttpd-mod-ubus ucode-mod-lua \ ca-certificates curl # Application files (self-contained image; compose may override with volumes) COPY root/usr/sbin/zt-gateway-switch /usr/sbin/zt-gateway-switch RUN chmod +x /usr/sbin/zt-gateway-switch && \ rm -f /var/run/zt-gateway-drain.* /tmp/zt-gw-stderr /tmp/zt-gw-out-* COPY docker/openwrt-luci-entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh EXPOSE 80 ENTRYPOINT ["/entrypoint.sh"] ``` ## Build Commands **Use Podman** (image storage is shared with Docker on Podman-backed systems): ```bash podman build --security-opt seccomp=unconfined \ -t zt-gateway-luci:dev \ -f Dockerfile.openwrt . ``` Then start the stack with Docker Compose (it will find the already-built image): ```bash docker compose up -d ``` ## Why Docker BuildKit Fails Podman applies seccomp filtering at the OCI runtime level. BuildKit's `RUN --security=insecure` only affects BuildKit's internal seccomp sandbox, not the Podman runtime sandbox. Therefore `docker buildx build --allow security.insecure` still blocks musl-libc syscalls used by `uclient-fetch`. `podman build --security-opt seccomp=unconfined` passes the flag directly to the runtime, bypassing both Podman and crun seccomp profiles, allowing `apk add` to function. ## Common Issues | Problem | Root Cause | Fix | |---|---|---| | `wget: Operation not permitted` | BuildKit/Podman seccomp blocks musl-libc syscalls used by `uclient-fetch` | Use `podman build --security-opt seccomp=unconfined` | | `wget: exited with error 8` | `APKINDEX.tar.gz` 404; OpenWrt uses `packages.adb` | Append `/packages.adb` to repo URLs | | `UNTRUSTED signature` | Base rootfs lacks OpenWrt apk signing keys | `apk add --allow-untrusted` | | Post-install script fails | `/var/lock` missing; procd scripts try to create lockfiles | `mkdir -p /var/lock /var/run` before `apk add` | | `uhttpd: not found` | Base image lacks web server | Explicitly install `uhttpd uhttpd-mod-ubus` | | `conntrack-tools` missing | Kernel-userland packages don't exist as apk packages | Skip them; container shares host kernel | | `sleep 0.5` fails | busybox `sleep` only supports integer seconds | Use `sleep 1` |