Skip to content

feat(docker): non-root image binds :80/:443 via CAP_NET_BIND_SERVICE file capability#714

Merged
jarvis9443 merged 1 commit into
mainfrom
feat/nonroot-bind-privileged-ports
Jul 3, 2026
Merged

feat(docker): non-root image binds :80/:443 via CAP_NET_BIND_SERVICE file capability#714
jarvis9443 merged 1 commit into
mainfrom
feat/nonroot-bind-privileged-ports

Conversation

@jarvis9443

@jarvis9443 jarvis9443 commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Customers deploying the DP on Kubernetes with hostNetwork: true want the proxy listener directly on node port 80. The image runs as uid 10001, so binding a privileged port previously required running the container as root (or shipping a separate root image variant).

Instead, the Dockerfile now sets the cap_net_bind_service=+ep file capability on the binary. The image stays non-root and can bind 80/443 in plain Docker, in hostNetwork pods, and under the restricted Pod Security Standard (drop: [ALL] + add: [NET_BIND_SERVICE]). Same approach as Traefik/Envoy images. No separate root image, no release-workflow changes.

Implementation notes:

  • install + setcap happen in one bind-mount RUN (no COPY --from for the binary) so the xattr change doesn't duplicate the ~large binary into a second layer, and because COPY does not reliably carry security.capability xattrs;
  • libcap2-bin is purged again in the same layer.

Behavior change / compatibility: NET_BIND_SERVICE is in the default Docker/containerd capability set, so default deployments are unaffected. The one caveat: a pod that drops ALL capabilities without adding NET_BIND_SERVICE back now fails at exec (Operation not permitted) instead of starting — with the effective bit set, the kernel refuses to exec a binary whose file capabilities cannot be granted. Documented in the paired docs PR (api7/docs#1766).

Testing: docker-image.yml PR builds now load the image and smoke-test the contract — run the container with the default non-root user on the host network with proxy.addr: 0.0.0.0:80 and require /livez to answer. The test fails on the pre-fix image (proxy serve error: Permission denied (os error 13)) and passes with this change. Also locally verified: --cap-drop ALL fails exec as documented, --cap-drop ALL --cap-add NET_BIND_SERVICE works.

🤖 Generated with Claude Code

…:80/:443

Customers deploying the DP with Kubernetes hostNetwork want the proxy
listener directly on node port 80. The image runs as uid 10001, so the
bind previously required running the container as root (or a separate
root image). Set the cap_net_bind_service=+ep file capability on the
binary instead: the image stays non-root and privileged ports work in
plain Docker, hostNetwork pods, and under the restricted Pod Security
Standard (drop ALL + add NET_BIND_SERVICE).

Install + setcap happen in one bind-mount RUN so the xattr change does
not duplicate the binary into a second layer (and COPY --from does not
reliably carry xattrs).

PR builds now load the image and smoke-test the contract: run the
container on the host network with proxy.addr :80 and require /livez
to answer — fails on the pre-fix image where the bind is refused.
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 7 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0cec2339-488c-49b1-bc00-80f7d56943a9

📥 Commits

Reviewing files that changed from the base of the PR and between bae570f and ce3389a.

📒 Files selected for processing (2)
  • .github/workflows/docker-image.yml
  • Dockerfile
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/nonroot-bind-privileged-ports

Comment @coderabbitai help to get the list of available commands.

@jarvis9443 jarvis9443 merged commit 13f09ff into main Jul 3, 2026
10 checks passed
@jarvis9443 jarvis9443 deleted the feat/nonroot-bind-privileged-ports branch July 3, 2026 06:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant