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

Build multi-architecture images #197

Merged
merged 27 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5e851b4
trial staged build with github actions tooling
4141done Jan 9, 2024
c9b9a33
fix some yaml issues
4141done Jan 9, 2024
5f531ed
debug image state after loading base image in unprivileged build
4141done Jan 9, 2024
0d84f4f
adjust debug prints
4141done Jan 9, 2024
391f08d
move to a registry strategy to share base images due to buildx
4141done Jan 9, 2024
9944209
attempt a different build strategy to share base image
4141done Jan 10, 2024
4cc8a93
try building the base image, pushing, and saving
4141done Jan 10, 2024
6d1b798
wait for build to run before we start testing
4141done Jan 10, 2024
d0b303e
fix file path for oss image upload
4141done Jan 10, 2024
205fc95
add all tests
4141done Jan 10, 2024
e086211
correct image name in later tests
4141done Jan 10, 2024
1e32e13
add platforms to all build config
4141done Jan 10, 2024
4a022b2
redo build for base image, try the oci exporter
4141done Jan 10, 2024
793640f
simplify to just build for test initial stages
4141done Jan 10, 2024
c296ad5
add unprivileged
4141done Jan 10, 2024
c5aa0c0
add push job
4141done Jan 11, 2024
d79d4bd
fix bad comments
4141done Jan 11, 2024
fc657e7
fix missing date
4141done Jan 11, 2024
62813ca
get interpolation right in docker tag
4141done Jan 11, 2024
2569856
try moving to github.repository
4141done Jan 11, 2024
452d23b
clean up test script
4141done Jan 11, 2024
15fb908
remove syntax error
4141done Jan 11, 2024
fc4dd27
remove branch restrictions on test jobs. They should run always
4141done Jan 11, 2024
590c3e4
ensure runner version, set explicit artifact retention period
4141done Jan 12, 2024
8182945
fix temp dir
4141done Jan 12, 2024
fa22c86
try using the runner temp for file upload and download
4141done Jan 12, 2024
bb364c0
use the temp variable all the places
4141done Jan 12, 2024
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
327 changes: 233 additions & 94 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,52 @@ on:
pull_request:
branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel

env:
CI: true
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

annotation: This is temporary until we get the whole test suite refactored. For now we skip the image build step in the test script since this pipeline ensures that the correct images are available.



# Job progression. We make sure that the base image [oss] builds and passes tests before kicking off the other builds

# ┌──────────────────┐ ┌────────────────┐ ┌────────────────┐
# ┌─────────┐ ┌─────────┬────► Build Latest NJS ├────────►Test Latest NJS ├─────►│Push Latest NJS │
# │Build OSS├────►│Test OSS │ └──────────────────┘ └────────────────┘ └────────────────┘
# └─────────┘ └──┬──────┤
# │ │ ┌──────────────────┐ ┌──────────────────┐ ┌─────────────────┐
# │ └────►Build Unprivileged├───────►Test Unprivileged ├────►│Push Unprivileged│
# │ └──────────────────┘ └──────────────────┘ ├────────┬────────┘
# │ ├────────┤
# └──────────────────────────────────────────────────────────────►│Push OSS│
# └────────┘

# As a last step, if we are on the main/master branch, multi-architecture images will be built and pushed to github packages
# and docker hub

jobs:
build:
build-oss-for-test:
runs-on: ubuntu-latest

if: github.ref != 'refs/heads/master'
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and export
uses: docker/build-push-action@v5
with:
file: Dockerfile.oss
context: .
tags: nginx-s3-gateway , nginx-s3-gateway:oss
outputs: type=docker,dest=/tmp/oss.tar
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: oss
path: /tmp/oss.tar
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

annotation: The other two images use this as a base. Therefore we export the built image for use in:

  • The tests for this image
  • The build process for the latest-njs and unprivileged images


test-oss:
runs-on: ubuntu-latest
needs: build-oss-for-test
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt-get update -qq && sudo apt-get install -y curl wait-for-it
- name: Restore cached binaries
Expand All @@ -34,35 +70,58 @@ jobs:
curl --insecure --retry 6 --fail --silent --location "https://dl.min.io/client/mc/release/linux-$(dpkg --print-architecture)/archive/mc.RELEASE.2023-06-19T19-31-19Z.sha256sum" | sha256sum --check -
mv mc.RELEASE.2023-06-19T19-31-19Z mc
chmod +x mc
- name: Save cached binaries
id: cache-binaries-save
uses: actions/cache/save@v3

- name: Download artifact
uses: actions/download-artifact@v3
with:
path: .bin
key: ${{ steps.cache-binaries-restore.outputs.cache-primary-key }}
- name: Run tests - latest njs version
run: ./test.sh --latest-njs --type oss
name: oss
path: /tmp
- name: Load image
run: |
docker load --input /tmp/oss.tar
- name: Run tests - stable njs version
run: ./test.sh --type oss
- name: Run tests - stable njs version - unprivileged process
run: ./test.sh --unprivileged --type oss
- name: Run tests - latest njs version - unprivileged process
run: ./test.sh --latest-njs --unprivileged --type oss

build_and_deploy:
build-latest-njs-for-test:
runs-on: ubuntu-latest

if: github.ref == 'refs/heads/master'
needs: test-oss
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2

- name: Get current date
id: date
run: echo "date=$(date +'%Y%m%d')" >> $GITHUB_OUTPUT
- name: Configure Github Package Registry
run: echo ${{ secrets.GITHUB_TOKEN }} | docker login docker.pkg.github.com -u $GITHUB_ACTOR --password-stdin
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: oss
path: /tmp
- name: Load image
run: |
docker load --input /tmp/oss.tar
- name: Build and load oss image
uses: docker/build-push-action@v5
with:
file: Dockerfile.latest-njs
context: .
tags: nginx-s3-gateway:latest-njs-oss
load: true
# Save manually here since we need to use the `docker` buildx `driver` but that can't output
# a file that upload-artifact likes.
- name: save image
run: |
docker save nginx-s3-gateway:latest-njs-oss > /tmp/latest-njs.tar
- name: Upload artifact - latest-njs
uses: actions/upload-artifact@v3
with:
name: latest-njs
path: /tmp/latest-njs.tar

test-latest-njs:
runs-on: ubuntu-latest
needs: build-latest-njs-for-test
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt-get update -qq && sudo apt-get install -y curl wait-for-it
- name: Restore cached binaries
Expand All @@ -75,79 +134,159 @@ jobs:
run: |
mkdir .bin || exit 0
cd .bin
curl --insecure --retry 6 --fail --silent --location --output mc.RELEASE.2023-06-19T19-31-19Z "https://dl.min.io/client/mc/release/linux-$(dpkg --print-architecture)/archive/mc.RELEASE.2023-06-19T19-31-19Z"
curl --insecure --retry 6 --fail --location --output mc.RELEASE.2023-06-19T19-31-19Z "https://dl.min.io/client/mc/release/linux-$(dpkg --print-architecture)/archive/mc.RELEASE.2023-06-19T19-31-19Z"
curl --insecure --retry 6 --fail --silent --location "https://dl.min.io/client/mc/release/linux-$(dpkg --print-architecture)/archive/mc.RELEASE.2023-06-19T19-31-19Z.sha256sum" | sha256sum --check -
mv mc.RELEASE.2023-06-19T19-31-19Z mc
chmod +x mc

# Run tests and builds image
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: latest-njs
path: /tmp
- name: Load image
run: |
docker load --input /tmp/latest-njs.tar
docker tag nginx-s3-gateway:latest-njs-oss nginx-s3-gateway
- name: Run tests - latest njs version
run: ./test.sh --latest-njs --type oss
# latest-njs-oss image push [Github]
- name: Tag container image for Push to github [latest-njs-oss date]
run: docker tag nginx-s3-gateway:latest-njs-oss docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:latest-njs-oss-${{ steps.date.outputs.date }}
- name: Tag container image for Push to github [latest-njs-oss]
run: docker tag nginx-s3-gateway:latest-njs-oss docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:latest-njs-oss
- name: Push container image to github [latest-njs-oss date]
run: docker push docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:latest-njs-oss-${{ steps.date.outputs.date }}
- name: Push container image to github [latest-njs-oss]
run: docker push docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:latest-njs-oss

# Run tests and builds image
- name: Run tests - stable njs version - unprivileged process

build-unprivileged-for-test:
runs-on: ubuntu-latest
needs: test-oss
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver: docker
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

annotation:
If we use the docker-container driver that buildx uses by default, a docker load does not get the image in a context where the build process can access it. In order to do this you must use a local registry as detailed in this guide: https://docs.docker.com/build/ci/github-actions/named-contexts/#using-with-a-container-builder

- name: Download artifact
uses: actions/download-artifact@v3
with:
name: oss
path: /tmp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would check to see if github actions has defined an environment variable for the temp path. Generally, it isn't great to assume that /tmp is the system temp directory. Yes, I know it is in this case and this is a nit.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this note. I discovered ${{ runner.temp }} which serves the purpose well.

- name: Load image
run: |
docker load --input /tmp/oss.tar
- name: Build and load oss image
uses: docker/build-push-action@v5
with:
file: Dockerfile.unprivileged
context: .
tags: nginx-s3-gateway:unprivileged-oss
load: true
# Save manually here since we need to use the `docker` buildx `driver` but that can't output
# a file that upload-artifact likes.
- name: save image
run: |
docker save nginx-s3-gateway:unprivileged-oss > /tmp/unprivileged.tar
- name: Upload artifact - unprivileged
uses: actions/upload-artifact@v3
with:
name: unprivileged
path: /tmp/unprivileged.tar
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refresh my memory if the uploaded artifacts eventually get cleaned up. I have a vague memory that they do.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a default setting for the repo which I believe is 30 days. However based on this comment I'm going to update the retention explicitly since so it's obvious from the script.

retention-days: 1 One day is the minimum which is really too long for this but should serve us fine.

Also worth noting that artifacts are only accessible from the workflow in which they were created so there's no chance of us pulling an old artifact which I was worried about initially.


test-unprivileged:
runs-on: ubuntu-latest
needs: build-unprivileged-for-test
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: sudo apt-get update -qq && sudo apt-get install -y curl wait-for-it
- name: Restore cached binaries
id: cache-binaries-restore
uses: actions/cache/restore@v3
with:
path: .bin
key: ${{ runner.os }}-binaries
- name: Install MinIO Client
run: |
mkdir .bin || exit 0
cd .bin
curl --insecure --retry 6 --fail --location --output mc.RELEASE.2023-06-19T19-31-19Z "https://dl.min.io/client/mc/release/linux-$(dpkg --print-architecture)/archive/mc.RELEASE.2023-06-19T19-31-19Z"
curl --insecure --retry 6 --fail --silent --location "https://dl.min.io/client/mc/release/linux-$(dpkg --print-architecture)/archive/mc.RELEASE.2023-06-19T19-31-19Z.sha256sum" | sha256sum --check -
mv mc.RELEASE.2023-06-19T19-31-19Z mc
chmod +x mc
- name: Download artifact
uses: actions/download-artifact@v3
with:
name: unprivileged
path: /tmp
- name: Load image
run: |
docker load --input /tmp/unprivileged.tar
docker tag nginx-s3-gateway:unprivileged-oss nginx-s3-gateway
- name: Run tests - unprivileged
run: ./test.sh --unprivileged --type oss
# unprivileged-oss image push [Github]
- name: Tag container image for Push to github [unprivileged-oss date]
run: docker tag nginx-s3-gateway:unprivileged-oss docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:unprivileged-oss-${{ steps.date.outputs.date }}
- name: Tag container image for Push to github [unprivileged-oss]
run: docker tag nginx-s3-gateway:unprivileged-oss docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:unprivileged-oss
- name: Push container image to github [unprivileged-oss date]
run: docker push docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:unprivileged-oss-${{ steps.date.outputs.date }}
- name: Push container image to github [unprivileged-oss]
run: docker push docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:unprivileged-oss

# Run tests and builds image
- name: Run tests - stable njs version
run: ./test.sh --type oss
# oss image push [Github]
- name: Tag container image for Push to github [oss date]
run: docker tag nginx-s3-gateway:oss docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:latest-${{ steps.date.outputs.date }}
- name: Tag container image for Push to github [oss]
run: docker tag nginx-s3-gateway:oss docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:latest
- name: Push container image to github [oss date]
run: docker push docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:latest-${{ steps.date.outputs.date }}
- name: Push container image to github [oss latest]
run: docker push docker.pkg.github.com/$GITHUB_REPOSITORY/nginx-oss-s3-gateway:latest
# Login to Docker Hub

# After the tests are done, build multiarch and push to both github packages and dockerhub if we are on master/main
tag-and-push:
runs-on: ubuntu-latest
needs: [test-oss, test-latest-njs, test-unprivileged]

if: |
github.ref == 'refs/heads/master' ||
github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Get current date
id: date
run: echo "date=$(date +'%Y%m%d')" >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64,linux/arm64
- name: Login to Docker Hub
uses: docker/login-action@v1
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
# latest-njs-oss image push [Docker Hub]
- name: Tag container image for Push to Docker Hub [latest-njs-oss date]
run: docker tag nginx-s3-gateway:latest-njs-oss nginxinc/nginx-s3-gateway:latest-njs-oss-${{ steps.date.outputs.date }}
- name: Tag container image for Push to Docker Hub [latest-njs-oss]
run: docker tag nginx-s3-gateway:latest-njs-oss nginxinc/nginx-s3-gateway:latest-njs-oss
- name: Push container image to Docker Hub [latest-njs-oss date]
run: docker push nginxinc/nginx-s3-gateway:latest-njs-oss-${{ steps.date.outputs.date }}
- name: Push container image to Docker Hub [latest-njs-oss]
run: docker push nginxinc/nginx-s3-gateway:latest-njs-oss
# unprivileged-oss image push [Docker Hub]
- name: Tag container image for Push to Docker Hub [unprivileged-oss date]
run: docker tag nginx-s3-gateway:unprivileged-oss nginxinc/nginx-s3-gateway:unprivileged-oss-${{ steps.date.outputs.date }}
- name: Tag container image for Push to Docker Hub [unprivileged-oss]
run: docker tag nginx-s3-gateway:unprivileged-oss nginxinc/nginx-s3-gateway:unprivileged-oss
- name: Push container image to Docker Hub [unprivileged-oss date]
run: docker push nginxinc/nginx-s3-gateway:unprivileged-oss-${{ steps.date.outputs.date }}
- name: Push container image to Docker Hub [unprivileged-oss]
run: docker push nginxinc/nginx-s3-gateway:unprivileged-oss
# oss image push [Docker Hub]
- name: Tag container image for Push to Docker Hub [oss date]
run: docker tag nginx-s3-gateway:oss nginxinc/nginx-s3-gateway:latest-${{ steps.date.outputs.date }}
- name: Tag container image for Push to Docker Hub [oss]
run: docker tag nginx-s3-gateway:oss nginxinc/nginx-s3-gateway:latest
- name: Push container image to Docker Hub [oss date]
run: docker push nginxinc/nginx-s3-gateway:latest-${{ steps.date.outputs.date }}
- name: Push container image to Docker Hub [oss latest]
run: docker push nginxinc/nginx-s3-gateway:latest
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push image [oss]
uses: docker/build-push-action@v5
with:
file: Dockerfile.oss
context: .
push: true
platforms: linux/amd64,linux/arm64
provenance: false
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

annotation:
This is a little workaround for the github packages repo. The provenance file is a docker thing not an OCI thing so you'll get an unknown/unknown architecture listed in gh packages if you don't set this.

ref: https://docs.docker.com/build/attestations/slsa-provenance/

If we want these to go to dockerhub, we could also separate the builds again but I think the simplicity of having them both push is more desireable.

tags: |
ghcr.io/${{ github.repository }}/nginx-oss-s3-gateway:latest-${{ steps.date.outputs.date }}
ghcr.io/${{ github.repository }}/nginx-oss-s3-gateway:latest
nginxinc/nginx-s3-gateway:latest-${{ steps.date.outputs.date }}
nginxinc/nginx-s3-gateway:latest
Comment on lines +266 to +270
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

annotation:
This is nice, the plugin lets you log in to both registries then pushes tot the correct one based on the tag.


- name: Build and push image [latest-njs]
uses: docker/build-push-action@v5
with:
file: Dockerfile.latest-njs
context: .
push: true
platforms: linux/amd64,linux/arm64
provenance: false
tags: |
ghcr.io/${{ github.repository }}/nginx-oss-s3-gateway:latest-njs-oss-${{ steps.date.outputs.date }}
ghcr.io/${{ github.repository }}/nginx-oss-s3-gateway:latest-njs-oss
nginxinc/nginx-s3-gateway:latest-njs-oss-${{ steps.date.outputs.date }}
nginxinc/nginx-s3-gateway:latest-njs-oss

- name: Build and push image [unprivileged]
uses: docker/build-push-action@v5
with:
file: Dockerfile.unprivileged
context: .
push: true
platforms: linux/amd64,linux/arm64
provenance: false
tags: |
ghcr.io/${{ github.repository }}/nginx-oss-s3-gateway:unprivileged-oss-${{ steps.date.outputs.date }}
ghcr.io/${{ github.repository }}/nginx-oss-s3-gateway:unprivileged-oss
nginxinc/nginx-s3-gateway:unprivileged-oss-${{ steps.date.outputs.date }}
nginxinc/nginx-s3-gateway:unprivileged-oss
Loading