-
Notifications
You must be signed in to change notification settings - Fork 28
/
Dockerfile
184 lines (153 loc) · 5.98 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# syntax = docker/dockerfile:1.7.1
# Builds a minimal image with the binary only. It is multi-arch capable,
# cross-building to aarch64 and x86_64. When cross-compiling, Docker sets two
# implicit BUILDARG: BUILDPLATFORM being the host platform and TARGETPLATFORM
# being the platform being built.
# The Debian version and version name must be in sync
ARG DEBIAN_VERSION=12
ARG DEBIAN_VERSION_NAME=bookworm
ARG RUSTC_VERSION=1.78.0
# XXX: Upgrade to 0.10.0 blocked by https://github.com/ziglang/zig/issues/10915#issuecomment-1354548110
# XXX: Upgrade to 0.11.0 blocked by https://github.com/rust-cross/cargo-zigbuild/issues/162
ARG ZIG_VERSION=0.9.1
ARG NODEJS_VERSION=20.12.2
ARG OPA_VERSION=0.64.1
ARG CARGO_AUDITABLE_VERSION=0.6.3
ARG CARGO_CHEF_VERSION=0.1.66
ARG CARGO_ZIGBUILD_VERSION=0.18.4
##########################################
## Build stage that builds the frontend ##
##########################################
FROM --platform=${BUILDPLATFORM} docker.io/library/node:${NODEJS_VERSION}-${DEBIAN_VERSION_NAME} AS frontend
WORKDIR /app/frontend
COPY ./frontend/package.json ./frontend/package-lock.json /app/frontend/
# Network access: to fetch dependencies
RUN --network=default \
npm ci
COPY ./frontend/ /app/frontend/
COPY ./templates/ /app/templates/
RUN --network=none \
npm run build
# Move the built files
RUN --network=none \
mkdir -p /share/assets && \
cp ./dist/manifest.json /share/manifest.json && \
rm -f ./dist/index.html* ./dist/manifest.json* && \
cp ./dist/* /share/assets/
##############################################
## Build stage that builds the OPA policies ##
##############################################
FROM --platform=${BUILDPLATFORM} docker.io/library/buildpack-deps:${DEBIAN_VERSION_NAME} AS policy
ARG BUILDOS
ARG BUILDARCH
ARG OPA_VERSION
# Download Open Policy Agent
ADD --chmod=755 https://github.com/open-policy-agent/opa/releases/download/v${OPA_VERSION}/opa_${BUILDOS}_${BUILDARCH}_static /usr/local/bin/opa
WORKDIR /app/policies
COPY ./policies /app/policies
RUN --network=none \
make -B && \
chmod a+r ./policy.wasm
##########################################################################
## Base image with cargo-chef and the right cross-compilation toolchain ##
##########################################################################
FROM --platform=${BUILDPLATFORM} docker.io/library/rust:${RUSTC_VERSION}-${DEBIAN_VERSION_NAME} AS toolchain
ARG CARGO_AUDITABLE_VERSION
ARG CARGO_CHEF_VERSION
ARG CARGO_ZIGBUILD_VERSION
ARG RUSTC_VERSION
ARG ZIG_VERSION
# Make cargo use the git cli for fetching dependencies
ENV CARGO_NET_GIT_FETCH_WITH_CLI=true
# Install pinned versions of cargo-chef, cargo-zigbuild and cargo-auditable
# Network access: to fetch dependencies
RUN --network=default \
cargo install --locked \
cargo-chef@=${CARGO_CHEF_VERSION} \
cargo-zigbuild@=${CARGO_ZIGBUILD_VERSION} \
cargo-auditable@=${CARGO_AUDITABLE_VERSION}
# Download zig compiler for cross-compilation
# Network access: to download zig
RUN --network=default \
curl -L "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-$(uname -m)-${ZIG_VERSION}.tar.xz" | tar -J -x -C /usr/local && \
ln -s "/usr/local/zig-linux-$(uname -m)-${ZIG_VERSION}/zig" /usr/local/bin/zig
# Install all cross-compilation targets
# Network access: to download the targets
RUN --network=default \
rustup target add \
--toolchain "${RUSTC_VERSION}" \
x86_64-unknown-linux-gnu \
aarch64-unknown-linux-gnu
# Set the working directory
WORKDIR /app
#####################################
## Run the planner from cargo-chef ##
#####################################
FROM --platform=${BUILDPLATFORM} toolchain AS planner
COPY ./Cargo.toml ./Cargo.lock /app/
COPY ./crates /app/crates
RUN --network=none \
cargo chef prepare --recipe-path recipe.json --bin crates/cli
########################
## Actual build stage ##
########################
FROM --platform=${BUILDPLATFORM} toolchain AS builder
# Build dependencies
COPY --from=planner /app/recipe.json recipe.json
# Network access: cargo-chef cook fetches the dependencies
RUN --network=default \
cargo chef cook \
--zigbuild \
--bin mas-cli \
--release \
--recipe-path recipe.json \
--no-default-features \
--features docker \
--target x86_64-unknown-linux-gnu \
--target aarch64-unknown-linux-gnu \
--package mas-cli
# Build the rest
COPY ./Cargo.toml ./Cargo.lock /app/
COPY ./crates /app/crates
ENV SQLX_OFFLINE=true
# Network access: cargo auditable needs it
RUN --network=default \
cargo auditable zigbuild \
--locked \
--release \
--bin mas-cli \
--no-default-features \
--features docker \
--target x86_64-unknown-linux-gnu \
--target aarch64-unknown-linux-gnu
# Move the binary to avoid having to guess its name in the next stage
RUN --network=none \
mv "target/x86_64-unknown-linux-gnu/release/mas-cli" /usr/local/bin/mas-cli-amd64
RUN --network=none \
mv "target/aarch64-unknown-linux-gnu/release/mas-cli" /usr/local/bin/mas-cli-arm64
#######################################
## Prepare /usr/local/share/mas-cli/ ##
#######################################
FROM --platform=${BUILDPLATFORM} scratch AS share
COPY --from=frontend /share /share
COPY --from=policy /app/policies/policy.wasm /share/policy.wasm
COPY ./templates/ /share/templates
COPY ./translations/ /share/translations
##################################
## Runtime stage, debug variant ##
##################################
FROM --platform=${TARGETPLATFORM} gcr.io/distroless/base-nossl-debian${DEBIAN_VERSION}:debug-nonroot AS debug
ARG TARGETARCH
COPY --from=builder /usr/local/bin/mas-cli-${TARGETARCH} /usr/local/bin/mas-cli
COPY --from=share /share /usr/local/share/mas-cli
WORKDIR /
ENTRYPOINT ["/usr/local/bin/mas-cli"]
###################
## Runtime stage ##
###################
FROM --platform=${TARGETPLATFORM} gcr.io/distroless/base-nossl-debian${DEBIAN_VERSION}:nonroot
ARG TARGETARCH
COPY --from=builder /usr/local/bin/mas-cli-${TARGETARCH} /usr/local/bin/mas-cli
COPY --from=share /share /usr/local/share/mas-cli
WORKDIR /
ENTRYPOINT ["/usr/local/bin/mas-cli"]