-
-
Notifications
You must be signed in to change notification settings - Fork 270
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Split linux build into debian & alpine
- Loading branch information
Showing
5 changed files
with
426 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// Ignore everything | ||
* | ||
|
||
// Allow what is needed | ||
!crates | ||
!tests | ||
!resources/docker/entrypoint.sh | ||
|
||
!Cargo.lock | ||
!Cargo.toml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,30 +37,28 @@ jobs: | |
fail-fast: false | ||
matrix: | ||
include: | ||
- target: x86_64-unknown-linux-gnu | ||
- target: x86_64-unknown-linux-musl | ||
- target: aarch64-unknown-linux-gnu | ||
build_env: "JEMALLOC_SYS_WITH_LG_PAGE=16" | ||
- target: aarch64-unknown-linux-musl | ||
build_env: "JEMALLOC_SYS_WITH_LG_PAGE=16" | ||
- target: armv7-unknown-linux-gnueabihf | ||
build_env: "JEMALLOC_SYS_WITH_LG_PAGE=16" | ||
- target: armv7-unknown-linux-musleabihf | ||
build_env: "JEMALLOC_SYS_WITH_LG_PAGE=16" | ||
- target: arm-unknown-linux-gnueabihf | ||
- target: arm-unknown-linux-musleabihf | ||
- variant: debian | ||
- variant: alpine | ||
|
||
name: Build / ${{matrix.target}} | ||
name: Build / ${{matrix.variant}} | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set up QEMU | ||
uses: docker/setup-qemu-action@v3 | ||
with: | ||
platforms: "arm64,arm" | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v3 | ||
with: | ||
# buildkitd-config-inline: | | ||
# [worker.oci] | ||
# max-parallelism = 2 | ||
driver-opts: | | ||
network=host | ||
- name: Log In to GitHub Container Registry | ||
uses: docker/login-action@v3 | ||
|
@@ -82,26 +80,21 @@ jobs: | |
path: | | ||
var-cache-apt | ||
var-lib-apt | ||
key: docker-apt-cache-${{ hashFiles('Dockerfile.build') }} | ||
key: apt-cache-${{ hashFiles('Dockerfile.debian') }}-${{ hashFiles('Dockerfile.alpine') }} | ||
|
||
- name: Calculate shasum of external deps | ||
id: cal-dep-shasum | ||
run: | | ||
echo "checksum=$(yq -p toml -oy '.package[] | select((.source | contains("")) or (.checksum | contains("")))' Cargo.lock | sha256sum | awk '{print $1}')" >> "$GITHUB_OUTPUT" | ||
- name: Get latest zig version | ||
id: zig-version | ||
run: | | ||
echo "zig_version=$(curl -s "https://api.github.com/repos/ziglang/zig/releases/latest" | jq -r '.tag_name')" >> "$GITHUB_OUTPUT" | ||
- name: Cache Cargo | ||
uses: actions/cache@v4 | ||
id: cargo-cache | ||
with: | ||
path: | | ||
usr-local-cargo-registry | ||
usr-local-cargo-git | ||
key: docker-cargo-cache-${{ steps.cal-dep-shasum.outputs.checksum }} | ||
key: cargo-cache-${{ steps.cal-dep-shasum.outputs.checksum }} | ||
|
||
- name: Inject cache into docker | ||
uses: reproducible-containers/[email protected] | ||
|
@@ -123,7 +116,7 @@ jobs: | |
${{github.repository}} | ||
ghcr.io/${{github.repository}} | ||
flavor: | | ||
suffix=${{ endsWith(matrix.target, 'musl') && '-alpine' || '' }},onlatest=true | ||
suffix=${{ endsWith(matrix.variant, 'alpine') && '-alpine' || '' }},onlatest=true | ||
tags: | | ||
type=ref,event=tag | ||
type=edge,branch=main | ||
|
@@ -133,44 +126,104 @@ jobs: | |
id: build | ||
uses: docker/bake-action@v6 | ||
env: | ||
TARGET: ${{matrix.target}} | ||
DOCKER_BUILD_RECORD_UPLOAD: false | ||
ARTIFACT_REPO: ghcr.io/${{github.repository}} | ||
BUILD_ENV: ${{matrix.build_env}} | ||
ZIG_VERSION: ${{ steps.zig-version.outputs.zig_version }} | ||
DOCKER_PLATFORM: ${{ startsWith(matrix.target, 'x86') && 'amd64' || 'arm64' }} | ||
with: | ||
source: . | ||
provenance: false | ||
files: | | ||
docker-bake.hcl | ||
bake.hcl | ||
${{ steps.meta.outputs.bake-file }} | ||
targets: ${{(github.event_name == 'push' || inputs.Docker) && (startsWith(matrix.target, 'x86') || startsWith(matrix.target, 'aarch64')) && 'build,image' || 'build'}} | ||
targets: ${{ (github.event_name == 'push' || inputs.Docker) && format('build-{0},image-{0}', matrix.variant) || format('build-{0}', matrix.variant) }} | ||
|
||
- name: Upload Artifacts | ||
- name: Generate target mappings | ||
id: map-targets | ||
run: | | ||
cd ${{ matrix.variant }} | ||
declare -A TRIPLET_MAP | ||
if [ "${{ matrix.variant }}" = "debian" ]; then | ||
TRIPLET_MAP=( | ||
["linux_amd64"]="x86_64-unknown-linux-gnu" | ||
["linux_arm64"]="aarch64-unknown-linux-gnu" | ||
["linux_arm_v7"]="armv7-unknown-linux-gnueabihf" | ||
["linux_arm_v6"]="arm-unknown-linux-gnueabihf" | ||
) | ||
else | ||
TRIPLET_MAP=( | ||
["linux_amd64"]="x86_64-unknown-linux-musl" | ||
["linux_arm64"]="aarch64-unknown-linux-musl" | ||
["linux_arm_v7"]="armv7-unknown-linux-musleabihf" | ||
["linux_arm_v6"]="arm-unknown-linux-musleabihf" | ||
) | ||
fi | ||
targets=() | ||
for dir in linux_*; do | ||
if [ -d "$dir" ]; then | ||
if [ -n "${TRIPLET_MAP[$dir]}" ]; then | ||
targets+=("{\"folder\":\"$dir\",\"triplet\":\"${TRIPLET_MAP[$dir]}\"}") | ||
else | ||
echo "Warning: Unknown directory format: $dir" | ||
fi | ||
fi | ||
done | ||
json="[" | ||
json+=$(IFS=,; echo "${targets[*]}") | ||
json+="]" | ||
echo "target_mappings=$json" >> $GITHUB_OUTPUT | ||
echo "Generated mappings:" | ||
echo "$json" | ||
# Upload for x86_64 | ||
- name: Upload x86_64 artifact | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: ${{matrix.target}} | ||
path: | | ||
artifact | ||
!artifact/*.json | ||
name: ${{ fromJson(steps.map-targets.outputs.target_mappings)[0].triplet }} | ||
path: ${{ matrix.variant }}/${{ fromJson(steps.map-targets.outputs.target_mappings)[0].folder }} | ||
|
||
# Upload for aarch64 | ||
- name: Upload aarch64 artifact | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: ${{ fromJson(steps.map-targets.outputs.target_mappings)[1].triplet }} | ||
path: ${{ matrix.variant }}/${{ fromJson(steps.map-targets.outputs.target_mappings)[1].folder }} | ||
|
||
# Upload for armv7 | ||
- name: Upload armv7 artifact | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: ${{ fromJson(steps.map-targets.outputs.target_mappings)[2].triplet }} | ||
path: ${{ matrix.variant }}/${{ fromJson(steps.map-targets.outputs.target_mappings)[2].folder }} | ||
|
||
# Upload for arm | ||
- name: Upload arm artifact | ||
uses: actions/upload-artifact@v4 | ||
with: | ||
name: ${{ fromJson(steps.map-targets.outputs.target_mappings)[3].triplet }} | ||
path: ${{ matrix.variant }}/${{ fromJson(steps.map-targets.outputs.target_mappings)[3].folder }} | ||
|
||
- name: Get image digest | ||
id: image-digest | ||
if: (github.event_name == 'push' || inputs.Docker) && (startsWith(matrix.target, 'x86') || startsWith(matrix.target, 'aarch64')) | ||
if: github.event_name == 'push' || inputs.Docker | ||
run: | | ||
echo "image_digest=$(echo '${{ steps.build.outputs.metadata }}' | jq -r '.image.["containerimage.digest"]')" >> "$GITHUB_OUTPUT" | ||
echo "image_digest=$(echo '${{ steps.build.outputs.metadata }}' | jq -r '.image-${{matrix.variant}}.["containerimage.digest"]')" >> "$GITHUB_OUTPUT" | ||
- name: Attest Dockerhub | ||
uses: actions/attest-build-provenance@v2 | ||
if: (github.event_name == 'push' || inputs.Docker) && (startsWith(matrix.target, 'x86') || startsWith(matrix.target, 'aarch64')) | ||
if: github.event_name == 'push' || inputs.Docker | ||
with: | ||
subject-name: index.docker.io/${{github.repository}} | ||
subject-digest: ${{ steps.image-digest.outputs.image_digest }} | ||
push-to-registry: true | ||
|
||
- name: Attest GHCR | ||
uses: actions/attest-build-provenance@v2 | ||
if: (github.event_name == 'push' || inputs.Docker) && (startsWith(matrix.target, 'x86') || startsWith(matrix.target, 'aarch64')) | ||
if: github.event_name == 'push' || inputs.Docker | ||
with: | ||
subject-name: ghcr.io/${{github.repository}} | ||
subject-digest: ${{ steps.image-digest.outputs.image_digest }} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
# syntax=docker/dockerfile:1 | ||
# check=skip=FromPlatformFlagConstDisallowed,RedundantTargetPlatform | ||
|
||
# ***************** | ||
# Base image for planner & builder | ||
# ***************** | ||
FROM --platform=$BUILDPLATFORM docker.io/library/rust:slim-bookworm AS base | ||
|
||
ENV DEBIAN_FRONTEND="noninteractive" \ | ||
RUSTC_WRAPPER="sccache" \ | ||
BINSTALL_DISABLE_TELEMETRY=true \ | ||
SCCACHE_GHA_ENABLED=true \ | ||
CARGO_TERM_COLOR=always \ | ||
LANG=C.UTF-8 \ | ||
TZ=UTC \ | ||
TERM=xterm-256color | ||
# With zig, we only need libclang and make | ||
RUN \ | ||
--mount=type=cache,target=/var/cache/apt,sharing=locked \ | ||
--mount=type=cache,target=/var/lib/apt,sharing=locked \ | ||
rm -f /etc/apt/apt.conf.d/docker-clean && \ | ||
echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' >/etc/apt/apt.conf.d/keep-cache && \ | ||
apt-get update && \ | ||
apt-get install -yq --no-install-recommends curl xz-utils make jq libclang-16-dev | ||
# Install zig | ||
RUN ZIG_VERSION=$(curl --retry 5 -sL "https://api.github.com/repos/ziglang/zig/releases/latest" | jq -r '.tag_name') && \ | ||
[ ! -z "$ZIG_VERSION" ] && \ | ||
curl --retry 5 -Ls "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 cargo-binstall | ||
RUN curl --retry 5 -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash | ||
# Install cargo-chef & sccache & cargo-zigbuild | ||
RUN cargo binstall --no-confirm cargo-chef sccache cargo-zigbuild | ||
|
||
# ***************** | ||
# Planner | ||
# ***************** | ||
FROM base AS planner | ||
WORKDIR /app | ||
COPY . . | ||
# Generate recipe file | ||
RUN cargo chef prepare --recipe-path recipe.json | ||
|
||
# ***************** | ||
# Builder | ||
# ***************** | ||
FROM base AS builder | ||
WORKDIR /app | ||
COPY --from=planner /app/recipe.json recipe.json | ||
ARG TARGETPLATFORM | ||
SHELL ["/bin/bash", "-o", "pipefail", "-c"] | ||
# Generate musl build env | ||
RUN case "$TARGETPLATFORM" in \ | ||
"linux/amd64") \ | ||
echo "export CARGO_TARGET=x86_64-unknown-linux-musl" >> /build-env \ | ||
;; \ | ||
"linux/arm64") \ | ||
echo "export CARGO_TARGET=aarch64-unknown-linux-musl" >> /build-env \ | ||
echo "export JEMALLOC_SYS_WITH_LG_PAGE=16" >> /build-env \ | ||
;; \ | ||
"linux/arm/v7") \ | ||
echo "export CARGO_TARGET=armv7-unknown-linux-musleabihf" >> /build-env \ | ||
echo "export JEMALLOC_SYS_WITH_LG_PAGE=16" >> /build-env \ | ||
;; \ | ||
"linux/arm/v6") \ | ||
echo "export CARGO_TARGET=arm-unknown-linux-musleabihf" >> /build-env \ | ||
;; \ | ||
*) \ | ||
echo "Error: Unsupported platform $TARGETPLATFORM" && exit 1 \ | ||
;; \ | ||
esac && \ | ||
cat /build-env | ||
RUN source /build-env && \ | ||
rustup target add "${CARGO_TARGET}" && \ | ||
mkdir -p artifact | ||
# Cargo-chef Cache Layer - 1 | ||
RUN --mount=type=secret,id=ACTIONS_CACHE_URL,env=ACTIONS_CACHE_URL \ | ||
--mount=type=secret,id=ACTIONS_RUNTIME_TOKEN,env=ACTIONS_RUNTIME_TOKEN \ | ||
--mount=type=cache,target=/usr/local/cargo/registry \ | ||
--mount=type=cache,target=/usr/local/cargo/git \ | ||
source /build-env && \ | ||
cargo chef cook --recipe-path recipe.json --zigbuild --release --target "${CARGO_TARGET}" -p mail-server -p stalwart-cli | ||
# Copy the source code | ||
COPY . . | ||
# Build generic version | ||
RUN --mount=type=secret,id=ACTIONS_CACHE_URL,env=ACTIONS_CACHE_URL \ | ||
--mount=type=secret,id=ACTIONS_RUNTIME_TOKEN,env=ACTIONS_RUNTIME_TOKEN \ | ||
--mount=type=cache,target=/usr/local/cargo/registry \ | ||
--mount=type=cache,target=/usr/local/cargo/git \ | ||
source /build-env && \ | ||
cargo zigbuild --release --target ${CARGO_TARGET} -p mail-server -p stalwart-cli && \ | ||
mv /app/target/${CARGO_TARGET}/release/stalwart-mail /app/artifact/stalwart-mail && \ | ||
mv /app/target/${CARGO_TARGET}/release/stalwart-cli /app/artifact/stalwart-cli | ||
|
||
# ***************** | ||
# Binary stage | ||
# ***************** | ||
FROM scratch AS binaries | ||
COPY --from=builder /app/artifact / | ||
|
||
# ***************** | ||
# Runtime image for musl targets | ||
# ***************** | ||
FROM --platform=$TARGETPLATFORM alpine AS runtime | ||
WORKDIR /opt/stalwart-mail | ||
RUN apk add --update --no-cache ca-certificates tzdata && rm -rf /var/cache/apk/* | ||
COPY --from=binaries /stalwart-mail /usr/local/bin | ||
COPY --from=binaries /stalwart-cli /usr/local/bin | ||
COPY ./resources/docker/entrypoint.sh /usr/local/bin/entrypoint.sh | ||
RUN chmod -R 755 /usr/local/bin | ||
CMD ["/usr/local/bin/stalwart-mail"] | ||
VOLUME [ "/opt/stalwart-mail" ] | ||
EXPOSE 443 25 110 587 465 143 993 995 4190 8080 | ||
ENTRYPOINT ["/bin/sh", "/usr/local/bin/entrypoint.sh"] | ||
# FIXME 需要将所有的export输入到一个文本然后在需要的地方source | ||
# 修改glare 用jq | ||
# 需要分别有两个dockerfile docker 脚本解析 TARGETPLATFORM 来生成 rust-target | ||
# 修改upload-artifact * 3,在其之前添加解析name的action脚本 |
Oops, something went wrong.