diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 7a5e6471..67b06bd3 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -20,47 +20,52 @@ on: - "Dockerfile" workflow_dispatch: +permissions: + contents: read + packages: write + jobs: base: runs-on: ubuntu-latest - name: Build base image (amd64) + name: Build base image steps: # Configure build environment - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 # Authenticate with GHCR - name: Login to Github Container Registry - uses: docker/login-action@v1 + if: ${{ github.event_name != 'pull_request' }} + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - # Build all projects and cache - - name: Build Base Image - uses: docker/build-push-action@v3 + - name: Build base image + uses: docker/build-push-action@v4 with: context: . - push: true - tags: ghcr.io/revoltchat/base:latest - cache-from: type=gha - cache-to: type=gha,mode=max + push: ${{ github.event_name != 'pull_request' }} + platforms: linux/amd64,linux/arm64 + tags: ghcr.io/${{ github.repository_owner }}/base:latest + cache-from: type=gha,scope=buildx-base-multi-arch + cache-to: type=gha,scope=buildx-base-multi-arch,mode=max - publish_amd64: + publish: needs: [base] runs-on: ubuntu-latest if: github.event_name != 'pull_request' strategy: matrix: project: [delta, bonfire] - name: Build ${{ matrix.project }} image (amd64) + name: Build ${{ matrix.project }} image steps: # Configure build environment - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 @@ -68,10 +73,11 @@ jobs: - name: Login to DockerHub uses: docker/login-action@v2 with: + registry: docker.io username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Login to Github Container Registry - uses: docker/login-action@v1 + uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.actor }} @@ -86,11 +92,11 @@ jobs: { "delta": { "path": "crates/delta", - "tag": "revoltchat/server" + "tag": "${{ github.repository_owner }}/server" }, "bonfire": { "path": "crates/bonfire", - "tag": "revoltchat/bonfire" + "tag": "${{ github.repository_owner }}/bonfire" } } export_to: output @@ -98,19 +104,21 @@ jobs: # Configure metadata - name: Docker meta id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v4 with: - images: ${{ steps.export.outputs.tag }}, ghcr.io/${{ steps.export.outputs.tag }} + images: | + docker.io/${{ steps.export.outputs.tag }} + ghcr.io/${{ steps.export.outputs.tag }} # Build crate image - name: Publish - uses: docker/build-push-action@v3 + uses: docker/build-push-action@v4 with: context: . push: true - platforms: linux/amd64 + platforms: linux/amd64,linux/arm64 file: ${{ steps.export.outputs.path }}/Dockerfile tags: ${{ steps.meta.outputs.tags }} + build-args: | + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha - cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile index 877ed09e..748757cb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,27 @@ # Build Stage -FROM rustlang/rust:nightly-slim AS builder +FROM --platform="${BUILDPLATFORM}" rustlang/rust:nightly-slim USER 0:0 WORKDIR /home/rust/src -# Install build requirements -RUN apt-get update && apt-get install -y libssl-dev pkg-config +ARG TARGETARCH -# Build all crates +# Install build requirements +RUN dpkg --add-architecture "${TARGETARCH}" +RUN apt-get update && \ + apt-get install -y \ + make \ + pkg-config \ + libssl-dev:"${TARGETARCH}" +COPY scripts/build-image-layer.sh /tmp/ +RUN sh /tmp/build-image-layer.sh tools + +# Build all dependencies COPY Cargo.toml Cargo.lock ./ +COPY crates/bonfire/Cargo.toml ./crates/bonfire/ +COPY crates/delta/Cargo.toml ./crates/delta/ +COPY crates/quark/Cargo.toml ./crates/quark/ +RUN sh /tmp/build-image-layer.sh deps + +# Build all apps COPY crates ./crates -RUN cargo build --locked --release +RUN sh /tmp/build-image-layer.sh apps diff --git a/crates/bonfire/Dockerfile b/crates/bonfire/Dockerfile index e0b41afd..272ed03d 100644 --- a/crates/bonfire/Dockerfile +++ b/crates/bonfire/Dockerfile @@ -1,10 +1,11 @@ # Build Stage FROM ghcr.io/revoltchat/base:latest AS builder -RUN cargo install --locked --path crates/bonfire # Bundle Stage FROM debian:buster-slim -RUN apt-get update && apt-get install -y ca-certificates -COPY --from=builder /usr/local/cargo/bin/revolt-bonfire ./ +RUN apt-get update && \ + apt-get install -y ca-certificates && \ + apt-get clean +COPY --from=builder /home/rust/src/target/release/revolt-bonfire ./ EXPOSE 9000 CMD ["./revolt-bonfire"] diff --git a/crates/delta/Dockerfile b/crates/delta/Dockerfile index f02812b4..78489315 100644 --- a/crates/delta/Dockerfile +++ b/crates/delta/Dockerfile @@ -1,11 +1,12 @@ # Build Stage FROM ghcr.io/revoltchat/base:latest AS builder -RUN cargo install --locked --path crates/delta # Bundle Stage FROM debian:buster-slim -RUN apt-get update && apt-get install -y ca-certificates -COPY --from=builder /usr/local/cargo/bin/revolt-delta ./ +RUN apt-get update && \ + apt-get install -y ca-certificates && \ + apt-get clean +COPY --from=builder /home/rust/src/target/release/revolt-delta ./ EXPOSE 8000 ENV ROCKET_ADDRESS 0.0.0.0 diff --git a/scripts/build-image-layer.sh b/scripts/build-image-layer.sh new file mode 100644 index 00000000..69fca820 --- /dev/null +++ b/scripts/build-image-layer.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +set -eu + +case "${TARGETARCH}" in + "amd64") + LINKER_NAME="x86_64-linux-gnu-gcc" + LINKER_PACKAGE="gcc-x86-64-linux-gnu" + BUILD_TARGET="x86_64-unknown-linux-gnu" ;; + "arm64") + LINKER_NAME="aarch64-linux-gnu-gcc" + LINKER_PACKAGE="gcc-aarch64-linux-gnu" + BUILD_TARGET="aarch64-unknown-linux-gnu" ;; +esac + +tools() { + apt-get install -y "${LINKER_PACKAGE}" + rustup target add "${BUILD_TARGET}" +} + +deps() { + mkdir -p \ + crates/bonfire/src \ + crates/delta/src \ + crates/quark/src + echo 'fn main() { panic!("stub"); }' | + tee crates/bonfire/src/main.rs | + tee crates/delta/src/main.rs + echo '' | + tee crates/quark/src/lib.rs + cargo build --locked --release --target "${BUILD_TARGET}" +} + +apps() { + touch -am \ + crates/bonfire/src/main.rs \ + crates/delta/src/main.rs \ + crates/quark/src/lib.rs + cargo build --locked --release --target "${BUILD_TARGET}" + mv target _target && mv _target/"${BUILD_TARGET}" target +} + +export RUSTFLAGS="-C linker=${LINKER_NAME}" +export PKG_CONFIG_ALLOW_CROSS="1" +export PKG_CONFIG_PATH="/usr/lib/pkgconfig:/usr/lib/aarch64-linux-gnu/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig" + +"$@"