From d1b4aab8ca2ddac57f1d110d5198d9a3c28ed23c Mon Sep 17 00:00:00 2001 From: Brandon Thomas Date: Thu, 8 Feb 2024 02:06:12 -0500 Subject: [PATCH] Add Dockerfile and CI workflow for Bevy headless (#38) --- .github/workflows/docker-publish-cpu.yml | 115 +++++++++++++++++++++++ Dockerfile | 52 ++++++++++ 2 files changed, 167 insertions(+) create mode 100644 .github/workflows/docker-publish-cpu.yml create mode 100644 Dockerfile diff --git a/.github/workflows/docker-publish-cpu.yml b/.github/workflows/docker-publish-cpu.yml new file mode 100644 index 0000000..6bdcc00 --- /dev/null +++ b/.github/workflows/docker-publish-cpu.yml @@ -0,0 +1,115 @@ +# Adapted from +# https://github.com/actions/starter-workflows/ci/docker-publish.yml +# If using base images, don't forget to add READ access, eg. from a package settings page like: +# https://github.com/orgs/storytold/packages/container/docker-base-images-rust-ssl/settings/actions_access +name: "Build GHCR Rust Docker artifact" +on: + push: + branches: + # NB: Default-branch doesn't work, despite Github's documentation. + #- $default-branch + - main +env: + IMAGE_NAME: studio-headless + +jobs: + # Push image to GitHub Packages. + # See also https://docs.docker.com/docker-hub/builds/ + # See also https://depot.dev/blog/docker-layer-caching-in-github-actions + # See also https://evilmartians.com/chronicles/build-images-on-github-actions-with-docker-layer-caching + build-docker-image: + name: "Build Docker Image" + #runs-on: ubuntu-22.04 # runs-on: ubuntu-latest + #runs-on: github-ubuntu-16core # NB: Premium GitHub runner with more cores + runs-on: github-ubuntu-64core # NB: Premium GitHub runner with more cores + if: github.event_name == 'push' + permissions: + packages: write + contents: read + + steps: + - uses: actions/checkout@v3 + + # - uses: docker/setup-buildx-action@v1 + # name: Set up Docker Buildx + + - uses: docker/login-action@v1 + name: Login to GitHub Container Registry + with: + registry: ghcr.io + username: ${{ github.actor }} # username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Calculate short SHA + id: vars + # echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + run: | + echo "sha_short=$(echo ${{ github.sha }} | cut -c1-12)" >> $GITHUB_OUTPUT + + - name: Emit short SHA + run: | + echo "Full SHA: ${{ github.sha }}" + echo "Short SHA: ${{ steps.vars.outputs.sha_short }}" + + #- uses: actions/cache@v2 + # name: Cache Docker layers + # with: + # path: /tmp/.buildx-cache + # key: ${{ runner.os }}-buildx-${{ github.sha }} + # restore-keys: | + # ${{ runner.os }}-buildx- + + # Docs for this action are at https://github.com/marketplace/actions/build-docker-images-using-cache + - uses: whoan/docker-build-with-cache-action@v6 + with: + registry: ghcr.io + username: ${{ github.actor }} # username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + image_name: storytold/storyteller-bevy + dockerfile: Dockerfile + # NB: The `git_push_tag: true` option does not work as expected, so we put the sha in `image_tag`: + # https://github.com/whoan/docker-build-with-cache-action/issues/72 + image_tag: latest,${{ github.sha }},${{ steps.vars.outputs.sha_short }} + # NB: Inject the Git SHA into the container so the servers can emit their own version: + build_extra_args: "--build-arg=GIT_SHA=${{ github.sha }}" + + # - name: Build image + # run: | + # SHORT_SHA=$(echo ${GITHUB_SHA} | cut -c1-12) + # docker build . --file Dockerfile --tag $IMAGE_NAME --label "runnumber=${GITHUB_RUN_ID}" --build-arg GIT_SHA=${SHORT_SHA} + + # - name: Push image to GitHub Container Registry + # run: | + # IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME + + # # Change all uppercase to lowercase + # IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') + + # # Strip git ref prefix from version + # VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') + + # # Strip "v" prefix from tag name + # [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') + + # # Use Docker `latest` tag convention + # [ "$VERSION" == "$default-branch" ] && VERSION=latest + + # echo IMAGE_ID=$IMAGE_ID + # echo VERSION=$VERSION + + # docker tag $IMAGE_NAME $IMAGE_ID:$VERSION + # docker push $IMAGE_ID:$VERSION + + # SHORT_SHA=$(echo ${GITHUB_SHA} | cut -c1-12) + + # docker tag $IMAGE_NAME $IMAGE_ID:$SHORT_SHA + # docker push $IMAGE_ID:$SHORT_SHA + + - name: Cleanup / Debug + # This job will run even on failures to help with debugging. + if: always() + run: | + echo "Report at final github action step:" + echo "Disk usage:" + pwd + du -hsc * | sort -hr diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..3b4f807 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,52 @@ +FROM ubuntu:jammy +# as rust-base + +# NB: This can be "stable" or another version. +ARG RUST_TOOLCHAIN="1.75.0" + +WORKDIR /tmp + +# NB: cmake is required for freetype-sys-0.13.1, which in turn has only been added for egui. +# NB: fontconfig is required by servo-fontconfig-sys, which is in the dependency chain for egui. +# NB: libfontconfig-dev is required by servo-fontconfig-sys, which is in the dependency chain for egui. +# NB: pkg-config and libssl are for container TLS; we may switch to rustls in the future. +# BEVY SPECIFIC - +# NB: libasound2-dev for alsa-sys +# NB: libudev-dev for libudev-sys +RUN apt-get update \ + && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install -y \ + build-essential \ + cmake \ + libasound2-dev \ + libudev-dev \ + curl \ + fontconfig \ + libfontconfig1-dev \ + libssl-dev \ + pkg-config + +# Install Rust +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \ + | sh -s -- --default-toolchain $RUST_TOOLCHAIN -y + +# Report Rust version for build debugging +RUN $HOME/.cargo/bin/rustup show +RUN $HOME/.cargo/bin/rustc --version +RUN $HOME/.cargo/bin/cargo --version + +# Install NPM +# https://nodejs.org/en +# https://github.com/nodesource/distributions +#RUN curl -fsSL https://deb.nodesource.com/setup_21.x | bash - && \ +# apt-get install -y nodejs + +# NB: Now we build and test our code. +COPY Cargo.lock . +COPY Cargo.toml . +COPY ./ . + + +RUN LD_LIBRARY_PATH=/usr/lib:${LD_LIBRARY_PATH} \ + $HOME/.cargo/bin/cargo build \ + --release \ + --bin studio-headless