-
Notifications
You must be signed in to change notification settings - Fork 83
feat: add rootless images #428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Ivan P <[email protected]>
Signed-off-by: Ivan P <[email protected]>
Signed-off-by: Ivan P <[email protected]>
Signed-off-by: Ivan P <[email protected]>
|
Is anyone available to take a look at this and offer feedback? There are several issues discussing the need for a rootless image. Our team is working on several Hyperledger and OpenWallet Foundation projects utilizing Caddy server as a reverse proxy. |
|
Sorry for the wait. Thanks for this, I think it's the way we should go (separate tagged variant for rootless), rather than try to force the main one to support rootless (which is what prior discussion has always suggested). There's still some things I think won't work well though, like the I want to get @hairyhenderson's thoughts on this before moving ahead with it though. |
|
Overall I'm supportive of this - @francislavoie and I have chatted about this and I'll let him make a few comments and get this merged. Thanks for your patience, @i5okie! |
|
|
||
| # Create non-root user with UID 1001 and root group (GID 0) | ||
| # OpenShift will override the UID but keep GID=0 | ||
| RUN adduser -D -u 1001 -g 0 -H -h /usr/bin caddy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this isn't correct, Alpine uses busybox's adduser which has different flags. -g is "GECOS", not group ID. See https://linux.die.net/man/1/busybox (ctrl+f for adduser).
| @@ -0,0 +1,47 @@ | |||
| FROM golang:1.25-alpine3.22 | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need a rootless builder? Is there a point to that? Can't the root builder be used anyway since it's only ever for multi-stage builds?
| RUN chown -R 1001:0 /data /config /etc/caddy /usr/share/caddy /usr/bin/caddy | ||
|
|
||
| # Make directories writable by the root group for OpenShift compatibility | ||
| RUN chmod -R g+w /data /config /etc/caddy /usr/share/caddy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users shouldn't be putting any files in /usr/share/caddy, this is just for the default welcome index.html.
| RUN chmod -R g+w /data /config /etc/caddy /usr/share/caddy | |
| RUN chmod -R g+w /data /config /etc/caddy |
Users would be writing their own Caddyfile (or more config files to import) to /etc/caddy/Caddyfile, so having that writable does make sense.
Of course /data and /config should also be writable so Caddy can work as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should /usr/bin/caddy be writable by the rootless user ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would it need to be @crntnvdl ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RUN chown -R 1001:0 [...] /usr/bin/caddy effectively gives write permission to the rootless user to write the caddy binary, I don't think this should be allowed ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, this thread is not a comment on that line, it just happens to be in the range github shows. That's a valid comment though.
Add rootless Docker images for enhanced security and Kubernetes/OpenShift compatibility
Purpose
This PR adds rootless variants of the Caddy Docker images that run as a non-root user (UID 1001), making them suitable for security-constrained environments like Kubernetes and OpenShift, while remaining a drop-in replacement for the alpine images.
Why rootless?
Security best practices: Running containers as root is discouraged in production environments. Non-root containers provide defense-in-depth by limiting the impact of potential container breakouts or exploits.
Kubernetes/OpenShift requirements: Many Kubernetes clusters enforce Pod Security Standards that prohibit root containers. OpenShift, in particular, assigns arbitrary UIDs to containers by default and requires images to support this pattern.
Port restrictions: Non-root users cannot bind to privileged ports (< 1024). Using ports 80 and 443 in Kubernetes is problematic anyway since:
What's included
New image variants:
caddy:rootless- Rootless runtime image (ports 8080, 8443, 2019)caddy:rootless-builder- Rootless builder image for custom Caddy builds with xcaddyKey features:
Implementation details:
The rootless templates are based on the standard alpine templates with these modifications:
setcapcapability (not needed for non-privileged ports)adduser -D -u 1001 -g 0chown 1001:0) and group permissions (chmod g+w) on all Caddy directoriessedto replace:80with:{$CADDY_HTTP_PORT:8080}CADDY_HTTP_PORT=8080andCADDY_HTTPS_PORT=8443environment variablesUSER 1001directive to run as non-rootTesting
Built and tested locally - serves the welcome page on port 8080 as expected. The image runs without root privileges and properly serves static content.