Skip to content

Commit

Permalink
feat(docker): add arm64 images
Browse files Browse the repository at this point in the history
  - Add a workaround for slow performance of amd64-arm64-QEMU yarn install
    by caching arm images
  • Loading branch information
sirchnik-xitaso committed Feb 3, 2025
1 parent e13022d commit ebf6f48
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 59 deletions.
155 changes: 98 additions & 57 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Docker
name: CI and Docker Deploy

on:
push:
Expand All @@ -14,26 +14,10 @@ concurrency:
env:
# github.repository as <account>/<repo>
IMAGE_NAME: mnestix-browser
IMAGE_TAG: latest
# Update the version manually
IMAGE_TAG_VERSION: 1.3.3
REGISTRY_USER: ${{ secrets.DOCKER_USERNAME }}
REGISTRY_PASS: ${{ secrets.DOCKER_API_TOKEN }}

jobs:
unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Run unit tests
id: test_units
run: yarn install && npx jest

build-browser-image:
name: Build browser image
runs-on: ubuntu-latest
Expand All @@ -44,14 +28,26 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build image
id: build
run: docker compose build mnestix-browser

uses: docker/build-push-action@v6
with:
platforms: linux/amd64
context: "."
cache-to: type=gha,scope=amd64,mode=max
cache-from: type=gha,scope=amd64
target: production
push: false
tags: mnestix/mnestix-browser:latest
load: true

- name: Save mnestix-browser image
run: docker save mnestix/mnestix-browser:latest -o mnestix-browser.tar

- name: Upload mnestix-browser artifact
uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -84,10 +80,11 @@ jobs:
run: docker load -i mnestix-browser.tar

# image too big to be reused
- name: prepare tests
run: |
docker compose -f compose.yml -f docker-compose/compose.test.yml --profile tests build cypress-test
docker compose -f compose.yml -f docker-compose/compose.test.yml --profile tests pull
- name: Build test image
run: docker compose -f compose.yml -f docker-compose/compose.test.yml --profile tests build cypress-test

- name: Pull images
run: docker compose -f compose.yml -f docker-compose/compose.test.yml --profile tests pull

- name: Run e2e tests
id: test
Expand All @@ -105,52 +102,96 @@ jobs:
name: cypress-artifacts-${{ matrix.containers }}
path: cypress-artifacts/

unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install dependencies
run: yarn install
- name: Run unit tests
id: test_units
run: npx jest

# Target for PR Merge Check
ci-success:
name: Successful build and tests
runs-on: ubuntu-latest
needs: [ 'unit-tests', 'e2e-tests' ]
steps:
- name: Success
run: echo "Success"

# It takes 22 minutes to build the arm64 image in amd64-QEMU so we build a cache on the arm64 runner
# Github Issues point to a yarn problem
# https://github.com/docker/build-push-action/issues/471
# https://github.com/nodejs/docker-node/issues/1335
build-arm-cache:
name: Build arm image cache
runs-on: ubuntu-24.04-arm
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build
uses: docker/build-push-action@v6
with:
platforms: linux/arm64
context: "."
cache-to: type=gha,scope=arm64,mode=max
cache-from: type=gha,scope=arm64
target: production
push: false

push-image:
name: Push image to registry
needs: [ 'build-browser-image', 'unit-tests', 'e2e-tests' ]
needs: [ 'ci-success', 'build-arm-cache' ]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/dev'
# if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/dev')
permissions:
contents: read
packages: write

steps:
- name: Extract branch name
id: extract_branch
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT

- name: Checkout repository
uses: actions/checkout@v4

- name: Download mnestix-browser artifact
uses: actions/download-artifact@v4
with:
name: mnestix-browser

- name: Load mnestix-browser image
run: docker load -i mnestix-browser.tar
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into docker hub
if: github.event_name != 'pull_request'
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ env.REGISTRY_USER }}
password: ${{ env.REGISTRY_PASS }}
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}

- name: Push Image to Production
- name: Extract branch name
id: extract_branch
run: echo "branch=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> $GITHUB_OUTPUT

- name: Build and push docker images
id: push-prod
if: github.ref == 'refs/heads/main'
run: docker tag mnestix/$IMAGE_NAME mnestix/$IMAGE_NAME:$IMAGE_TAG &&
docker tag mnestix/$IMAGE_NAME mnestix/$IMAGE_NAME:$IMAGE_TAG_VERSION &&
docker push mnestix/$IMAGE_NAME:$IMAGE_TAG &&
docker push mnestix/$IMAGE_NAME:$IMAGE_TAG_VERSION

- name: Push Image to development
id: push-dev
if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/staging'
env:
BRANCH_NAME: ${{ steps.extract_branch.outputs.branch }}
run: docker tag mnestix/$IMAGE_NAME mnestix/$IMAGE_NAME:$BRANCH_NAME &&
docker push mnestix/$IMAGE_NAME:$BRANCH_NAME
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
context: "."
cache-from: |
type=gha,scope=amd64
type=gha,scope=arm64
target: production
push: true
tags: |
${{ github.ref == 'refs/heads/main' && format('mnestix/{0}:{1}', env.IMAGE_NAME, env.IMAGE_TAG_VERSION) || '' }}
${{ github.ref == 'refs/heads/main' && format('mnestix/{0}:latest', env.IMAGE_NAME) || '' }}
${{ github.ref != 'refs/heads/main' && format('mnestix/{0}:{1}', env.IMAGE_NAME, steps.extract_branch.outputs.branch) || '' }}
12 changes: 10 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ RUN apk update && apk add --no-cache openssl
FROM base AS deps
WORKDIR /app
COPY package*.json yarn.lock* ./
RUN yarn install --frozen-lockfile --production
# This is a workaround for yarn QEMU support
# https://github.com/docker/build-push-action/issues/471
# https://github.com/nodejs/docker-node/issues/1335
RUN ARCH=$(uname -m); \
if [ "$ARCH" = "aarch64" ]; then \
yarn install --frozen-lockfile --production --network-timeout 1000000; \
else \
yarn install --frozen-lockfile --production; \
fi
RUN apk update && apk add --no-cache openssl

# Next.js collects completely anonymous telemetry data about general usage. Learn more here: https://nextjs.org/telemetry
Expand All @@ -29,7 +37,7 @@ RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
USER nextjs
EXPOSE 3000
ENV PORT 3000
ENV PORT=3000

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/prisma/database/mnestix-database.db ./prisma/database/mnestix-database.db
Expand Down

0 comments on commit ebf6f48

Please sign in to comment.