From c6ac0daf1843082bb4838a57b2e3073d0283be96 Mon Sep 17 00:00:00 2001 From: Wells Date: Wed, 31 Dec 2025 14:05:42 +0800 Subject: [PATCH 01/10] feat: support ARM64 with official Ruby + jemalloc --- .github/workflows/release.yml | 23 +++++++++++++-------- Dockerfile | 23 +++++++++++---------- README.md | 38 +++++++++++++++++++++++++++++------ sync-to-ecr.sh | 30 +++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 25 deletions(-) create mode 100644 sync-to-ecr.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6dcff90..23ea679 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,9 +1,9 @@ name: Build and Publish on: - create: + push: tags: - - '*' + - '*' jobs: build-and-push-docker-image: @@ -12,24 +12,31 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Docker meta id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 with: images: polydice/base tags: type=ref,event=tag - name: Login to DockerHub - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Build image and push to Docker Hub - uses: docker/build-push-action@v3 + - name: Build and push + uses: docker/build-push-action@v6 with: push: true context: . - tags: ${{ steps.meta.outputs.tags }} \ No newline at end of file + platforms: linux/amd64,linux/arm64 + tags: ${{ steps.meta.outputs.tags }} diff --git a/Dockerfile b/Dockerfile index 7fe06bb..3c70160 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,11 @@ ARG RUBY_VERSION=2.7.8 -ARG VARIANT=jemalloc-slim -FROM quay.io/evl.ms/fullstaq-ruby:${RUBY_VERSION}-${VARIANT} as base +FROM ruby:${RUBY_VERSION}-slim + +# jemalloc for better memory management +RUN apt-get update && apt-get install -y --no-install-recommends libjemalloc2 \ + && ln -sf /usr/lib/*-linux-gnu/libjemalloc.so.2 /usr/lib/libjemalloc.so.2 \ + && rm -rf /var/lib/apt/lists/* +ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2 ARG BUNDLER_VERSION=2.4.20 RUN gem install -N bundler -v ${BUNDLER_VERSION} @@ -8,7 +13,9 @@ RUN gem install -N bundler -v ${BUNDLER_VERSION} ARG NODE_VERSION=18.18.0 ARG YARN_VERSION=1.22.22 ARG PNPM_VERSION=9.9.0 -RUN curl https://get.volta.sh | bash +RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates \ + && rm -rf /var/lib/apt/lists/* \ + && curl https://get.volta.sh | bash ENV VOLTA_HOME /root/.volta ENV VOLTA_FEATURE_PNPM=1 ENV PATH $VOLTA_HOME/bin:/usr/local/bin:$PATH @@ -23,28 +30,22 @@ RUN apt-get update \ graphicsmagick \ file \ tar \ - curl \ - ca-certificates \ - libmcrypt4 \ shared-mime-info \ + libmcrypt4 \ && rm -rf /var/lib/apt/lists/* RUN set -ex \ - \ && buildDeps=' \ g++ \ make \ cmake \ - python \ ' \ && apt-get update \ && apt-get install -y --no-install-recommends $buildDeps \ && rm -rf /var/lib/apt/lists/* \ - \ && curl -L https://github.com/BYVoid/OpenCC/archive/refs/tags/ver.1.1.9.tar.gz | tar -xz \ - && cd OpenCC-ver.1.1.9 \ + && cd OpenCC-ver.1.1.9 \ && REL_BUILD_DOCUMENTATION=OFF make install \ - \ && apt-get purge -y --auto-remove $buildDeps \ && cd ../ \ && rm -rf OpenCC-ver.1.1.9 diff --git a/README.md b/README.md index 5fbdb5e..ebacf09 100644 --- a/README.md +++ b/README.md @@ -7,11 +7,37 @@ Polydice's base docker image for Rails applications. - `x.y.z` - Standard image for running on production - `x.y.z-testing` - Image for testing which includes additional packages. +## Architectures + +- `linux/amd64` (x86_64) +- `linux/arm64` (Graviton, Apple Silicon) + ## Versions -| Version | Ruby | Node.js | Yarn | Bundler | pnpm | -|---------|-------|---------|---------|---------|-------| -| 0.31.2 | 2.7.8 | 18.18.0 | 1.22.22 | 2.4.20 | 9.9.0 | -| 0.31.1 | 2.7.8 | 18.18.0 | 1.22.19 | 2.4.20 | 8.8.0 | -| 0.31.0 | 2.7.7 | 18.18.0 | 1.22.19 | 2.4.5 | 8.8.0 | -| 0.30.3 | 2.7.7 | 14.21.2 | 1.22.19 | 2.4.5 | | \ No newline at end of file +| Version | Ruby | Node.js | Yarn | Bundler | pnpm | ARM64 | +|---------|-------|---------|---------|---------|-------|-------| +| 0.32.0 | 2.7.8 | 18.18.0 | 1.22.22 | 2.4.20 | 9.9.0 | ✅ | +| 0.31.2 | 2.7.8 | 18.18.0 | 1.22.22 | 2.4.20 | 9.9.0 | ❌ | +| 0.31.1 | 2.7.8 | 18.18.0 | 1.22.19 | 2.4.20 | 8.8.0 | ❌ | +| 0.31.0 | 2.7.7 | 18.18.0 | 1.22.19 | 2.4.5 | 8.8.0 | ❌ | +| 0.30.3 | 2.7.7 | 14.21.2 | 1.22.19 | 2.4.5 | | ❌ | + +## Release + +1. Update version in README.md +2. Commit and push tag: + ```bash + git tag 0.32.0 + git push origin 0.32.0 + ``` +3. Wait for GitHub Actions to build and push to DockerHub +4. Sync to ECR Public: + ```bash + ./sync-to-ecr.sh 0.32.0 + ``` + +## Changes in 0.32.0 + +- Switched from fullstaq-ruby to official Ruby image +- Added jemalloc via `LD_PRELOAD` +- Added ARM64 (linux/arm64) support diff --git a/sync-to-ecr.sh b/sync-to-ecr.sh new file mode 100644 index 0000000..0bd4264 --- /dev/null +++ b/sync-to-ecr.sh @@ -0,0 +1,30 @@ +#!/bin/bash +set -e + +VERSION=${1:?Usage: ./sync-to-ecr.sh } +SOURCE="polydice/base" +TARGET="public.ecr.aws/z1n0q3w1/base" + +# Check AWS permissions +if ! aws ecr-public get-authorization-token --region us-east-1 &>/dev/null; then + echo "❌ No permission to push to ECR Public. Run 'aws configure' first." + exit 1 +fi + +# Login to ECR Public +aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws + +# Sync tags +for TAG in "${VERSION}" "${VERSION}-testing"; do + echo "🔄 Syncing ${TAG}..." + docker pull ${SOURCE}:${TAG} --platform linux/amd64 + docker tag ${SOURCE}:${TAG} ${TARGET}:${TAG} + docker push ${TARGET}:${TAG} + + # Also sync ARM64 + docker pull ${SOURCE}:${TAG} --platform linux/arm64 + docker tag ${SOURCE}:${TAG} ${TARGET}:${TAG}-arm64 + docker push ${TARGET}:${TAG}-arm64 +done + +echo "✅ Synced ${VERSION} to ECR Public (amd64 + arm64)" From da17cf25e8a7e097c342a4f487736492f5d6af54 Mon Sep 17 00:00:00 2001 From: Wells Date: Wed, 31 Dec 2025 14:27:46 +0800 Subject: [PATCH 02/10] fix: restore original trigger (on: create) --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 23ea679..0f07eff 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,7 @@ name: Build and Publish on: - push: + create: tags: - '*' From 1b3c0bf5cc0cf54337a36e8827dc6f375b044ed1 Mon Sep 17 00:00:00 2001 From: Wells Date: Wed, 31 Dec 2025 14:29:34 +0800 Subject: [PATCH 03/10] fix: use find instead of wildcard for jemalloc symlink --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3c70160..056e48b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM ruby:${RUBY_VERSION}-slim # jemalloc for better memory management RUN apt-get update && apt-get install -y --no-install-recommends libjemalloc2 \ - && ln -sf /usr/lib/*-linux-gnu/libjemalloc.so.2 /usr/lib/libjemalloc.so.2 \ + && ln -sf $(find /usr/lib -name "libjemalloc.so.2" | head -1) /usr/lib/libjemalloc.so.2 \ && rm -rf /var/lib/apt/lists/* ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2 From 70838188f569424c86fbcad3d34f8c506cdbcbad Mon Sep 17 00:00:00 2001 From: Wells Date: Wed, 31 Dec 2025 14:32:50 +0800 Subject: [PATCH 04/10] docs: use placeholder for version in release instructions --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ebacf09..098c142 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,13 @@ Polydice's base docker image for Rails applications. 1. Update version in README.md 2. Commit and push tag: ```bash - git tag 0.32.0 - git push origin 0.32.0 + git tag + git push origin ``` 3. Wait for GitHub Actions to build and push to DockerHub 4. Sync to ECR Public: ```bash - ./sync-to-ecr.sh 0.32.0 + ./sync-to-ecr.sh ``` ## Changes in 0.32.0 From b89b3d5a4aced91de3ab2bd52c71e8ad2eb56aff Mon Sep 17 00:00:00 2001 From: Wells Date: Wed, 31 Dec 2025 14:32:51 +0800 Subject: [PATCH 05/10] fix: use buildx imagetools for multi-arch sync --- sync-to-ecr.sh | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/sync-to-ecr.sh b/sync-to-ecr.sh index 0bd4264..6b02b5a 100644 --- a/sync-to-ecr.sh +++ b/sync-to-ecr.sh @@ -14,17 +14,12 @@ fi # Login to ECR Public aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws -# Sync tags +# Sync multi-arch images for TAG in "${VERSION}" "${VERSION}-testing"; do echo "🔄 Syncing ${TAG}..." - docker pull ${SOURCE}:${TAG} --platform linux/amd64 - docker tag ${SOURCE}:${TAG} ${TARGET}:${TAG} - docker push ${TARGET}:${TAG} - - # Also sync ARM64 - docker pull ${SOURCE}:${TAG} --platform linux/arm64 - docker tag ${SOURCE}:${TAG} ${TARGET}:${TAG}-arm64 - docker push ${TARGET}:${TAG}-arm64 + docker buildx imagetools create \ + --tag ${TARGET}:${TAG} \ + ${SOURCE}:${TAG} done -echo "✅ Synced ${VERSION} to ECR Public (amd64 + arm64)" +echo "✅ Synced ${VERSION} to ECR Public (multi-arch)" From 8332f22e7153c1a611f5a4ad178df0106cb56f24 Mon Sep 17 00:00:00 2001 From: Wells Date: Wed, 31 Dec 2025 14:54:21 +0800 Subject: [PATCH 06/10] fix: add jemalloc path verification and python3 for OpenCC build --- Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 056e48b..26f1dd5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,9 @@ FROM ruby:${RUBY_VERSION}-slim # jemalloc for better memory management RUN apt-get update && apt-get install -y --no-install-recommends libjemalloc2 \ - && ln -sf $(find /usr/lib -name "libjemalloc.so.2" | head -1) /usr/lib/libjemalloc.so.2 \ + && JEMALLOC_PATH=$(find /usr/lib -name "libjemalloc.so.2" | head -1) \ + && [ -n "$JEMALLOC_PATH" ] || (echo "libjemalloc.so.2 not found" && exit 1) \ + && ln -sf "$JEMALLOC_PATH" /usr/lib/libjemalloc.so.2 \ && rm -rf /var/lib/apt/lists/* ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2 @@ -39,6 +41,7 @@ RUN set -ex \ g++ \ make \ cmake \ + python3 \ ' \ && apt-get update \ && apt-get install -y --no-install-recommends $buildDeps \ From ef4138945bbcf3d3c55e96c769bc9d0c07b053b5 Mon Sep 17 00:00:00 2001 From: wells Date: Wed, 31 Dec 2025 15:04:02 +0800 Subject: [PATCH 07/10] fix: add tag existence check before syncing to ECR --- sync-to-ecr.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sync-to-ecr.sh b/sync-to-ecr.sh index 6b02b5a..8957c9b 100644 --- a/sync-to-ecr.sh +++ b/sync-to-ecr.sh @@ -16,10 +16,14 @@ aws ecr-public get-login-password --region us-east-1 | docker login --username A # Sync multi-arch images for TAG in "${VERSION}" "${VERSION}-testing"; do - echo "🔄 Syncing ${TAG}..." - docker buildx imagetools create \ - --tag ${TARGET}:${TAG} \ - ${SOURCE}:${TAG} + if docker manifest inspect ${SOURCE}:${TAG} &>/dev/null; then + echo "🔄 Syncing ${TAG}..." + docker buildx imagetools create \ + --tag ${TARGET}:${TAG} \ + ${SOURCE}:${TAG} + else + echo "⚠️ Tag ${TAG} not found on DockerHub, skipping..." + fi done -echo "✅ Synced ${VERSION} to ECR Public (multi-arch)" +echo "✅ Done syncing to ECR Public" From 0fe364bfd813022e224534c59e3ebc8838698751 Mon Sep 17 00:00:00 2001 From: wells Date: Wed, 31 Dec 2025 18:36:43 +0800 Subject: [PATCH 08/10] chore: remove -testing tag from sync script --- sync-to-ecr.sh | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) mode change 100644 => 100755 sync-to-ecr.sh diff --git a/sync-to-ecr.sh b/sync-to-ecr.sh old mode 100644 new mode 100755 index 8957c9b..3095825 --- a/sync-to-ecr.sh +++ b/sync-to-ecr.sh @@ -14,16 +14,10 @@ fi # Login to ECR Public aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws -# Sync multi-arch images -for TAG in "${VERSION}" "${VERSION}-testing"; do - if docker manifest inspect ${SOURCE}:${TAG} &>/dev/null; then - echo "🔄 Syncing ${TAG}..." - docker buildx imagetools create \ - --tag ${TARGET}:${TAG} \ - ${SOURCE}:${TAG} - else - echo "⚠️ Tag ${TAG} not found on DockerHub, skipping..." - fi -done +# Sync multi-arch image +echo "🔄 Syncing ${VERSION}..." +docker buildx imagetools create \ + --tag ${TARGET}:${VERSION} \ + ${SOURCE}:${VERSION} echo "✅ Done syncing to ECR Public" From be24bb014cf82029895e091c7b1dd8741149d8a5 Mon Sep 17 00:00:00 2001 From: wells Date: Tue, 6 Jan 2026 17:42:45 +0800 Subject: [PATCH 09/10] =?UTF-8?q?Add=20=20build=20tools=20=E5=92=8C=20nati?= =?UTF-8?q?ve=20extension=20=E4=BE=9D=E8=B3=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 26f1dd5..f53eb7b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,7 +9,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends libjemalloc2 \ && rm -rf /var/lib/apt/lists/* ENV LD_PRELOAD=/usr/lib/libjemalloc.so.2 -ARG BUNDLER_VERSION=2.4.20 +# 安裝 build tools 和 native extension 依賴 +RUN apt-get update && apt-get install -y --no-install-recommends \ + build-essential \ + libpq-dev \ + libffi-dev \ + && rm -rf /var/lib/apt/lists/* + +ARG BUNDLER_VERSION=2.4.22 RUN gem install -N bundler -v ${BUNDLER_VERSION} ARG NODE_VERSION=18.18.0 From 79e00b9d353cc6f7da0f2ce67433e69359b74345 Mon Sep 17 00:00:00 2001 From: wells Date: Tue, 6 Jan 2026 22:23:45 +0800 Subject: [PATCH 10/10] Keep male and g++ --- Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index f53eb7b..91f57d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -43,10 +43,9 @@ RUN apt-get update \ libmcrypt4 \ && rm -rf /var/lib/apt/lists/* +# Don't add g++/make to buildDeps, or purge will remove build-essential RUN set -ex \ && buildDeps=' \ - g++ \ - make \ cmake \ python3 \ ' \