Run as a non-root user in containers - #581
Draft
emersonian wants to merge 2 commits into
Draft
Conversation
The image was built from golang:1.25 and shipped as-is, so it carried the entire Go toolchain and a copy of the source tree into production, and re-downloaded dependencies on every source change. Build in a golang:1.25-alpine stage and copy only the resulting binary into an alpine:3.21 runtime, which takes the image from ~1.9 GB to ~51 MB. Copy go.mod/go.sum ahead of the source so module downloads are cached in their own layer. Runtime behaviour is deliberately unchanged: the container still runs as root, and the lightwalletd user keeps uid/gid 2002 and ownership of /var/lib/lightwalletd/db, exactly as before. Running as that user is a worthwhile hardening but would break existing deployments whose data directories were written as root, so it is left to a separate change. The build still runs from a full checkout, so the git describe and git rev-parse in the Makefile continue to stamp version metadata into the binary. One visible difference: an Alpine base has no bash, so shells into the container need sh.
The image has always created a lightwalletd user (uid/gid 2002) and given it ownership of /var/lib/lightwalletd/db, but never set USER, so the container ran as root and the user went unused. Set USER lightwalletd, so a compromise of the process does not start out with root in the container. This is a breaking change for existing deployments, and is kept separate from the Alpine image rework for that reason. A data directory created by an earlier root-running container is owned by root, so the unprivileged process cannot write its block cache and fails with permission denied. Operators must chown the directory to 2002:2002, or run with --user 0:0 to keep the previous behaviour. Deployments on a fresh volume are unaffected, since a new volume inherits the image's 2002:2002 ownership. CHANGELOG.md carries the migration step.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The lightwalletd Dockerfile adds a user account that it does not use, instead running lightwalletd as root.
Prerequisite: Alpine PR #578
This PR runs lightwalletd as a non-root user inside containers for additional security.
This will be a breaking change for container operators due to permissions variances on the data directory across container runtimes, and as such should cause a minor version bump of lightwalletd if merged in my opinion.