feat(ci): move rust docker target bash to shell script

This commit is contained in:
alyssa 2024-10-25 03:27:58 +09:00
parent 79f7c973e7
commit 124da02a42
5 changed files with 139 additions and 19 deletions

View file

@ -12,8 +12,8 @@ on:
- 'services/gateway/**' - 'services/gateway/**'
- 'services/avatars/**' - 'services/avatars/**'
- '.github/workflows/rust.yml' - '.github/workflows/rust.yml'
- 'Dockerfile.rust' - 'ci/Dockerfile.rust'
- 'Dockerfile.bin' - 'ci/rust-docker-target.sh'
- 'Cargo.toml' - 'Cargo.toml'
- 'Cargo.lock' - 'Cargo.lock'
@ -40,7 +40,7 @@ jobs:
with: with:
# https://github.com/docker/build-push-action/issues/378 # https://github.com/docker/build-push-action/issues/378
context: . context: .
file: Dockerfile.rust file: ci/Dockerfile.rust
push: false push: false
cache-from: type=registry,ref=ghcr.io/pluralkit/docker-cache:rust cache-from: type=registry,ref=ghcr.io/pluralkit/docker-cache:rust
cache-to: type=registry,ref=ghcr.io/pluralkit/docker-cache:rust,mode=max cache-to: type=registry,ref=ghcr.io/pluralkit/docker-cache:rust,mode=max
@ -48,13 +48,7 @@ jobs:
# add more binaries here # add more binaries here
- run: | - run: |
for binary in "api" "gateway" "avatars"; do tag=${{ github.sha }} \
for tag in latest ${{ env.BRANCH_NAME }} ${{ github.sha }}; do branch=${{ env.BRANCH_NAME }} \
cat Dockerfile.bin | sed "s/__BINARY__/$binary/g" | docker build -t ghcr.io/pluralkit/$binary:$tag -f - . push=$([ "${{ github.repository }}" == "PluralKit/PluralKit" ] && echo true || echo false) \
done ci/rust-docker-target.sh
if [ "${{ github.repository }}" == "PluralKit/PluralKit" ]; then
docker push ghcr.io/pluralkit/$binary:${{ env.BRANCH_NAME }}
docker push ghcr.io/pluralkit/$binary:${{ github.sha }}
[ "${{ env.BRANCH_NAME }}" == "main" ] && docker push ghcr.io/pluralkit/$binary:latest
fi
done

View file

@ -1,5 +0,0 @@
FROM alpine:latest
COPY /.docker-bin/__BINARY__ /bin/__BINARY__
CMD ["/bin/__BINARY__"]

View file

@ -34,8 +34,9 @@ RUN cargo build --bin api --release --target x86_64-unknown-linux-musl
RUN cargo build --bin gateway --release --target x86_64-unknown-linux-musl RUN cargo build --bin gateway --release --target x86_64-unknown-linux-musl
RUN cargo build --bin avatars --release --target x86_64-unknown-linux-musl RUN cargo build --bin avatars --release --target x86_64-unknown-linux-musl
FROM scratch FROM scratch
COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/api /api COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/api /api
COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/gateway /gateway COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/gateway /gateway
COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/avatars /avatars COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/avatars /avatars
COPY --from=binary-builder /build/target/x86_64-unknown-linux-musl/release/avatars /avatars

42
ci/rust-docker-target.sh Executable file
View file

@ -0,0 +1,42 @@
#!/bin/bash
set -e
#tag=
#branch=
#push=
build() {
bin=$1
extra=$2
f=$(mktemp)
cat > $f << EOF
FROM alpine:latest
COPY .docker-bin/$bin /bin/$bin
$extra
CMD ["/bin/$bin"]
EOF
echo "building $dockerfile"
$dockerfile | docker build -t ghcr.io/pluralkit/$bin:$tag -f $f .
rm $f
if [ "$push" == "true" ]; then
docker push ghcr.io/pluralkit/$bin:$tag
docker image tag ghcr.io/pluralkit/$bin:$tag ghcr.io/pluralkit/$bin:$branch
docker push ghcr.io/pluralkit/$bin:$branch
if [ "$branch" == "main" ]; then
docker image tag ghcr.io/pluralkit/$bin:$tag ghcr.io/pluralkit/$bin:latest
docker push ghcr.io/pluralkit/$bin:latest
fi
fi
}
# add rust binaries here to build
build api
build gateway
build avatars

View file

@ -0,0 +1,88 @@
# syntax=docker/dockerfile:1
# Comments are provided throughout this file to help you get started.
# If you need more help, visit the Dockerfile reference guide at
# https://docs.docker.com/go/dockerfile-reference/
ARG RUST_VERSION=1.75.0
ARG APP_NAME=pluralkit-avatars
################################################################################
# xx is a helper for cross-compilation.
# See https://github.com/tonistiigi/xx/ for more information.
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.3.0 AS xx
################################################################################
# Create a stage for building the application.
FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-alpine AS build
ARG APP_NAME
WORKDIR /app
# Copy cross compilation utilities from the xx stage.
COPY --from=xx / /
# Install host build dependencies.
RUN apk add --no-cache clang lld musl-dev git file
# This is the architecture youre building for, which is passed in by the builder.
# Placing it here allows the previous steps to be cached across architectures.
ARG TARGETPLATFORM
# Install cross compilation build dependencies.
RUN xx-apk add --no-cache musl-dev gcc
# Build the application.
# Leverage a cache mount to /usr/local/cargo/registry/
# for downloaded dependencies, a cache mount to /usr/local/cargo/git/db
# for git repository dependencies, and a cache mount to /app/target/ for
# compiled dependencies which will speed up subsequent builds.
# Leverage a bind mount to the src directory to avoid having to copy the
# source code into the container. Once built, copy the executable to an
# output directory before the cache mounted /app/target is unmounted.
# XXX: removed `id` from target mount, see: https://github.com/reproducible-containers/buildkit-cache-dance/issues/12
RUN --mount=type=bind,source=src,target=src \
--mount=type=bind,source=Cargo.toml,target=Cargo.toml \
--mount=type=bind,source=Cargo.lock,target=Cargo.lock \
--mount=type=cache,target=/app/target/$TARGETPLATFORM/ \
--mount=type=cache,target=/usr/local/cargo/git/db \
--mount=type=cache,target=/usr/local/cargo/registry/ \
<<EOF
set -e
xx-cargo build --locked --release --target-dir ./target/$TARGETPLATFORM/
cp ./target/$TARGETPLATFORM/$(xx-cargo --print-target-triple)/release/$APP_NAME /bin/server
xx-verify /bin/server
EOF
################################################################################
# Create a new stage for running the application that contains the minimal
# runtime dependencies for the application. This often uses a different base
# image from the build stage where the necessary files are copied from the build
# stage.
#
# The example below uses the alpine image as the foundation for running the app.
# By specifying the "3.18" tag, it will use version 3.18 of alpine. If
# reproducability is important, consider using a digest
# (e.g., alpine@sha256:664888ac9cfd28068e062c991ebcff4b4c7307dc8dd4df9e728bedde5c449d91).
FROM alpine:3.18 AS final
# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/go/dockerfile-user-best-practices/
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
USER appuser
# Copy the executable from the "build" stage.
COPY --from=build /bin/server /bin/
# Expose the port that the application listens on.
EXPOSE 3000
# What the container should run when it is started.
CMD ["/bin/server"]