# Docker: образ mtproxy_checker ## Что внутри образа | Компонент | Описание | |-----------|----------| | **База runtime** | Alpine Linux 3.20 | | **Бинарник** | Статическая сборка Go (`CGO_ENABLED=0`), путь в контейнере: `/usr/local/bin/mtproxy_checker` | | **Сертификаты** | Пакет `ca-certificates` (для TLS к реальным хостам при необходимости) | | **ENTRYPOINT** | Тот же бинарник — все аргументы `docker run …` передаются в утилиту | | **Порты** | Ничего не слушает: только **исходящие** TCP до хоста и порта из ссылки | Одна команда `docker run` = **одна** проверка одного прокси; процесс завершается с **кодом выхода** (`0`…`4`), что удобно в CI и скриптах. ## Требования - [Docker Engine](https://docs.docker.com/engine/install/) (Linux) или Docker Desktop (Windows/macOS). - Для `docker pull` из приватного registry — логин и токен. ## Сборка образа локально **Linux / macOS:** ```bash cd /path/to/mtproxy_checker docker build -t mtproxy_checker:local . ``` **Windows (PowerShell):** ```powershell cd C:\path\to\mtproxy_checker docker build -t mtproxy_checker:local . ``` Проверка, что образ собран: ```bash docker run --rm mtproxy_checker:local -timeout 5s 2>&1 | head -1 # ожидается сообщение usage (код выхода 2 — нормально без URL) ``` ## Запуск под Linux ### Один прокси (ссылка `tg://`) ```bash docker run --rm mtproxy_checker:local \ 'tg://proxy?server=example.com&port=443&secret=eeYOURHEX...' ``` С флагами утилиты (таймаут, DC): ```bash docker run --rm mtproxy_checker:local \ -timeout 25s -dc-id 2 \ 'tg://proxy?server=example.com&port=443&secret=eeYOURHEX...' ``` Чтобы не светить секрет в истории shell, прочитайте его из файла и передайте флагами (образ запускает бинарник как `ENTRYPOINT`, отдельный `sh` без смены entrypoint использовать нельзя): ```bash SECRET=$(tr -d ' \n' < secret.hex) docker run --rm mtproxy_checker:local \ --server example.com --port 443 --secret "$SECRET" ``` ### Сеть и DNS на Linux - По умолчанию контейнер использует bridge Docker; нужен исходящий доступ к `server:port` и рабочий DNS. - Если имена не резолвятся: ```bash docker run --rm --dns 8.8.8.8 mtproxy_checker:local 'tg://proxy?...' ``` - Режим сети хоста (как на машине без NAT; используйте осознанно): ```bash docker run --rm --network host mtproxy_checker:local 'tg://proxy?...' ``` На Docker Desktop для Windows/macOS `--network host` ведёт себя иначе, чем на Linux. ## Несколько MTProxy ссылок подряд Утилита принимает **ровно один** прокси за запуск. Чтобы проверить много `tg://` ссылок, обходите их в оболочке. ### Вариант 1: цикл в bash ```bash IMAGE=mtproxy_checker:local # или registry/owner/mtproxy_checker:latest for url in \ 'tg://proxy?server=a.example.com&port=443&secret=ee1111...' \ 'tg://proxy?server=b.example.com&port=8443&secret=ee2222...' \ 'tg://proxy?server=c.example.com&port=443&secret=dd3333...' do echo "=== $url ===" if docker run --rm "$IMAGE" -timeout 20s "$url"; then echo "OK" else echo "FAIL (код $?)" fi done ``` ### Вариант 2: файл — одна ссылка на строку `proxies.txt` (пустые строки и строки с `#` в начале можно пропускать): ``` tg://proxy?server=one.example.com&port=443&secret=ee... tg://proxy?server=two.example.com&port=8443&secret=ee... ``` Скрипт: ```bash IMAGE=mtproxy_checker:local while IFS= read -r line || [ -n "$line" ]; do line="${line#"${line%%[![:space:]]*}"}" # trim leading spaces [ -z "$line" ] && continue case "$line" in \#*) continue ;; esac echo "=== $line ===" docker run --rm "$IMAGE" -timeout 20s "$line" && echo OK || echo "FAIL ($?)" done < proxies.txt ``` ### Вариант 3: параллельно (`xargs`) Осторожно: одновременно много контейнеров нагружают сеть и целевые прокси. ```bash IMAGE=mtproxy_checker:local grep -v '^\s*$\|^\s*#' proxies.txt | xargs -I{} -P 4 sh -c \ 'echo "=== {}"; docker run --rm '"$IMAGE"' -timeout 20s "{}" || echo FAIL' ``` `-P 4` — не более четырёх проверок одновременно; уменьшите при необходимости. ### Вариант 4: итоговый код для CI Если нужен «провал всего job при любом FAIL»: ```bash set -e IMAGE=mtproxy_checker:local while IFS= read -r url; do [ -z "$url" ] && continue case "$url" in \#*) continue ;; esac docker run --rm "$IMAGE" -timeout 25s "$url" done < proxies.txt ``` ## Запуск из PowerShell (Windows) Одинарные кавычки с `tg://` в PowerShell неудобны; проще двойные: ```powershell docker run --rm mtproxy_checker:local ` "tg://proxy?server=example.com&port=443&secret=eeYOURHEX..." ``` Несколько ссылок: ```powershell $urls = @( "tg://proxy?server=a.com&port=443&secret=ee...", "tg://proxy?server=b.com&port=8443&secret=ee..." ) foreach ($u in $urls) { Write-Host "=== $u ===" docker run --rm mtproxy_checker:local -timeout 20s $u if ($LASTEXITCODE -ne 0) { Write-Host "FAIL exit $LASTEXITCODE" } } ``` ## Загрузка образа из Container Registry Gitea 1. Включите **Packages / Container Registry** на инстансе Gitea ([документация](https://docs.gitea.com/usage/packages/container)). 2. Создайте токен с правом на пакеты. 3. Логин: ```bash docker login git.shts.su # или ваш registry ``` 4. Сборка workflow публикует теги `latest`, имя ветки/тега и `sha-…` — см. `.gitea/workflows/docker.yaml`. ```bash docker pull git.shts.su/owner/mtproxy_checker:latest docker run --rm git.shts.su/owner/mtproxy_checker:latest 'tg://proxy?...' ``` ## Пример docker-compose Одна проверка за `compose run`: ```yaml services: mtproxy-check: image: mtproxy_checker:local build: . command: ['tg://proxy?server=example.com&port=443&secret=ee...'] ``` ```bash docker compose run --rm mtproxy-check ``` Для списка прокси удобнее внешний bash-цикл или отдельный `command: ["sh","-c","..."]` с циклом по файлу, смонтированному в volume. ## Использование в CI другого проекта ```bash docker run --rm registry.example.com/owner/mtproxy_checker:latest \ "tg://proxy?server=${MTPROXY_HOST}&port=${MTPROXY_PORT}&secret=${MTPROXY_SECRET}" ``` ## Коды выхода и диагностика | Код | Значение | |-----|----------| | 0 | Проверка прошла | | 1 | Ошибка (сеть, протокол, неверный ответ) | | 2 | Неверные аргументы CLI | | 3 | Прокси закрыл TCP сразу после начального payload | | 4 | Общий таймаут (`-timeout`) | **Не путать с ping:** ICMP не используется. Типичные сообщения: - `connection refused` — порт закрыт или фильтр. - `FAIL: timeout` — нет ответа за `-timeout`. - Ошибки чтения/проверки ServerHello — несовместимый ответ или обрыв соединения. Для отладки без `--rm` можно посмотреть логи контейнера по id; с `--rm` контейнер удаляется сразу после выхода.