Skip to content

Run the Caddy container as a non-root user #6

Description

@koinsaari

Summary

The Caddy container currently runs as root inside the container, hardened with cap_drop: ALL and cap_add: NET_BIND_SERVICE. Switching to a non-root user would be a small defense-in-depth improvement and would remove the requirement that caddy_data / caddy_config be root-owned on the host.

Context

The current model is already well-hardened: container-root has no capabilities beyond NET_BIND_SERVICE, so it cannot bypass file modes or do anything privileged. A container escape would land the attacker on the host as UID 0 anyway — that's a runtime/kernel concern, not an in-container UID concern. The reason this came up: during the recent restructure, a chown -R stoga:stoga broke Caddy because container-root, without CAP_DAC_OVERRIDE, couldn't read mode-0600 cert files owned by UID 1000. Running the container as UID 1000 would make the data dirs naturally stoga-owned and avoid this kind of footgun.

Scope

  • Set user: 1000:1000 on the caddy service
  • Make binding ports 80 and 443 work: either bake setcap cap_net_bind_service+ep into a derived image, set sysctl net.ipv4.ip_unprivileged_port_start=80 on the host, or run Caddy on high ports and forward
  • Re-chown caddy_data and caddy_config to 1000:1000

Acceptance criteria

  • Caddy comes up as UID 1000
  • All public hostnames still serve TLS on 443 from a fresh up
  • Data directories owned by 1000:1000, no sudo needed for routine ops

Notes

Draft / backlog. Marginal security gain. The official Caddy image documents running as root; going non-root is off the happy path. Filing so the rationale is preserved and we can revisit if the host-config footprint becomes worth carrying.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions