Skip to content

Commit

Permalink
feat(docker): Rewrite Dockerfile and GitHub action.
Browse files Browse the repository at this point in the history
  • Loading branch information
Erk- committed Mar 12, 2024
1 parent cc42534 commit 9bdd31a
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 110 deletions.
67 changes: 28 additions & 39 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,56 +34,45 @@ jobs:
musl-target: aarch64-linux-musl

steps:
# Podman 4.x is necessary here because it supports --platform=$BUILDPLATFORM. Otherwise, podman
# would pull the base image for aarch64 when building for aarch64. See https://github.com/containers/buildah/pull/3757
# for the implementation. GitHub actions currently still ship Podman 3.x, even though 4.x has been
# out for over a year.
# The repository used is the same as GitHub actions uses for their source - just that it's the unstable version
# rather than the stable one.
# TODO: Once podman 4.x is available in actions by default (or in the Ubuntu repositories), remove this.
- name: Install podman 4.x
run: |
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.opensuse.org/repositories/devel:kubic:libcontainers:unstable/xUbuntu_$(lsb_release -rs)/Release.key \
| gpg --dearmor \
| sudo tee /etc/apt/keyrings/devel_kubic_libcontainers_unstable.gpg > /dev/null
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/devel_kubic_libcontainers_unstable.gpg]\
https://download.opensuse.org/repositories/devel:kubic:libcontainers:unstable/xUbuntu_$(lsb_release -rs)/ /" \
| sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:unstable.list > /dev/null
sudo apt -qq -y purge buildah podman
sudo apt -qq -y autoremove --purge
sudo apt update -qq
sudo apt -qq -y install podman

- name: Checkout sources
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Login to ghcr
if: github.ref == 'refs/heads/trunk' && github.event_name != 'pull_request'
run: |
echo "${{ secrets.GITHUB_TOKEN }}" | podman login -u ${{ github.repository_owner }} --password-stdin ghcr.io
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Convert GITHUB_REPOSITORY into lowercase
run: |
echo "REPO=${GITHUB_REPOSITORY,,}" >>${GITHUB_ENV}
- name: Build ${{ matrix.tag }}
run: |
podman build \
--format docker \
--arch ${{ matrix.arch }} \
--build-arg FEATURES=${{ matrix.features }} \
--build-arg RUST_TARGET=${{ matrix.rust-target }} \
--build-arg MUSL_TARGET=${{ matrix.musl-target }} \
-t http-proxy:${{ matrix.tag }} \
.
if: github.ref != 'refs/heads/trunk' || github.event_name == 'pull_request'
uses: docker/build-push-action@v5
with:
push: false
tags: http-proxy:${{ matrix.tag }}
build-args: |
FEATURES=${{ matrix.features }}
RUST_TARGET=${{ matrix.rust-target }}
MUSL_TARGET=${{ matrix.musl-target }}
- name: Push image
- name: Build and push ${{ matrix.tag }}
if: github.ref == 'refs/heads/trunk' && github.event_name != 'pull_request'
run: |
podman tag http-proxy:${{ matrix.tag }} ghcr.io/${REPO}:${{ matrix.tag }}
podman push ghcr.io/${REPO}:${{ matrix.tag }}
uses: docker/build-push-action@v5
with:
push: true
tags: http-proxy:${{ matrix.tag }}
build-args: |
FEATURES=${{ matrix.features }}
RUST_TARGET=${{ matrix.rust-target }}
MUSL_TARGET=${{ matrix.musl-target }}
create-manifest:
name: Create Docker manifests
Expand Down
126 changes: 55 additions & 71 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,88 +5,72 @@ ARG MUSL_TARGET="x86_64-linux-musl"
# The crate features to build this with
ARG FEATURES=""

FROM --platform=$BUILDPLATFORM docker.io/alpine:latest as build
FROM --platform=$BUILDPLATFORM rust:latest AS chef
ARG RUST_TARGET
ARG MUSL_TARGET
ARG FEATURES

RUN apk upgrade && \
apk add curl gcc musl-dev && \
curl -sSf https://sh.rustup.rs | sh -s -- --profile minimal --default-toolchain nightly --component rust-src -y

RUN source $HOME/.cargo/env && \
mkdir -p /app/.cargo && \
if [ "$RUST_TARGET" != $(rustup target list --installed) ]; then \
rustup target add $RUST_TARGET && \
curl -L "https://musl.cc/$MUSL_TARGET-cross.tgz" -o /toolchain.tgz && \
tar xf toolchain.tgz && \
ln -s "/$MUSL_TARGET-cross/bin/$MUSL_TARGET-gcc" "/usr/bin/$MUSL_TARGET-gcc" && \
ln -s "/$MUSL_TARGET-cross/bin/$MUSL_TARGET-ld" "/usr/bin/$MUSL_TARGET-ld" && \
ln -s "/$MUSL_TARGET-cross/bin/$MUSL_TARGET-strip" "/usr/bin/actual-strip" && \
GCC_VERSION=$($MUSL_TARGET-gcc --version | grep gcc | awk '{print $3}') && \
echo -e "\
[build]\n\
rustflags = [\"-L\", \"native=/$MUSL_TARGET-cross/$MUSL_TARGET/lib\", \"-L\", \"native=/$MUSL_TARGET-cross/lib/gcc/$MUSL_TARGET/$GCC_VERSION/\", \"-l\", \"static=gcc\", \"-Z\", \"gcc-ld=lld\"]\n\
[target.$RUST_TARGET]\n\
linker = \"$MUSL_TARGET-gcc\"\n\
[unstable]\n\
build-std = [\"std\", \"panic_abort\"]\n\
" > /app/.cargo/config; \
else \
echo "skipping toolchain as we are native" && \
echo -e "\
[build]\n\
rustflags = [\"-L\", \"native=/usr/lib\"]\n\
[unstable]\n\
build-std = [\"std\", \"panic_abort\"]\n\
" > /app/.cargo/config && \
ln -s /usr/bin/strip /usr/bin/actual-strip; \
fi
RUN <<EOT
set -ex
apt-get update
apt-get install --assume-yes musl-dev clang lld
EOT

RUN rustup target add $RUST_TARGET

RUN cargo install cargo-chef --locked

COPY <<EOF /app/.cargo/config
[env]
CC_aarch64-unknown-linux-musl = "clang -target aarch64-unknown-linux-musl -fuse-ld=lld"
CXX_aarch64-unknown-linux-musl = "clang++ -target aarch64-unknown-linux-musl -fuse-ld=lld"
CC_x86_64-unknown-linux-musl = "clang -target x86_64-unknown-linux-musl -fuse-ld=lld"
CXX_x86_64-unknown-linux-musl = "clang++ -target x86_64-unknown-linux-musl -fuse-ld=lld"

[target.aarch64-unknown-linux-musl]
linker = "clang"
rustflags = ["-C", "link-args=-target aarch64-unknown-linux-musl -fuse-ld=lld"]

[target.x86_64-unknown-linux-musl]
linker = "clang"
rustflags = ["-C", "link-args=-target x86_64-unknown-linux-musl -fuse-ld=lld"]

#[unstable]
#build-std = ["std", "panic_abort"]
EOF

WORKDIR /app

COPY ./Cargo.lock ./Cargo.lock
COPY ./Cargo.toml ./Cargo.toml

# We need a source directory so that it builds the dependencies and an empty
# binary.
RUN mkdir src/
RUN echo 'fn main() {}' > ./src/main.rs
RUN source $HOME/.cargo/env && \
if [ "$FEATURES" == "" ]; then \
cargo build --release \
--target="$RUST_TARGET"; \
else \
cargo build --release \
--target="$RUST_TARGET" --features="$FEATURES"; \
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json

FROM chef AS builder
COPY --from=planner /app/recipe.json recipe.json
RUN <<EOF bash
set -ex
if test "$FEATURES" = ""; then
cargo chef cook --target "$RUST_TARGET" --release --recipe-path recipe.json
else
cargo chef cook --target "$RUST_TARGET" --features="$FEATURES" --release --recipe-path recipe.json
fi
EOF

COPY . .

RUN <<EOF bash
set -ex
if test "$FEATURES" = "" ; then
cargo build --release --target $RUST_TARGET
else
cargo build --release --target $RUST_TARGET --features="$FEATURES"
fi
cp target/$RUST_TARGET/release/twilight-http-proxy /twilight-http-proxy
EOF

# Now, delete the fake source and copy in the actual source. This allows us to
# have a previous compilation step for compiling the dependencies, while being
# able to only copy in and compile the binary itself when something in the
# source changes.
#
# This is very important. If we just copy in the source after copying in the
# Cargo.lock and Cargo.toml, then every time the source changes the dependencies
# would have to be re-downloaded and re-compiled.
#
# Also, remove the artifacts of building the binaries.
RUN rm -f target/$RUST_TARGET/release/deps/twilight_http_proxy*
COPY ./src ./src

RUN source $HOME/.cargo/env && \
if [ "$FEATURES" == "" ]; then \
cargo build --release \
--target="$RUST_TARGET"; \
else \
cargo build --release \
--target="$RUST_TARGET" --features="$FEATURES"; \
fi && \
cp target/$RUST_TARGET/release/twilight-http-proxy /twilight-http-proxy && \
actual-strip /twilight-http-proxy

FROM scratch

COPY --from=build /twilight-http-proxy /twilight-http-proxy
COPY --from=builder /twilight-http-proxy /twilight-http-proxy

CMD ["./twilight-http-proxy"]

0 comments on commit 9bdd31a

Please sign in to comment.