From 85e05b74ca580affa7708e353efdc2bcd0047d2a Mon Sep 17 00:00:00 2001 From: Adam Israel Date: Fri, 7 Jul 2023 12:05:21 -0400 Subject: [PATCH 1/3] chore: [VIO-3019] Update the Dockerfiles Update the `Dockerfile`s to use the `debian:stable-slim` as the builder, and `scratch` for the final (production) image. --- Dockerfile | 6 ++++-- dev.Dockerfile | 3 +-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index e3c9722..c1de8ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,14 @@ # # Builder Image # -FROM docker.io/vaporio/golang:1.16 as builder +FROM docker.io/library/debian:stable-slim as builder + +RUN apt-get update && apt-get install -y ca-certificates # # Final Image # -FROM docker.io/vaporio/scratch-ish:1.0.0 +FROM scratch LABEL org.label-schema.schema-version="1.0" \ org.label-schema.name="vaporio/emulator-plugin" \ diff --git a/dev.Dockerfile b/dev.Dockerfile index fdda8cf..13136c0 100644 --- a/dev.Dockerfile +++ b/dev.Dockerfile @@ -6,8 +6,7 @@ # Development images contain additional tooling that makes it easier # to exec into a contain and dig into whatever may be going on inside. # - -FROM vaporio/golang:1.16 +FROM docker.io/library/debian:stable-slim as builder WORKDIR /synse From f429a457c135e69f1f3e537ce3980b6f7b4f1965 Mon Sep 17 00:00:00 2001 From: Adam Israel Date: Wed, 12 Jul 2023 08:51:26 -0400 Subject: [PATCH 2/3] Build go binary; run as user Build the go binary statically linked so that it works in the `scratch` image. Runs as the `vaporio` user, instead of root. --- Dockerfile | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index c1de8ae..b70e172 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,10 +1,33 @@ # # Builder Image # -FROM docker.io/library/debian:stable-slim as builder +FROM docker.io/library/golang:1.16 as builder RUN apt-get update && apt-get install -y ca-certificates +RUN useradd -M vaporio + +WORKDIR /app + +# Download dependencies +COPY go.* ./ +RUN go mod download + +# Copy the project into the builder +COPY . ./ + +# Disable dynamic linking. The binary won't work on scratch otherwise +ENV CGO_ENABLED=0 + +# Build the binary. +RUN make build-linux + + +RUN mkdir -p /etc/synse/plugin/config \ + && mkdir -p /etc/synse/plugin/config \ + && chown -R vaporio /etc/synse \ + && chown -R vaporio /app + # # Final Image # @@ -16,15 +39,20 @@ LABEL org.label-schema.schema-version="1.0" \ org.label-schema.vendor="Vapor IO" COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY --from=builder /etc/group /etc/group +COPY --from=builder /etc/passwd /etc/passwd # Build the device configurations directly into the image. This is not # generally advised, but is acceptable here since the plugin is merely # an emulator and its config is not tied to anything real. -COPY config/device /etc/synse/plugin/config/device -COPY config.yml /etc/synse/plugin/config/config.yml +COPY --chown=vaporio config/device /etc/synse/plugin/config/device +COPY --chown=vaporio config.yml /etc/synse/plugin/config/config.yml # Copy the executable. -COPY synse-emulator-plugin ./plugin +COPY --chown=vaporio --from=builder /app/synse-emulator-plugin /app/plugin + EXPOSE 5001 -ENTRYPOINT ["./plugin"] + +USER vaporio +ENTRYPOINT ["/app/plugin"] \ No newline at end of file From 90a95ce2ca896fd3579ed9d380b8f9d3d73118d7 Mon Sep 17 00:00:00 2001 From: Adam Israel Date: Wed, 12 Jul 2023 09:55:43 -0400 Subject: [PATCH 3/3] Refactor Dockerfile/build In `dev.Dockerfile`, build the binary inside the Dockerfile build. In `Dockerfile`, follow the goreleaser pattern In `Makefile`, the `docker` target builds the image via gobuilder In `README.md`, add a "build" section to link to the goreleaser install page and document how to build the production image locally. --- Dockerfile | 27 ++++------------------ Makefile | 6 +---- README.md | 12 +++++++++- dev.Dockerfile | 62 +++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 68 insertions(+), 39 deletions(-) diff --git a/Dockerfile b/Dockerfile index b70e172..2fe7a19 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,32 +1,16 @@ # # Builder Image # -FROM docker.io/library/golang:1.16 as builder +# FROM docker.io/library/golang:1.16 as builder +FROM docker.io/library/debian:stable-slim as builder RUN apt-get update && apt-get install -y ca-certificates RUN useradd -M vaporio -WORKDIR /app - -# Download dependencies -COPY go.* ./ -RUN go mod download - -# Copy the project into the builder -COPY . ./ - -# Disable dynamic linking. The binary won't work on scratch otherwise -ENV CGO_ENABLED=0 - -# Build the binary. -RUN make build-linux - - RUN mkdir -p /etc/synse/plugin/config \ && mkdir -p /etc/synse/plugin/config \ - && chown -R vaporio /etc/synse \ - && chown -R vaporio /app + && chown -R vaporio /etc/synse # # Final Image @@ -49,10 +33,9 @@ COPY --chown=vaporio config/device /etc/synse/plugin/config/device COPY --chown=vaporio config.yml /etc/synse/plugin/config/config.yml # Copy the executable. -COPY --chown=vaporio --from=builder /app/synse-emulator-plugin /app/plugin - +COPY --chown=vaporio synse-emulator-plugin /plugin EXPOSE 5001 USER vaporio -ENTRYPOINT ["/app/plugin"] \ No newline at end of file +ENTRYPOINT ["/plugin"] \ No newline at end of file diff --git a/Makefile b/Makefile index 0fee180..64e0604 100644 --- a/Makefile +++ b/Makefile @@ -39,11 +39,7 @@ deploy: ## Run a local deployment of the plugin with Synse Server .PHONY: docker docker: ## Build the production docker image locally - docker build -f Dockerfile \ - --label "org.label-schema.build-date=${BUILD_DATE}" \ - --label "org.label-schema.vcs-ref=${GIT_COMMIT}" \ - --label "org.label-schema.version=${PLUGIN_VERSION}" \ - -t ${IMAGE_NAME}:latest . || exit + env GOLANG_VERSION=${GOLANG_VERSION} goreleaser release --snapshot --clean .PHONY: docker-dev docker-dev: ## Build the development docker image locally diff --git a/README.md b/README.md index 92d1b52..58d9294 100644 --- a/README.md +++ b/README.md @@ -226,11 +226,21 @@ The plugin can be run in debug mode for additional logging. This is done by: docker run -e PLUGIN_DEBUG=true vaporio/emulator-plugin ``` +### Building + +To build the production image locally, you'll first need to [install the goreleaser binary](https://goreleaser.com/install/). + +``` +make docker +``` + +This will run `goreleaser` to build a local image tagged as the current release, i.e., `docker.io/vaporio/emulator-plugin:3.4.1`. + ### Developing A [development/debug Dockerfile](Dockerfile.dev) is provided in the project repository to enable building image which may be useful when developing or debugging a plugin. Unlike the slim `scratch`-based -production image, the development image uses an ubuntu base, bringing with it all the standard command line +production image, the development image uses a Debian base, bringing with it all the standard command line tools one would expect. To build a development image: ``` diff --git a/dev.Dockerfile b/dev.Dockerfile index 13136c0..8eecdf5 100644 --- a/dev.Dockerfile +++ b/dev.Dockerfile @@ -6,21 +6,61 @@ # Development images contain additional tooling that makes it easier # to exec into a contain and dig into whatever may be going on inside. # -FROM docker.io/library/debian:stable-slim as builder +# +# Builder Image +# +FROM docker.io/library/golang:1.16 as builder + +RUN apt-get update && apt-get install -y ca-certificates + +RUN useradd -M vaporio + +WORKDIR /app + +# Download dependencies +COPY go.* ./ +RUN go mod download + +# Copy the project into the builder +COPY . ./ + +# Disable dynamic linking. The binary won't work on scratch otherwise +ENV CGO_ENABLED=0 + +# Build the binary. +RUN make build-linux -WORKDIR /synse + +RUN mkdir -p /etc/synse/plugin/config \ + && mkdir -p /etc/synse/plugin/config \ + && chown -R vaporio /etc/synse \ + && chown -R vaporio /app + +# +# Final Image +# +FROM docker.io/library/debian:stable-slim + +LABEL org.label-schema.schema-version="1.0" \ + org.label-schema.name="vaporio/emulator-plugin" \ + org.label-schema.vcs-url="https://github.com/vapor-ware/synse-emulator-plugin" \ + org.label-schema.vendor="Vapor IO" + +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY --from=builder /etc/group /etc/group +COPY --from=builder /etc/passwd /etc/passwd # Build the device configurations directly into the image. This is not # generally advised, but is acceptable here since the plugin is merely -# an emulator and its config is not tied to anything real. These config -# defaults may be overridden at run time. -COPY config/device /etc/synse/plugin/config/device -COPY config.yml /etc/synse/plugin/config/config.yml +# an emulator and its config is not tied to anything real. +COPY --chown=vaporio config/device /etc/synse/plugin/config/device +COPY --chown=vaporio config.yml /etc/synse/plugin/config/config.yml + +# Copy the executable. +COPY --chown=vaporio --from=builder /app/synse-emulator-plugin /app/plugin -# Copy the executable and README information. The executable should be -# built prior to the image build (see Makefile). -COPY synse-emulator-plugin ./plugin -COPY README.md . EXPOSE 5001 -ENTRYPOINT ["./plugin"] + +USER vaporio +ENTRYPOINT ["/app/plugin"]