-
Notifications
You must be signed in to change notification settings - Fork 32
/
Dockerfile
144 lines (120 loc) · 5.55 KB
/
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# Copyright 2021 IBM Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###############################################################################
# Stage 1: Create the developer image for the BUILDPLATFORM only
###############################################################################
ARG GOLANG_VERSION=1.21
FROM --platform=$BUILDPLATFORM registry.access.redhat.com/ubi8/go-toolset:$GOLANG_VERSION AS develop
ARG PROTOC_VERSION=21.12
USER root
ENV HOME=/root
# Install build and dev tools
# NOTE: Require python38 to install pre-commit
RUN --mount=type=cache,target=/root/.cache/dnf:rw \
dnf install --setopt=cachedir=/root/.cache/dnf -y --nodocs \
nodejs \
python38 \
&& ln -sf /usr/bin/python3 /usr/bin/python \
&& ln -sf /usr/bin/pip3 /usr/bin/pip \
&& true
# Install pre-commit
ENV PIP_CACHE_DIR=/root/.cache/pip
RUN --mount=type=cache,target=/root/.cache/pip \
pip install pre-commit
# When using the BuildKit backend, Docker predefines a set of ARG variables with
# information on the platform of the node performing the build (build platform)
# These arguments are defined in the global scope but are not automatically available
# inside build stages. We need to expose the BUILDOS and BUILDARCH inside the build
# stage and redefine it without a value
# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
ARG BUILDOS
ARG BUILDARCH
# Install protoc
# The protoc download files use a different variation of architecture identifiers
# from the Docker BUILDARCH forms amd64, arm64, ppc64le, s390x
# protoc-22.2-linux-aarch_64.zip <- arm64
# protoc-22.2-linux-ppcle_64.zip <- ppc64le
# protoc-22.2-linux-s390_64.zip <- s390x
# protoc-22.2-linux-x86_64.zip <- amd64
# so we need to map the arch identifiers before downloading the protoc.zip using
# shell parameter expansion: with the first character of a parameter being an
# exclamation point (!) it introduces a level of indirection where the value
# of the parameter is used as the name of another variable and the value of that
# other variable is the result of the expansion, e.g. the echo statement in the
# following three lines of shell script print "x86_64"
# BUILDARCH=amd64
# amd64=x86_64
# echo ${!BUILDARCH}
RUN set -eux; \
amd64=x86_64; \
arm64=aarch_64; \
ppc64le=ppcle_64; \
s390x=s390_64; \
wget -qO protoc.zip "https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-${BUILDOS}-${!BUILDARCH}.zip" \
&& sha256sum protoc.zip \
&& unzip protoc.zip -x readme.txt -d /usr/local \
&& protoc --version \
&& true
WORKDIR /opt/app
COPY go.mod go.sum ./
# Download dependencies before copying the source so they will be cached
RUN go mod download
# Install go protoc plugins,
# no required module provides package google.golang.org/grpc/cmd/protoc-gen-go-grpc
# to add it run `go get google.golang.org/grpc/cmd/protoc-gen-go-grpc`
ENV PATH $HOME/go/bin:$PATH
RUN true \
&& go get google.golang.org/grpc/cmd/[email protected] \
&& go install google.golang.org/grpc/cmd/protoc-gen-go-grpc \
google.golang.org/protobuf/cmd/protoc-gen-go \
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway \
&& protoc-gen-go --version \
&& true
# Download and initialize the pre-commit environments before copying the source so they will be cached
COPY .pre-commit-config.yaml ./
RUN git init && \
pre-commit install-hooks && \
git config --global --add safe.directory "*" && \
rm -rf .git
# the ubi/go-toolset image doesn't define ENTRYPOINT or CMD, but we need it to run 'make develop'
CMD /bin/bash
###############################################################################
# Stage 2: Run the go build with BUILDPLATFORM's native go compiler
###############################################################################
FROM --platform=$BUILDPLATFORM develop AS build
LABEL image="build"
# Copy the source
COPY . ./
# https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope
# don't provide "default" values (e.g. 'ARG TARGETARCH=amd64') for non-buildx environments,
# see https://github.com/docker/buildx/issues/510
ARG TARGETOS
ARG TARGETARCH
# Build the binaries using native go compiler from BUILDPLATFORM but compiled output for TARGETPLATFORM
# https://www.docker.com/blog/faster-multi-platform-builds-dockerfile-cross-compilation-guide/
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg \
GOOS=${TARGETOS:-linux} \
GOARCH=${TARGETARCH:-amd64} \
CGO_ENABLED=0 \
GO111MODULE=on \
go build -a -o /go/bin/server ./proxy/
###############################################################################
# Stage 3: Copy binaries only to create the smallest final runtime image
###############################################################################
FROM registry.access.redhat.com/ubi8/ubi-micro:latest as runtime
ARG USER=2000
USER ${USER}
COPY --from=build /go/bin/server /go/bin/server
CMD ["/go/bin/server"]