Skip to content
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

x/pkgsite: Dockerfile.frontend should use a scratch base image #48605

Open
sfllaw opened this issue Sep 24, 2021 · 5 comments
Open

x/pkgsite: Dockerfile.frontend should use a scratch base image #48605

sfllaw opened this issue Sep 24, 2021 · 5 comments
Labels
NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. pkgsite

Comments

@sfllaw
Copy link
Contributor

sfllaw commented Sep 24, 2021

Problem

Currently, devtools/docker/Dockerfile.frontend uses the golang image as its base image.

This is inconsistent with modern best practices, where services are typically hosted on the minimal scratch image. The current image has an entire operating system and the Go toolchain included, which is unnecessary because only the frontend and its data are copied in. The frontend doesn’t need an entire OS to run.

Suggested solution

  1. Build cmd/frontend with CGO_ENABLED=0 to produce a statically linked binary.
  2. Use FROM scratch to build the final Docker image.

Links

Related: #39827

@gopherbot gopherbot added this to the Unreleased milestone Sep 24, 2021
@sfllaw
Copy link
Contributor Author

sfllaw commented Sep 24, 2021

Here is a sample devtools/docker/Dockerfile.frontend that works for me:

# Copyright 2021 The Go Authors. All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

# This Dockerfile expects the build context to be the public repo root.

################################################################
FROM golang:1.16.7 AS builder

# Set the working directory outside $GOPATH to ensure module mode is enabled.
WORKDIR /src

# Copy go.mod and go.sum into the container.
# If they don't change, which is the common case, then docker can
# cache this COPY and the subsequent RUN.
COPY go.mod go.sum all.bash /

# Download the dependencies.
RUN go mod download

# Copy the pkgsite repo from local machine into Docker client’s current working
# directory, so that we can use it to build the frontend.
# See .dockerignore at the repo root for excluded files.
COPY . /src

# Build the frontend.
RUN CGO_ENABLED=0 go build -mod=readonly ./cmd/frontend

################################################################
FROM busybox:1.32-musl AS busybox

FROM scratch

WORKDIR app

COPY --from=busybox /bin/sh /bin/
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

COPY --from=builder src/frontend      frontend
COPY static                           static
COPY third_party                      third_party

@sfllaw
Copy link
Contributor Author

sfllaw commented Sep 24, 2021

The above Dockerfile as a diff:

diff --git a/devtools/docker/Dockerfile.frontend b/devtools/docker/Dockerfile.frontend
index a35f73da..f17135ac 100644
--- a/devtools/docker/Dockerfile.frontend
+++ b/devtools/docker/Dockerfile.frontend
@@ -6,7 +6,6 @@
 
 ################################################################
 FROM golang:1.16.7 AS builder
-# If you change the Go version above, change the FROM line below as well.
 
 # Set the working directory outside $GOPATH to ensure module mode is enabled.
 WORKDIR /src
@@ -25,13 +24,18 @@ RUN go mod download
 COPY . /src
 
 # Build the frontend.
-RUN go build -mod=readonly ./cmd/frontend
+RUN CGO_ENABLED=0 go build -mod=readonly ./cmd/frontend
 
 ################################################################
-FROM golang:1.16.7
+FROM busybox:1.32-musl AS busybox
+
+FROM scratch
 
 WORKDIR app
 
+COPY --from=busybox /bin/sh /bin/
+COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
+
 COPY --from=builder src/frontend      frontend
 COPY static                           static
 COPY third_party                      third_party

@sfllaw sfllaw changed the title x/pkgsite: Dockerfile.frontend should be use a scratch base image x/pkgsite: Dockerfile.frontend should use a scratch base image Sep 24, 2021
@ALTree ALTree added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Sep 24, 2021
@jamalc jamalc modified the milestones: Unreleased, pkgsite/unplanned Oct 4, 2021
@mitar
Copy link
Contributor

mitar commented Nov 28, 2021

Are you sure scratch is enough and not something like gcr.io/distroless/static?

@sfllaw
Copy link
Contributor Author

sfllaw commented Nov 29, 2021

@mitar That is a good question. Since frontend relies on GOPROXY, having the CA certificates baked in to the image might be very nice.

@sfllaw
Copy link
Contributor Author

sfllaw commented Dec 4, 2021

Also, it would probably be best to add an ENTRYPOINT statement in there: https://github.com/docker-library/official-images#consistency:

If the image only contains the main executable and its linked libraries (ie no shell) then it is fine to use the executable as the ENTRYPOINT, since that is the only thing that can run:

ENTRYPOINT ["fully-static-binary"]
CMD ["--help"]

The most common indicator of whether this is appropriate is that the image Dockerfile starts with scratch (FROM scratch).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. pkgsite
Projects
None yet
Development

No branches or pull requests

5 participants