Update Docker configuration and documentation for Linux compatibility. Added extra_hosts for Docker Compose and updated GATEWAY_RUN.md to reflect changes in running commands for Linux. Enhanced GitHub Actions workflow for building and pushing Docker images.
This commit is contained in:
@@ -1,20 +1,27 @@
|
|||||||
name: ci
|
name: Publish telemt-api gateway Docker image
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [main, master]
|
branches:
|
||||||
tags: ["v*"]
|
- "**"
|
||||||
pull_request:
|
tags:
|
||||||
|
- "*"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
GO_VERSION: "1.22"
|
GO_VERSION: "1.22"
|
||||||
|
REGISTRY: git.shts.su
|
||||||
|
IMAGE_REPO: ${{ gitea.repository }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
timeout-minutes: 10
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
@@ -24,38 +31,70 @@ jobs:
|
|||||||
- name: Test
|
- name: Test
|
||||||
run: go mod tidy && go test ./...
|
run: go mod tidy && go test ./...
|
||||||
|
|
||||||
docker:
|
build-and-push:
|
||||||
needs: test
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
needs: test
|
||||||
|
timeout-minutes: 20
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 1
|
||||||
|
|
||||||
- name: Build image
|
- name: Set up Docker Buildx
|
||||||
run: docker build -t telemt-api:ci .
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
driver-opts: |
|
||||||
|
image=moby/buildkit:v0.13.2
|
||||||
|
|
||||||
- name: Push to registry
|
- name: Log in to Gitea Registry
|
||||||
if: github.event_name == 'push'
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ gitea.actor }}
|
||||||
|
password: ${{ secrets.ACTIONS_PAT }}
|
||||||
|
|
||||||
|
- name: Prepare Docker tags
|
||||||
|
id: prep
|
||||||
|
shell: bash
|
||||||
env:
|
env:
|
||||||
REGISTRY_IMAGE: ${{ secrets.REGISTRY_IMAGE }}
|
REPO: ${{ gitea.repository }}
|
||||||
REGISTRY_URL: ${{ secrets.REGISTRY_URL }}
|
SHA: ${{ gitea.sha }}
|
||||||
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
REF_NAME: ${{ gitea.ref_name }}
|
||||||
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
|
||||||
run: |
|
run: |
|
||||||
set -e
|
set -euo pipefail
|
||||||
if [ -z "$REGISTRY_IMAGE" ] || [ -z "$REGISTRY_URL" ] || [ -z "$REGISTRY_USER" ] || [ -z "$REGISTRY_PASSWORD" ]; then
|
IMAGE="${REGISTRY}/${REPO}"
|
||||||
echo "Registry secrets not set (REGISTRY_IMAGE, REGISTRY_URL, REGISTRY_USER, REGISTRY_PASSWORD) — push skipped."
|
BRANCH_OR_TAG="${REF_NAME:-unknown}"
|
||||||
exit 0
|
SAFE_REF="$(echo "${BRANCH_OR_TAG}" | tr '/' '-')"
|
||||||
fi
|
SHORT_SHA="$(echo "${SHA}" | cut -c1-12)"
|
||||||
echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY_URL" -u "$REGISTRY_USER" --password-stdin
|
|
||||||
docker tag telemt-api:ci "${REGISTRY_IMAGE}:sha-${GITHUB_SHA}"
|
TAGS="$(printf '%s\n%s\n%s\n' \
|
||||||
docker push "${REGISTRY_IMAGE}:sha-${GITHUB_SHA}"
|
"${IMAGE}:latest" \
|
||||||
if [ "${GITHUB_REF}" = "refs/heads/main" ] || [ "${GITHUB_REF}" = "refs/heads/master" ]; then
|
"${IMAGE}:${SAFE_REF}" \
|
||||||
docker tag telemt-api:ci "${REGISTRY_IMAGE}:latest"
|
"${IMAGE}:sha-${SHORT_SHA}")"
|
||||||
docker push "${REGISTRY_IMAGE}:latest"
|
|
||||||
fi
|
echo "tags<<EOF" >> "${GITHUB_OUTPUT}"
|
||||||
if echo "${GITHUB_REF}" | grep -q '^refs/tags/'; then
|
echo "${TAGS}" >> "${GITHUB_OUTPUT}"
|
||||||
TAG="${GITHUB_REF#refs/tags/}"
|
echo "EOF" >> "${GITHUB_OUTPUT}"
|
||||||
docker tag telemt-api:ci "${REGISTRY_IMAGE}:${TAG}"
|
|
||||||
docker push "${REGISTRY_IMAGE}:${TAG}"
|
- name: Build and push Docker image
|
||||||
fi
|
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=telemt-api-gateway
|
||||||
|
org.opencontainers.image.description=HTTP gateway with IP whitelist and Telemt Control API proxy by alias
|
||||||
|
org.opencontainers.image.revision=${{ gitea.sha }}
|
||||||
|
org.opencontainers.image.source=${{ gitea.server_url }}/${{ gitea.repository }}
|
||||||
|
provenance: false
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# telemt-api
|
||||||
|
|
||||||
|
HTTP‑шлюз на Go для [Telemt Control API](docs/API.md): один порт, **белый список IP (CIDR)**, маршруты вида `/api/{alias}/…` → `{base_url}/v1/…`, метрики Prometheus на `/metrics`.
|
||||||
|
|
||||||
|
## Быстрый старт (Linux)
|
||||||
|
|
||||||
|
Предполагается установлены Docker и Docker Compose v2.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone <url-репозитория> && cd telemt-api
|
||||||
|
cp config.example.yaml config.yaml
|
||||||
|
# отредактируйте config.yaml: servers, whitelist_cidrs или allow_all для разработки
|
||||||
|
docker build -t telemt-api-gateway:local .
|
||||||
|
docker run -d --name telemt-gateway \
|
||||||
|
-p 8080:8080 \
|
||||||
|
-v "$(pwd)/config.yaml:/etc/telemt-gateway/config.yaml:ro" \
|
||||||
|
-e CONFIG_PATH=/etc/telemt-gateway/config.yaml \
|
||||||
|
telemt-api-gateway:local
|
||||||
|
curl -sS http://127.0.0.1:8080/health
|
||||||
|
curl -sS http://127.0.0.1:8080/api/main_srv/health
|
||||||
|
```
|
||||||
|
|
||||||
|
Или через Compose (пример конфига смотрите в `config.compose.yaml`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d --build
|
||||||
|
docker compose logs -f gateway
|
||||||
|
```
|
||||||
|
|
||||||
|
## Документация
|
||||||
|
|
||||||
|
| Документ | Содержание |
|
||||||
|
|----------|------------|
|
||||||
|
| **[docs/GATEWAY_RUN.md](docs/GATEWAY_RUN.md)** | Полная инструкция: конфиг, Docker CLI, Compose, CI/CD, неполадки |
|
||||||
|
| **[docs/API.md](docs/API.md)** | Контракт Telemt Control API (`/v1/…`) |
|
||||||
|
|
||||||
|
## Сборка и тесты без Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go mod tidy && go test ./...
|
||||||
|
```
|
||||||
|
|
||||||
|
## CI/CD
|
||||||
|
|
||||||
|
В репозитории: [.gitea/workflows/docker.yaml](.gitea/workflows/docker.yaml) — тесты Go, сборка и публикация образа в Container Registry Gitea (см. раздел «Обновление и CI/CD» в [docs/GATEWAY_RUN.md](docs/GATEWAY_RUN.md)).
|
||||||
+1
-1
@@ -1,9 +1,9 @@
|
|||||||
# Пример для docker compose: без whitelist (только для локальной проверки).
|
# Пример для docker compose: без whitelist (только для локальной проверки).
|
||||||
|
# На Linux в docker-compose.yml задано extra_hosts host.docker.internal:host-gateway.
|
||||||
listen: ":8080"
|
listen: ":8080"
|
||||||
allow_all: true
|
allow_all: true
|
||||||
whitelist_cidrs: []
|
whitelist_cidrs: []
|
||||||
trusted_proxies: []
|
trusted_proxies: []
|
||||||
servers:
|
servers:
|
||||||
- alias: main_srv
|
- alias: main_srv
|
||||||
# Telemt на хосте Windows/macOS/Linux:
|
|
||||||
base_url: http://host.docker.internal:9091
|
base_url: http://host.docker.internal:9091
|
||||||
|
|||||||
@@ -8,3 +8,6 @@ services:
|
|||||||
- ./config.compose.yaml:/etc/telemt-gateway/config.yaml:ro
|
- ./config.compose.yaml:/etc/telemt-gateway/config.yaml:ro
|
||||||
environment:
|
environment:
|
||||||
CONFIG_PATH: /etc/telemt-gateway/config.yaml
|
CONFIG_PATH: /etc/telemt-gateway/config.yaml
|
||||||
|
# Доступ к Telemt на хосте Linux (host.docker.internal в config.compose.yaml):
|
||||||
|
extra_hosts:
|
||||||
|
- "host.docker.internal:host-gateway"
|
||||||
|
|||||||
+23
-21
@@ -84,49 +84,52 @@ servers:
|
|||||||
|
|
||||||
В каталоге репозитория:
|
В каталоге репозитория:
|
||||||
|
|
||||||
```powershell
|
```bash
|
||||||
docker build -t telemt-api-gateway:local .
|
docker build -t telemt-api-gateway:local .
|
||||||
```
|
```
|
||||||
|
|
||||||
## Запуск через Docker CLI
|
## Запуск через Docker CLI
|
||||||
|
|
||||||
Пример для PowerShell (подставьте путь к своему `config.yaml`):
|
Пример для Linux (подставьте путь к `config.yaml`; ниже — файл из текущего каталога):
|
||||||
|
|
||||||
```powershell
|
```bash
|
||||||
docker run -d --name telemt-gateway `
|
docker run -d --name telemt-gateway \
|
||||||
-p 8080:8080 `
|
-p 8080:8080 \
|
||||||
-v "C:\path\to\config.yaml:/etc/telemt-gateway/config.yaml:ro" `
|
-v "$(pwd)/config.yaml:/etc/telemt-gateway/config.yaml:ro" \
|
||||||
-e CONFIG_PATH=/etc/telemt-gateway/config.yaml `
|
-e CONFIG_PATH=/etc/telemt-gateway/config.yaml \
|
||||||
telemt-api-gateway:local
|
telemt-api-gateway:local
|
||||||
```
|
```
|
||||||
|
|
||||||
Проверка:
|
Проверка:
|
||||||
|
|
||||||
```powershell
|
```bash
|
||||||
Invoke-WebRequest -Uri http://127.0.0.1:8080/health -UseBasicParsing
|
curl -sS -i http://127.0.0.1:8080/health
|
||||||
Invoke-WebRequest -Uri http://127.0.0.1:8080/api/main_srv/health -UseBasicParsing
|
curl -sS -i http://127.0.0.1:8080/api/main_srv/health
|
||||||
```
|
```
|
||||||
|
|
||||||
Второй запрос проксируется на `{base_url}/v1/health` для alias `main_srv`.
|
Второй запрос проксируется на `{base_url}/v1/health` для alias `main_srv`.
|
||||||
|
|
||||||
Остановка и удаление:
|
Остановка и удаление:
|
||||||
|
|
||||||
```powershell
|
```bash
|
||||||
docker stop telemt-gateway
|
docker stop telemt-gateway
|
||||||
docker rm telemt-gateway
|
docker rm telemt-gateway
|
||||||
```
|
```
|
||||||
|
|
||||||
## Запуск через Docker Compose
|
## Запуск через Docker Compose
|
||||||
|
|
||||||
В репозитории есть [docker-compose.yml](../docker-compose.yml) и пример [config.compose.yaml](../config.compose.yaml) с `allow_all: true` и `base_url: http://host.docker.internal:9091` (Telemt на хосте).
|
В репозитории есть [docker-compose.yml](../docker-compose.yml) и пример [config.compose.yaml](../config.compose.yaml) с `allow_all: true` и `base_url: http://host.docker.internal:9091` (Telemt на хосте; на Docker Desktop для Linux это обычно работает из коробки).
|
||||||
|
|
||||||
```powershell
|
```bash
|
||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
docker compose logs -f gateway
|
docker compose logs -f gateway
|
||||||
docker compose down
|
docker compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
На старых Linux‑хостах, где нет `host.docker.internal`, замените `base_url` на IP хоста или добавьте сервис Telemt в тот же `docker-compose` и укажите его DNS‑имя.
|
На Linux без `host.docker.internal` сделайте одно из:
|
||||||
|
|
||||||
|
- в `docker-compose.yml` для сервиса `gateway` добавьте `extra_hosts: ["host.docker.internal:host-gateway"]` (Docker Engine 20.10+);
|
||||||
|
- либо замените в `config.compose.yaml` значение `base_url` на IP хоста в docker‑bridge (часто `172.17.0.1`) или на имя сервиса Telemt в той же сети compose.
|
||||||
|
|
||||||
## Проверка
|
## Проверка
|
||||||
|
|
||||||
@@ -143,17 +146,16 @@ docker compose down
|
|||||||
|
|
||||||
- **Образ**: пересоберите тег или подтяните новый из registry, затем `docker compose up -d --build` или `docker stop` / `docker run ...` с тем же volume конфига.
|
- **Образ**: пересоберите тег или подтяните новый из registry, затем `docker compose up -d --build` или `docker stop` / `docker run ...` с тем же volume конфига.
|
||||||
- **Конфиг**: отредактируйте файл на хосте и перезапустите контейнер (шлюз не перечитывает конфиг на лету).
|
- **Конфиг**: отредактируйте файл на хосте и перезапустите контейнер (шлюз не перечитывает конфиг на лету).
|
||||||
- **Gitea Actions**: workflow [.gitea/workflows/docker.yaml](../.gitea/workflows/docker.yaml) выполняет `go test` и собирает Docker‑образ. Для пуша в registry задайте secrets:
|
- **Gitea Actions**: workflow [.gitea/workflows/docker.yaml](../.gitea/workflows/docker.yaml) сначала выполняет `go mod tidy && go test ./...`, затем собирает образ через Buildx и пушит в Container Registry Gitea.
|
||||||
|
|
||||||
- `REGISTRY_IMAGE` — полное имя образа без тега, например `git.example.com/owner/telemt-api-gateway`
|
- В репозитории должен быть secret **`ACTIONS_PAT`** — personal access token пользователя с правом **`write:package`** (и при необходимости `read:package`), как для обычного `docker login` к registry.
|
||||||
- `REGISTRY_URL` — хост registry, например `git.example.com`
|
- Логин в registry: пользователь **`gitea.actor`** (кто запустил workflow), пароль — этот PAT.
|
||||||
- `REGISTRY_USER` / `REGISTRY_PASSWORD`
|
- Хост registry задаётся в workflow в `env.REGISTRY` (по умолчанию `git.shts.su`); при другом инстансе Gitea измените значение в `.gitea/workflows/docker.yaml`.
|
||||||
|
- Теги образа: `latest`, имя ветки/тега (с `/` заменённым на `-`), и `sha-<первые 12 символов коммита>`. Полный путь: `{REGISTRY}/{gitea.repository}:<тег>`.
|
||||||
Если secrets не заданы, образ только собирается в runner без push.
|
|
||||||
|
|
||||||
## Устранение неполадок
|
## Устранение неполадок
|
||||||
|
|
||||||
- **`403 forbidden` с хоста при `allow_all: false`**: добавьте CIDR клиента в `whitelist_cidrs`. Запросы из контейнера к самому себе идут с `127.0.0.1` — при необходимости добавьте `127.0.0.1/32`.
|
- **`403 forbidden` с хоста при `allow_all: false`**: добавьте CIDR клиента в `whitelist_cidrs`. Запросы из контейнера к самому себе идут с `127.0.0.1` — при необходимости добавьте `127.0.0.1/32`.
|
||||||
- **За reverse proxy**: укажите CIDR прокси в `trusted_proxies`, иначе whitelist видит IP прокси, а не клиента.
|
- **За reverse proxy**: укажите CIDR прокси в `trusted_proxies`, иначе whitelist видит IP прокси, а не клиента.
|
||||||
- **`502 bad_gateway`**: проверьте `base_url`, DNS в Docker‑сети и то, что Telemt слушает API (`[server.api].enabled=true` и корректный `listen`).
|
- **`502 bad_gateway`**: проверьте `base_url`, DNS в Docker‑сети и то, что Telemt слушает API (`[server.api].enabled=true` и корректный `listen`).
|
||||||
- **Сборка Go без Docker**: выполните `go mod tidy && go test ./...` в корне репозитория.
|
- **Сборка Go без Docker**: в корне репозитория выполните `go mod tidy && go test ./...`.
|
||||||
|
|||||||
Reference in New Issue
Block a user