Gitea Actions: как обойти ошибку 403 от docker.io при сборке образа

Привет.

У меня есть репозиторий с go-утилитой. Когда-то я настроил там экшн для сборки релиза при пуше тега версии. Тег пушнул, релиз в репе собрался, файлы приложились. Текстовка, правда, не написалась, но раз в полгода можно и ручками .

Теперь я организую докер-образы утилиты, чтобы они пушились в организацию. И возникла проблема: при сборке раннером на сервере возникала ошибка 403 при получении базового образа.

Напомню свою конфигурацию сервера:

Базово, чтобы создать докер-образ и пушнуть его в какой-то реестр, используя gitea actions, нужно всего-ничего:

...
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Log in to Gitea Container Registry
        uses: docker/login-action@v3
        with:
          registry: registry.example.com
          username: ${{ secrets.USERNAME }}
          password: ${{ secrets.RELEASE_TOKEN }}
      - name: Build and push Docker images
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            registry.example.com/test/myapp:${{ github.ref_name }}
            registry.example.com/test/myapp:latest
...

По шагам:

  1. получение репозитория
  2. создание докер-билдера для образов
  3. авторизация в условном докер-хабе или собственном хранилище;
  4. построение и отправка образов в хранилище.

На последнем шаге при построении моих образов докер-хаб не пускал в себя за базовым.

...
[command]/usr/bin/docker buildx build --iidfile /tmp/docker-actions-toolkit-6LSbUU/build-iidfile-eea13063d6.txt --attest type=provenance,mode=max,builder-id=http://gitea:3000/IPTV/iptvc/actions/runs/35 --tag registry.example.com/test/myapp:v-test --tag registry.example.com/test/myapp:latest --metadata-file /tmp/docker-actions-toolkit-6LSbUU/build-metadata-2728a4ffb8.json --push .
#0 building with "builder-dbdc9d2c-2704-4862-aa99-01ea55eb702e" instance using docker-container driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 745B 0.0s done
#1 DONE 0.1s
#2 [internal] load metadata for docker.io/library/alpine:3.22.2
#2 ...
#3 [internal] load metadata for docker.io/library/golang:1.25-alpine
#3 ERROR: unexpected status from HEAD request to https://registry-1.docker.io/v2/library/golang/manifests/1.25-alpine: 403 Forbidden
#2 [internal] load metadata for docker.io/library/alpine:3.22.2
#2 CANCELED
------
 > [internal] load metadata for docker.io/library/golang:1.25-alpine:
------
Dockerfile:1
--------------------
   1 | >>> FROM golang:1.25-alpine AS iptv-img-builder
   2 |     ARG GOOS
   3 |     ARG GOARCH
--------------------
ERROR: failed to build: failed to solve: golang:1.25-alpine: failed to resolve source metadata for docker.io/library/golang:1.25-alpine: unexpected status from HEAD request to https://registry-1.docker.io/v2/library/golang/manifests/1.25-alpine: 403 Forbidden
::error::buildx failed with: ERROR: failed to build: failed to solve: golang:1.25-alpine: failed to resolve source metadata for docker.io/library/golang:1.25-alpine: unexpected status from HEAD request to https://registry-1.docker.io/v2/library/golang/manifests/1.25-alpine: 403 Forbidden

Проверка HEAD-запросом с сервера раннера на docker.io показала, что он отдаёт ту же 403. На самом сервере docker pull работает успешно, но там и зеркала прописаны:

Расследование показало, что создаваемый билдер изолирован от хостового, а значит эти зеркала он с хоста не берёт и ломится напрямую.

Как будто, выглядит странновато, не так-ли? В том посте я писал, что докер-хаб довольно быстро разблокировал РФ после той шумихи. Но сервер с моей гити находится в РФ, а 403 я всё равно получаю.

На самом деле, я не знаю на текущий момент с чем это связано, и разбираться не хочу, пока есть рабочие зеркала. Скорее всего, санкции продолжают действовать на российских гигамонстров вроде Селектела.

Ну, если зеркала не берутся с хоста, то надо их как-то подсунуть в экшен, но куда? Третий экшен со сборкой никак не связан, а четвёртый билдера просто вызывает и обрабатывает его результаты. Значит во второй, куда же ещё.

И такая возможность действительно есть. Изучение документации у docker/setup-buildx-action навело меня на параметр buildkitd-config-inline, где многострочным значением можно указать всякие настройки. А настройки, которые касаются зеркал, для buildx существуют, поэтому обязательно их прописываем прямо в ямл:

...
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          buildkitd-config-inline: |
            [ registry."docker.io" ]
            mirrors = ["https://dockerhub.timeweb.cloud", "https://dh-mirror.gitverse.ru"]
            http = true
            insecure = true
...

Вот и всё. При следующем триггере экшены отработают и окажутся зелёными, а образы будут лежать там, где ты заменил registry.example.com/test/myapp на свой адрес.

Использованные материалы


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *