Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New dockerfile #77

Open
wants to merge 13 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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\
Erk- marked this conversation as resolved.
Show resolved Hide resolved
[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
Erk- marked this conversation as resolved.
Show resolved Hide resolved
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
Erk- marked this conversation as resolved.
Show resolved Hide resolved
[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"]
Erk- marked this conversation as resolved.
Show resolved Hide resolved
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"]
Loading