This significantly reworks the docker support to provide build a
lightweight non-root distroless container image based on scratch. It
employs a multi-stage build that downloads and builds the latest source
code, compresses the resulting binaries, and then produces the final
image based on scratch that only includes the Decred-specific binaries.
It must be noted that there are some still remaining TODO items in the
documentation as well as the Dockerfile that will need to be handled by
a future commit, but the changes are being submitted now to allow
another contributor to finish up those aspects.
The following is an overview of the changes:
- Removes existing Dockerfile and Dockerfile.alpine
- Introduces a new Dockerfile under contrib/docker with the following
properties:
- Runs as a non-root user
- Uses a static UID:GID of 10000:10000
- Note that using UIDs/GIDs below 10000 for container users is a
security risk on several systems since a hypothetical attack which
allows escalation outside of the container might otherwise
coincide with an existing user's UID or existing group's GID which
has additional permissions
- The image is based on scratch image (aka completely empty) and only
includes the Decred-specific binaries which means there is no shell
or any other binaries available if an attacker were to somehow
manage to find a remote execution vulnerability exploit in a Decred
binary
- Introduces code to build an entrypoint for the image since it is based
on scratch and thus has no shell for that purpose
- Adds contrib/docker/README.md
- Updates README.md in the main directory to account for changes
- There is still outstanding work to be done here and thus has several
TODOs
- Updates contrib/README.md to call out the new addition
84 lines
2.6 KiB
Docker
84 lines
2.6 KiB
Docker
|
|
# TODO: Needs some documentation here about the RPC server, logging via docker
|
|
# logs, mounting a volume, the conf file, etc...
|
|
|
|
###############
|
|
# Builder Stage
|
|
###############
|
|
|
|
# Basic Go environment with git, SSL CA certs, and upx.
|
|
# golang:1.17.1-alpine (linux/amd64)
|
|
FROM golang@sha256:13919fb9091f6667cb375d5fdf016ecd6d3a5d5995603000d422b04583de4ef9 AS builder
|
|
RUN apk add --no-cache git ca-certificates upx
|
|
|
|
# Empty directory to be copied into place in the production image since it will
|
|
# run as a non-root container and thus not have permissions to create
|
|
# directories or change ownership of anything outside of the structure already
|
|
# created for it.
|
|
RUN mkdir /emptydatadir
|
|
|
|
# New unprivileged user for use in production image below to improve security.
|
|
ENV USER=decred
|
|
ENV UID=10000
|
|
RUN adduser \
|
|
--disabled-password \
|
|
--gecos "" \
|
|
--home="/home/${USER}" \
|
|
--shell "/sbin/nologin" \
|
|
--no-create-home \
|
|
--uid "${UID}" \
|
|
"${USER}"
|
|
|
|
# Build dcrd and other commands it provides
|
|
WORKDIR /go/src/github.com/decred/dcrd
|
|
RUN git clone https://github.com/decred/dcrd . && \
|
|
CGO_ENABLED=0 GOOS=linux \
|
|
go install -trimpath -tags safe,netgo,timetzdata \
|
|
-ldflags="-s -w" \
|
|
. ./cmd/gencerts ./cmd/promptsecret
|
|
|
|
# Build dcrctl
|
|
WORKDIR /go/src/github.com/decred/dcrctl
|
|
RUN git clone https://github.com/decred/dcrctl . && \
|
|
CGO_ENABLED=0 GOOS=linux \
|
|
go install -trimpath -tags safe,netgo -ldflags="-s -w"
|
|
|
|
# Build entrypoint helper for the production image.
|
|
WORKDIR /go/src/github.com/decred/dcrd/contrib/docker/entrypoint
|
|
COPY ./contrib/docker/entrypoint/entrypoint.go .
|
|
RUN go mod init entrypoint && \
|
|
go mod tidy && \
|
|
CGO_ENABLED=0 GOOS=linux \
|
|
go install -trimpath -tags netgo,timetzdata -ldflags="-s -w" .
|
|
|
|
# Compress bins
|
|
RUN upx -9 /go/bin/*
|
|
|
|
##################
|
|
# Production image
|
|
##################
|
|
|
|
# Minimal scratch-based environment.
|
|
FROM scratch
|
|
ENV DECRED_DATA=/home/decred
|
|
#ENV DCRD_EXPOSE_RPC=false # TODO: Want something like this?
|
|
ENV DCRD_NO_FILE_LOGGING=true
|
|
COPY --from=builder /etc/passwd /etc/passwd
|
|
COPY --from=builder /etc/group /etc/group
|
|
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
|
COPY --from=builder /go/bin/* /bin/
|
|
COPY --from=builder --chown=decred /emptydatadir /tmp
|
|
|
|
# Use an unprivileged user.
|
|
USER decred
|
|
|
|
# Ports for the p2p and json-rpc of mainnet, testnet, and simnet, respectively.
|
|
EXPOSE 9108 9109 19108 19109 18555 19556
|
|
|
|
ENTRYPOINT [ "/bin/entrypoint" ]
|
|
|
|
RUN [ "dcrd", "--version" ]
|
|
|
|
# TODO: Want this or not? I've seen conflicting info and I'm not a docker expert...
|
|
#VOLUME [ "/home/decred" ]
|