-
Notifications
You must be signed in to change notification settings - Fork 21
Expand file tree
/
Copy pathDockerfile
More file actions
362 lines (295 loc) · 12.5 KB
/
Dockerfile
File metadata and controls
362 lines (295 loc) · 12.5 KB
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# Copyright The containerd Authors.
# 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.
# -----------------------------------------------------------------------------
# syntax=docker/dockerfile:1
# Build the Linux kernel, initrd ,and containerd shim for running nerbox
ARG XX_VERSION=1.9.0
ARG GO_VERSION=1.26.2
ARG BASE_DEBIAN_DISTRO="bookworm"
ARG GOLANG_IMAGE="golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO}"
ARG GOLANGCI_LINT_VERSION=2.7.2
ARG GOLANGCI_FROM_SOURCE=false
ARG DOCKER_VERSION=28.4.0
ARG DOCKER_IMAGE="docker:${DOCKER_VERSION}-cli"
ARG RUST_IMAGE="rust:1.89.0-slim-${BASE_DEBIAN_DISTRO}"
# xx is a helper for cross-compilation
FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx
FROM --platform=$BUILDPLATFORM ${GOLANG_IMAGE} AS base
RUN echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
RUN apt-get update && apt-get install --no-install-recommends -y file
FROM base AS kernel-build-base
# Set environment variables for non-interactive installations
ENV DEBIAN_FRONTEND=noninteractive
RUN echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
# Install build dependencies
RUN --mount=type=cache,sharing=locked,id=kernel-aptlib,target=/var/lib/apt \
--mount=type=cache,sharing=locked,id=kernel-aptcache,target=/var/cache/apt \
apt-get update && apt-get install -y build-essential libncurses-dev flex bison libssl-dev libelf-dev bc cpio git wget xz-utils pahole
ARG KERNEL_VERSION="6.12.44"
ARG KERNEL_ARCH="x86_64"
ARG KERNEL_NPROC
ARG KERNEL_PAGE_SIZE="4k"
# Validate KERNEL_PAGE_SIZE early
RUN <<EOT
set -e
case "${KERNEL_PAGE_SIZE}" in
4k|16k) ;;
*) echo "ERROR: unsupported KERNEL_PAGE_SIZE=${KERNEL_PAGE_SIZE} (must be 4k or 16k)" ; exit 1 ;;
esac
if [ "${KERNEL_PAGE_SIZE}" = "16k" ] && [ "${KERNEL_ARCH}" != "arm64" ]; then
echo "ERROR: KERNEL_PAGE_SIZE=16k is only supported on arm64, not ${KERNEL_ARCH}" ; exit 1
fi
EOT
# Install cross-compiler if host architecture differs from target
RUN --mount=type=cache,sharing=locked,id=kernel-aptlib,target=/var/lib/apt \
--mount=type=cache,sharing=locked,id=kernel-aptcache,target=/var/cache/apt <<EOT
HOST_ARCH=$(uname -m)
# Normalize host arch to match KERNEL_ARCH naming
case "${HOST_ARCH}" in
aarch64) HOST_ARCH=arm64 ;;
esac
if [ "${HOST_ARCH}" != "${KERNEL_ARCH}" ]; then
case "${KERNEL_ARCH}" in
arm64) apt-get update && apt-get install -y gcc-aarch64-linux-gnu ;;
x86_64) apt-get update && apt-get install -y gcc-x86-64-linux-gnu ;;
*) echo "Unsupported architecture: ${KERNEL_ARCH}" ; exit 1 ;;
esac
fi
EOT
# Set the working directory
WORKDIR /usr/src
RUN wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-${KERNEL_VERSION}.tar.xz && \
tar -xf linux-${KERNEL_VERSION}.tar.xz && \
rm linux-${KERNEL_VERSION}.tar.xz && \
mv linux-${KERNEL_VERSION} linux
#COPY --from=config-build /usr/src/fragments/.config /usr/src/linux/.config
COPY kernel/config-${KERNEL_VERSION}-${KERNEL_ARCH} /usr/src/linux/.config
COPY kernel/patches /usr/src/linux/patches
RUN <<EOT
for patch in $(ls -d /usr/src/linux/patches/*.patch); do
patch -p1 -d /usr/src/linux < "$patch";
done
EOT
# Adjust kernel page size for arm64 (x86_64 only supports 4k pages)
RUN <<EOT
set -e
if [ "${KERNEL_ARCH}" = "arm64" ] && [ "${KERNEL_PAGE_SIZE}" = "16k" ]; then
/usr/src/linux/scripts/config --file /usr/src/linux/.config \
--disable CONFIG_ARM64_4K_PAGES \
--enable CONFIG_ARM64_16K_PAGES \
--disable CONFIG_ARM64_64K_PAGES
HOST_ARCH=$(uname -m)
case "${HOST_ARCH}" in
aarch64) HOST_ARCH=arm64 ;;
esac
CROSS_COMPILE=""
if [ "${HOST_ARCH}" != "${KERNEL_ARCH}" ]; then
case "${KERNEL_ARCH}" in
arm64) CROSS_COMPILE=aarch64-linux-gnu- ;;
x86_64) CROSS_COMPILE=x86_64-linux-gnu- ;;
esac
fi
cd linux && ARCH="${KERNEL_ARCH}" CROSS_COMPILE="${CROSS_COMPILE}" make olddefconfig
fi
EOT
# Build the kernel
# Seperate from base to allow config construction from fragments in the future
FROM kernel-build-base AS kernel-build
# Compile the kernel
RUN <<EOT
set -e
HOST_ARCH=$(uname -m)
# Normalize host arch to match KERNEL_ARCH naming
case "${HOST_ARCH}" in
aarch64) HOST_ARCH=arm64 ;;
esac
CROSS_COMPILE=""
if [ "${HOST_ARCH}" != "${KERNEL_ARCH}" ]; then
case "${KERNEL_ARCH}" in
arm64) CROSS_COMPILE=aarch64-linux-gnu- ;;
x86_64) CROSS_COMPILE=x86_64-linux-gnu- ;;
esac
fi
cd linux && ARCH="${KERNEL_ARCH}" CROSS_COMPILE="${CROSS_COMPILE}" make -j${KERNEL_NPROC:-$(nproc)}
EOT
RUN <<EOT
set -e
cd linux
mkdir /build
case "${KERNEL_ARCH}" in
x86_64) cp vmlinux /build/kernel ;;
arm64) cp arch/arm64/boot/Image /build/kernel ;;
*) echo "Unsupported architecture: ${KERNEL_ARCH} " ; exit 1 ;;
esac
EOT
FROM base AS shim-build
WORKDIR /go/src/github.com/containerd/nerdbox
ARG GO_DEBUG_GCFLAGS
ARG GO_GCFLAGS
ARG GO_BUILD_FLAGS
ARG GO_LDFLAGS
ARG TARGETOS
ARG TARGETARCH
ARG TARGETPLATFORM
ARG GOPROXY
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/root/.cache/go-build,id=shim-build-$TARGETPLATFORM \
GOOS=${TARGETOS} GOPROXY=${GOPROXY} GOARCH=${TARGETARCH} go build ${GO_DEBUG_GCFLAGS} ${GO_GCFLAGS} ${GO_BUILD_FLAGS} -o /build/containerd-shim-nerdbox-v1 ${GO_LDFLAGS} -tags 'no_grpc' ./cmd/containerd-shim-nerdbox-v1
FROM base AS vminit-build
WORKDIR /go/src/github.com/containerd/nerdbox
ARG GO_DEBUG_GCFLAGS
ARG GO_GCFLAGS
ARG GO_BUILD_FLAGS
ARG TARGETPLATFORM
ARG TARGETARCH
ARG GOPROXY
RUN --mount=type=bind,target=.,rw \
--mount=type=cache,target=/root/.cache/go-build,id=vminit-build-$TARGETPLATFORM \
GOARCH=${TARGETARCH} GOPROXY=${GOPROXY} go build ${GO_DEBUG_GCFLAGS} ${GO_GCFLAGS} ${GO_BUILD_FLAGS} -o /build/vminitd -ldflags '-extldflags \"-static\" -s -w' -tags 'osusergo netgo static_build no_grpc' ./cmd/vminitd
# TODO: Use nix instructions to build crun statically
#FROM base AS crun-src
#
#ARG CRUN_VERSION=1.24
#
#WORKDIR /usr/src/crun
#RUN git init . && git remote add origin "https://github.com/containers/crun.git"
#
#RUN git fetch -q --depth 1 origin "${CRUN_VERSION}" +refs/tags/*:refs/tags/* && git checkout -q FETCH_HEAD
#
#FROM base AS crun-build
#WORKDIR /go/src/github.com/containers/crun
#ARG TARGETPLATFORM
#RUN --mount=type=cache,sharing=locked,id=crun-aptlib,target=/var/lib/apt \
# --mount=type=cache,sharing=locked,id=crun-aptcache,target=/var/cache/apt \
# apt-get update && apt-get install -y --no-install-recommends \
# make git gcc build-essential pkgconf libtool \
# libsystemd-dev libprotobuf-c-dev libcap-dev libseccomp-dev libyajl-dev \
# go-md2man autoconf python3 automake
#RUN --mount=from=crun-src,src=/usr/src/crun,rw \
# --mount=type=cache,target=/root/.cache/go-build,id=crun-build-$TARGETPLATFORM <<EOT
# set -e
# ./autogen.sh
# ./configure
# make
# mkdir /build
# mv crun /build/
#EOT
FROM base AS crun-build
WORKDIR /usr/src/crun
ARG TARGETARCH
RUN mkdir /build && wget -O /build/crun https://github.com/containers/crun/releases/download/1.24/crun-1.24-linux-${TARGETARCH}-disable-systemd
FROM base AS initrd-build
WORKDIR /usr/src/init
ARG TARGETPLATFORM
RUN --mount=type=cache,sharing=locked,id=initrd-aptlib,target=/var/lib/apt \
--mount=type=cache,sharing=locked,id=initrd-aptcache,target=/var/cache/apt \
apt-get update && apt-get install -y --no-install-recommends cpio
RUN mkdir sbin proc sys tmp run
COPY --from=vminit-build /build/vminitd ./init
COPY --from=crun-build /build/crun ./sbin/crun
RUN <<EOT
set -e
chmod +x sbin/crun
mkdir /build
(find . -print0 | cpio --null -H newc -o ) | gzip -9 > /build/nerdbox-initrd
EOT
FROM scratch AS kernel
ARG KERNEL_ARCH="x86_64"
COPY --from=kernel-build /build/kernel /nerdbox-kernel-${KERNEL_ARCH}
FROM scratch AS initrd
COPY --from=initrd-build /build/nerdbox-initrd /nerdbox-initrd
FROM scratch AS shim
COPY --from=shim-build /build/containerd-shim-nerdbox-v1 /containerd-shim-nerdbox-v1
FROM "${DOCKER_IMAGE}" AS docker-cli
FROM "${GOLANG_IMAGE}" AS dlv
RUN go install github.com/go-delve/delve/cmd/dlv@latest
FROM "${RUST_IMAGE}" AS libkrun-build
ARG LIBKRUN_VERSION=v1.17.4
RUN --mount=type=cache,sharing=locked,id=libkrun-aptlib,target=/var/lib/apt \
--mount=type=cache,sharing=locked,id=libkrun-aptcache,target=/var/cache/apt \
apt-get update && apt-get install -y git libcap-ng-dev libclang-19-dev llvm make
RUN git clone --depth 1 --branch ${LIBKRUN_VERSION} https://github.com/containers/libkrun.git && \
cd libkrun && \
make -j$(nproc) BLK=1 NET=1
FROM scratch AS libkrun
COPY --from=libkrun-build /libkrun/target/release/libkrun.so /libkrun.so
FROM ${GOLANG_IMAGE} AS dev
ARG CONTAINERD_VERSION=2.1.4
ARG TARGETARCH
ENV PATH=/go/src/github.com/containerd/nerdbox/_output:$PATH
WORKDIR /go/src/github.com/containerd/nerdbox
RUN --mount=type=cache,sharing=locked,id=dev-aptlib,target=/var/lib/apt \
--mount=type=cache,sharing=locked,id=dev-aptcache,target=/var/cache/apt \
apt-get update && apt-get install -y erofs-utils git make wget
RUN wget https://github.com/containerd/containerd/releases/download/v${CONTAINERD_VERSION}/containerd-${CONTAINERD_VERSION}-linux-${TARGETARCH}.tar.gz && \
tar -C /usr/local/bin --strip-components=1 -xf containerd-${CONTAINERD_VERSION}-linux-${TARGETARCH}.tar.gz && \
rm containerd-${CONTAINERD_VERSION}-linux-${TARGETARCH}.tar.gz
COPY --from=docker-cli /usr/local/bin/docker /usr/local/bin/docker
COPY --from=docker-cli /usr/local/libexec/docker/cli-plugins/docker-buildx /usr/local/libexec/docker/cli-plugins/docker-buildx
COPY --from=dlv /go/bin/dlv /usr/local/bin/dlv
COPY --from=libkrun /libkrun.so /usr/local/lib64/libkrun.so
ENV LIBKRUN_PATH=/go/src/github.com/containerd/nerdbox/_output
VOLUME /var/lib/containerd
FROM base AS golangci-build
WORKDIR /src
ARG GOLANGCI_LINT_VERSION
ADD https://github.com/golangci/golangci-lint.git#v${GOLANGCI_LINT_VERSION} .
COPY --link --from=xx / /
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/ \
xx-go --wrap && \
go mod download
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/ \
xx-go --wrap && \
mkdir -p out && \
go build -o /out/golangci-lint ./cmd/golangci-lint
FROM scratch AS golangci-binary-false
FROM scratch AS golangci-binary-true
COPY --from=golangci-build /out/golangci-lint golangci-lint
FROM golangci-binary-${GOLANGCI_FROM_SOURCE} AS golangci-binary
FROM base AS lint-base
ENV GOFLAGS="-buildvcs=false"
RUN <<EOT
apt-get update
apt-get install -y --no-install-recommends gcc libc6-dev yamllint
rm -rf /var/lib/apt/lists/*
EOT
ARG GOLANGCI_LINT_VERSION
ARG GOLANGCI_FROM_SOURCE
COPY --link --from=golangci-binary / /usr/bin/
RUN [ "${GOLANGCI_FROM_SOURCE}" = "true" ] && exit 0; wget -O- -nv https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v${GOLANGCI_LINT_VERSION}
COPY --link --from=xx / /
WORKDIR /go/src/github.com/containerd/nerdbox
FROM lint-base AS golangci-lint
ARG TARGETNAME
ARG TARGETPLATFORM
RUN --mount=target=/go/src/github.com/containerd/nerdbox \
--mount=target=/root/.cache,type=cache,id=lint-cache-${TARGETNAME}-${TARGETPLATFORM} \
xx-go --wrap && \
golangci-lint run -c .golangci.yml && \
touch /golangci-lint.done
FROM lint-base AS golangci-verify-false
RUN --mount=target=/go/src/github.com/containerd/nerdbox \
golangci-lint config verify && \
touch /golangci-verify.done
FROM scratch AS golangci-verify-true
COPY <<EOF /golangci-verify.done
EOF
FROM golangci-verify-${GOLANGCI_FROM_SOURCE} AS golangci-verify
FROM lint-base AS yamllint
RUN --mount=target=/go/src/github.com/containerd/nerdbox \
yamllint -c .yamllint.yml --strict . && \
touch /yamllint.done
FROM scratch AS lint
COPY --link --from=golangci-lint /golangci-lint.done /
COPY --link --from=golangci-verify /golangci-verify.done /
COPY --link --from=yamllint /yamllint.done /