From fb5baf09f7220ab26a37db7567c21f788d279165 Mon Sep 17 00:00:00 2001 From: Nikolay Gagarinov Date: Thu, 20 Aug 2026 23:01:09 +0500 Subject: [PATCH 1/3] =?UTF-8?q?fix(ci):=20CONTENT-326=20=D1=81=D0=BE=D0=B1?= =?UTF-8?q?=D0=B8=D1=80=D0=B0=D1=82=D1=8C=20=D0=B8=20=D0=BF=D1=83=D0=B1?= =?UTF-8?q?=D0=BB=D0=B8=D0=BA=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B7=D1=8B=20=D0=BF=D0=BE=D0=B4=20arm64?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Опубликованный манифест hexletcomponents/devops-example-app содержал только linux/amd64. На Apple Silicon образ идёт через эмуляцию и Docker печатает предупреждение о несовпадении платформы, а при отключённой Rosetta запуск падает. Образ используется в уроках 300 и 600 курса docker_basics_course, и это первое, что студент вообще запускает. Причина была не в отсутствии настройки, а в том, что CI не пользовался тем, что уже настроено. В main.yml стоят setup-qemu-action и setup-buildx-action, но у шагов публикации не задан platforms, поэтому build-push-action собирал только под архитектуру раннера, то есть amd64. Мультиарх-команда в репозитории была — цель docker-push в Makefile, — но CI её не вызывает. Добавлен platforms: linux/amd64,linux/arm64 обоим шагам публикации, приложению и caddy. Шаг «Build and export to Docker» не тронут: у него load: true, а он с несколькими платформами не работает и нужен только для прогона тестов. Отдельно release.yml. Он собирал версионный тег через pull, tag и push, а этот паттерн схлопывает мультиарх: pull забирает образ только под платформу раннера. То есть даже с починенным main.yml теги v* остались бы однoархитектурными. Заменено на docker buildx imagetools create, который работает с манифестом в реестре, а не со скачанным образом. Оба Dockerfile архитектурно нейтральны: node:26-slim и caddy мультиарховые, пиновок под amd64 нет. Сборка под arm64 локально не проверялась — на машине не зарегистрирован binfmt, эмуляцию на раннере поднимает setup-qemu-action. --- .github/workflows/main.yml | 2 ++ .github/workflows/release.yml | 18 +++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 19e1501..2ad5e8e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,6 +36,7 @@ jobs: uses: docker/build-push-action@v7 with: context: . + platforms: linux/amd64,linux/arm64 push: true tags: hexletcomponents/devops-example-app:latest @@ -44,5 +45,6 @@ jobs: with: context: . file: services/caddy/Dockerfile + platforms: linux/amd64,linux/arm64 push: true tags: hexletcomponents/devops-example-caddy:latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cbd473b..10b7c41 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -22,10 +22,14 @@ jobs: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - - run: docker pull ${{ env.APP_IMAGE_NAME }}:latest - - run: docker tag ${{ env.APP_IMAGE_NAME }}:latest ${{ env.APP_IMAGE_NAME }}:${{ github.ref_name }} - - run: docker push ${{ env.APP_IMAGE_NAME }}:${{ github.ref_name }} - - - run: docker pull ${{ env.CADDY_IMAGE_NAME }}:latest - - run: docker tag ${{ env.CADDY_IMAGE_NAME }}:latest ${{ env.CADDY_IMAGE_NAME }}:${{ github.ref_name }} - - run: docker push ${{ env.CADDY_IMAGE_NAME }}:${{ github.ref_name }} + # imagetools работает с манифестом в реестре, а не со скачанным образом. + # Через pull/tag/push мультиарх схлопывался: pull забирает образ только + # под платформу раннера, и версионный тег получался одноархитектурным. + - run: | + docker buildx imagetools create \ + --tag ${{ env.APP_IMAGE_NAME }}:${{ github.ref_name }} \ + ${{ env.APP_IMAGE_NAME }}:latest + - run: | + docker buildx imagetools create \ + --tag ${{ env.CADDY_IMAGE_NAME }}:${{ github.ref_name }} \ + ${{ env.CADDY_IMAGE_NAME }}:latest From 5609c73bbe44c0f3adc8de9b49274136d0b058f8 Mon Sep 17 00:00:00 2001 From: Nikolay Gagarinov Date: Thu, 20 Aug 2026 23:07:07 +0500 Subject: [PATCH 2/3] =?UTF-8?q?refactor(ci):=20CONTENT-326=20=D1=83=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D1=82=D1=8C=20=D0=BB=D0=B8=D1=88=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B8=20=D0=B2=D0=BE=D0=BA?= =?UTF-8?q?=D1=80=D1=83=D0=B3=20=D0=BC=D1=83=D0=BB=D1=8C=D1=82=D0=B8=D0=B0?= =?UTF-8?q?=D1=80=D1=85-=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit imagetools-команды влезают в одну строку, комментарий сокращён до причины. Закомментированные uses в release.yml удалены: checkout, qemu и buildx этой джобе не нужны, а рядом с новой правкой они читаются как незаконченный шаг. Цель docker-push в Makefile мертва: публикацию делает CI, и после правки он собирает обе платформы сам. Комментарий про запуск x86-образа на ARM снят вместе с ней — образ мультиарховый. Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/release.yml | 18 +++--------------- Makefile | 6 ------ 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 10b7c41..de59c1c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,23 +13,11 @@ jobs: docker: runs-on: ubuntu-latest steps: - # - uses: actions/checkout@v2 - # - uses: docker/setup-qemu-action@v1 - # - uses: docker/setup-buildx-action@v1 - - uses: docker/login-action@v4 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - # imagetools работает с манифестом в реестре, а не со скачанным образом. - # Через pull/tag/push мультиарх схлопывался: pull забирает образ только - # под платформу раннера, и версионный тег получался одноархитектурным. - - run: | - docker buildx imagetools create \ - --tag ${{ env.APP_IMAGE_NAME }}:${{ github.ref_name }} \ - ${{ env.APP_IMAGE_NAME }}:latest - - run: | - docker buildx imagetools create \ - --tag ${{ env.CADDY_IMAGE_NAME }}:${{ github.ref_name }} \ - ${{ env.CADDY_IMAGE_NAME }}:latest + # imagetools переносит манифест целиком; pull/tag/push схлопывал его в платформу раннера + - run: docker buildx imagetools create -t ${{ env.APP_IMAGE_NAME }}:${{ github.ref_name }} ${{ env.APP_IMAGE_NAME }}:latest + - run: docker buildx imagetools create -t ${{ env.CADDY_IMAGE_NAME }}:${{ github.ref_name }} ${{ env.CADDY_IMAGE_NAME }}:latest diff --git a/Makefile b/Makefile index e76959e..4b1d2f6 100644 --- a/Makefile +++ b/Makefile @@ -35,9 +35,6 @@ compose: compose-down: docker compose down -v --remove-orphans -docker-push: - docker buildx build --platform linux/amd64,linux/arm64 -t hexletcomponents/devops-example-app --push . - setup: env-prepare install install: @@ -67,6 +64,3 @@ deploy: ssh: ssh root@`yq e '.all.children.webservers.hosts.web1.ansible_host' ansible/inventory.yml` - -# Для запуска x86-образа на ARM (например, Mac M1/M2): -# docker run --platform linux/amd64 -p 3000:3000 -e SERVER_MESSAGE="Hexlet Awesome Server" hexletcomponents/devops-example-app From 668dd89484c9efe93ff5dd3832b2132d54d731f4 Mon Sep 17 00:00:00 2001 From: Nikolay Gagarinov Date: Thu, 20 Aug 2026 23:16:53 +0500 Subject: [PATCH 3/3] =?UTF-8?q?fix(ci):=20CONTENT-326=20=D0=B7=D0=B0=D0=BF?= =?UTF-8?q?=D1=83=D1=81=D0=BA=D0=B0=D1=82=D1=8C=20release=20=D1=82=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=BA=D0=BE=20=D0=BF=D0=BE=20=D1=82=D0=B5=D0=B3?= =?UTF-8?q?=D0=B0=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit У события create фильтр tags игнорируется: воркфлоу срабатывал и на создание ветки, а github.ref_name тогда равен её имени. Так на Docker Hub попали теги content-326-multiarch-images, remove-biome, fix-main-ci и fix-stop-server — у обоих образов. У push фильтр по тегам работает. Мусорные теги удаляются в Docker Hub руками, воркфлоу их не трогает. Co-Authored-By: Claude Opus 5 (1M context) --- .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 de59c1c..aee593e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,7 @@ name: release on: - create: + push: tags: - v*