Enhance README and Docker workflow with detailed explanations on registry authentication, workflow triggers, and optional container update webhook. Updated job permissions and streamlined Docker image build and push process.
Publish cloudflare-balancer Docker image / build-and-push (push) Failing after 2m36s

This commit is contained in:
Denozordec
2026-03-23 17:43:44 +07:00
parent ce99072937
commit a151c20049
2 changed files with 95 additions and 54 deletions
+78 -44
View File
@@ -1,61 +1,95 @@
name: Docker
name: Publish cloudflare-balancer Docker image
on:
push:
branches:
- main
- master
- '**'
tags:
- 'v*'
pull_request:
- '*'
workflow_dispatch:
env:
# Хост Container Registry (без схемы), тот же что для docker pull/push
REGISTRY: git.shts.su
IMAGE_REPO: ${{ gitea.repository }}
jobs:
build:
build-and-push:
runs-on: ubuntu-latest
timeout-minutes: 20
permissions:
contents: read
packages: write
steps:
- name: Checkout
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Build image
run: docker build -t cloudflare-balancer:ci .
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
driver-opts: |
image=moby/buildkit:v0.13.2
# Публикация в registry: не используйте `if: secrets.X != ''` — в Gitea/GitHub
# проверка «пустой ли секрет» в выражениях часто всегда ложна, шаги пропускаются.
# Секреты пробрасываем в env и проверяем в bash.
#
# Секреты: REGISTRY_URL, REGISTRY_USER, PACKAGE_TOKEN (или REGISTRY_PASSWORD)
- name: Login and push to Container Registry (optional)
# Пароль registry — встроенный токен job (packages: write), без отдельного PAT
- name: Log in to Gitea Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ gitea.actor }}
password: ${{ gitea.token }}
- name: Prepare Docker tags
id: prep
shell: bash
env:
REGISTRY_URL: ${{ secrets.REGISTRY_URL }}
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
REPO: ${{ gitea.repository }}
SHA: ${{ gitea.sha }}
REF_NAME: ${{ gitea.ref_name }}
run: |
set -euo pipefail
IMAGE="${REGISTRY}/${REPO}"
BRANCH_OR_TAG="${REF_NAME:-unknown}"
SAFE_REF="$(echo "${BRANCH_OR_TAG}" | tr '/' '-')"
SHORT_SHA="$(echo "${SHA}" | cut -c1-12)"
TAGS="$(printf '%s\n%s\n%s\n' \
"${IMAGE}:latest" \
"${IMAGE}:${SAFE_REF}" \
"${IMAGE}:sha-${SHORT_SHA}")"
echo "tags<<EOF" >> "${GITHUB_OUTPUT}"
echo "${TAGS}" >> "${GITHUB_OUTPUT}"
echo "EOF" >> "${GITHUB_OUTPUT}"
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
platforms: linux/amd64
cache-from: |
type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_REPO }}:latest
cache-to: type=inline
tags: ${{ steps.prep.outputs.tags }}
labels: |
org.opencontainers.image.title=cloudflare-balancer
org.opencontainers.image.description=Health-check бэкендов и синхронизация пула A/AAAA в Cloudflare DNS
org.opencontainers.image.revision=${{ gitea.sha }}
org.opencontainers.image.source=${{ gitea.server_url }}/${{ gitea.repository }}
provenance: false
# Секрет CONTAINER_UPDATE_URL — URL webhook (например Portainer: обычно GET по уникальной ссылке)
- name: Webhook обновления контейнера
env:
CONTAINER_UPDATE_URL: ${{ secrets.CONTAINER_UPDATE_URL }}
run: |
set -e
if [ "${GITHUB_EVENT_NAME:-}" = "pull_request" ]; then
echo "Pull request: push в registry не выполняется (только сборка)."
if [ -z "${CONTAINER_UPDATE_URL:-}" ]; then
echo "CONTAINER_UPDATE_URL не задан — шаг пропущен."
exit 0
fi
if [ -z "${REGISTRY_URL:-}" ] || [ -z "${REGISTRY_USER:-}" ]; then
echo "Пропуск registry: задайте секреты REGISTRY_URL и REGISTRY_USER."
exit 0
fi
PASS="${PACKAGE_TOKEN:-}"
if [ -z "$PASS" ]; then PASS="${REGISTRY_PASSWORD:-}"; fi
if [ -z "$PASS" ]; then
echo "Пропуск registry: задайте PACKAGE_TOKEN или REGISTRY_PASSWORD."
exit 0
fi
REG="${REGISTRY_URL#https://}"
REG="${REG#http://}"
REG="${REG%/}"
echo "$PASS" | docker login "$REG" -u "$REGISTRY_USER" --password-stdin
IMG="cloudflare-balancer"
OWNER_LOWER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
TAG="${GITHUB_SHA:0:12}"
case "${GITHUB_REF}" in refs/tags/*) TAG="${GITHUB_REF#refs/tags/}" ;; esac
docker tag cloudflare-balancer:ci "${REG}/${OWNER_LOWER}/${IMG}:${TAG}"
docker tag cloudflare-balancer:ci "${REG}/${OWNER_LOWER}/${IMG}:latest"
docker push "${REG}/${OWNER_LOWER}/${IMG}:${TAG}"
docker push "${REG}/${OWNER_LOWER}/${IMG}:latest"
echo "Опубликовано: ${REG}/${OWNER_LOWER}/${IMG}:${TAG}"
curl -fsS -m 120 "${CONTAINER_UPDATE_URL}"
+17 -10
View File
@@ -239,19 +239,26 @@ docker logs -f <container_id>
## Сборка в CI (Gitea Actions)
1. На сервере Gitea включите **Actions** и подключите **runner** ([документация](https://docs.gitea.com/usage/actions/overview)).
2. Workflow: [.gitea/workflows/docker.yml](.gitea/workflows/docker.yml).
3. По умолчанию выполняется **`docker build`**.
4. Опциональная публикация в **Container Registry** Gitea: задайте секреты репозитория:
- `REGISTRY_URL` — хост (можно с `https://`, скрипт обрежет протокол для `docker login`).
- `REGISTRY_USER` — логин пользователя Gitea.
- **`PACKAGE_TOKEN`** — токен Gitea с правом публиковать пакеты (используется как **пароль** в `docker login`; рекомендуемый способ).
- `REGISTRY_PASSWORD` — опционально, только если не задан `PACKAGE_TOKEN` (устаревший/альтернативный секрет).
2. Workflow: [.gitea/workflows/docker.yml](.gitea/workflows/docker.yml)**Buildx**, `docker/login-action`, `docker/build-push-action`; пути и метаданные из контекста **`gitea.*`** (`repository`, `actor`, `sha`, `ref_name`, `server_url`).
Имя образа в registry: `<REGISTRY>/<owner_lowercase>/cloudflare-balancer:<tag>`.
**Авторизация в registry**
> В Gitea создайте **Personal Access Token** (или токен с нужным scope) с доступом к **пакетам** / записи в Container Registry и сохраните его в секрете **`PACKAGE_TOKEN`**.
- Отдельный **`ACTIONS_PAT` не нужен**: в `docker login` используется встроенный **`gitea.token`** (токен текущего запуска workflow) и **`gitea.actor`**. У job задано **`permissions: packages: write`** — этого достаточно для push в Container Registry на том же Gitea (при несовместимости вашей версии см. [документацию Gitea Actions](https://docs.gitea.com/usage/actions/overview)).
> **Почему шаги не «Skipped»:** в workflow нет условия `if: secrets.… != ''` — в Gitea Actions (как и в GitHub) такие проверки часто **всегда ложны**, и публикация молча пропускается. Вместо этого один шаг всегда выполняется: при отсутствии секретов он выводит причину и завершается с кодом 0. На **pull request** push в registry намеренно не делается (только `docker build`).
**Секрет для обновления контейнера (опционально)**
- **`CONTAINER_UPDATE_URL`** — полный URL webhook после успешного push (например ссылка **Redeploy** в Portainer, другой оркестратор). Workflow делает **`curl` (GET)** по этому URL; если секрет пустой, шаг только пишет в лог и выходит. При необходимости другого метода (POST) измените шаг в `docker.yml`.
**Переменные в workflow**
- **`env.REGISTRY`** в начале `docker.yml` — хост registry **без** схемы (`https://`), как для `docker pull` (в файле задан пример `git.shts.su`; замените при переносе на другой инстанс).
- **`IMAGE_REPO`:** `${{ gitea.repository }}` — полный путь образа: `${REGISTRY}/${{ gitea.repository }}`.
**Триггеры:** push по всем веткам и тегам, **`workflow_dispatch`**.
**Теги:** `latest`, «безопасное» имя ветки/тега (`/``-`), `sha-<12 hex>`.
**Job:** `permissions: contents: read`, `packages: write`.
---