Files
luci-app-zt-gateway/luci-dev/references/openwrt-docker-build.md
Malar Invention c6c5a04aca chore: clean up repo structure
- Add node_modules/, test-results/, e2e-report/, .omp/ to .gitignore
- Remove throwaway debug scripts (debug-pw*.js, debug-login-dom.js)
- Remove empty mock-server/ directory
- Untrack harness artifact (.omp/plans/)
- Add missing project files to git (e2e tests, Dockerfiles, tooling configs)
2026-07-12 23:42:54 +05:30

3.0 KiB

OpenWrt Docker Build Reference

Dockerfile Template

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):

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):

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