Зачем нужны best practices для туннелирования
Localhost tunnel — один из самых простых инструментов в арсенале разработчика: одна команда — и ваш локальный сервер доступен из интернета. Но простота обманчива. Неаккуратно настроенный туннель может раскрыть конфиденциальные данные, замедлить рабочий процесс или сломаться в разгар демонстрации клиенту. В 2026 году туннели стали стандартной частью разработки: команды используют их для тестирования вебхуков, preview-окружений в CI/CD, тестирования мобильных приложений и доступа к IoT-устройствам. Чем больше вы полагаетесь на туннели, тем важнее использовать их правильно.
Этот гайд содержит 20 best practices, разделённых на четыре категории: безопасность, производительность, командная работа и интеграция с CI/CD. Каждая практика включает конкретное действие, которое можно выполнить прямо сейчас. Примеры кода используют fxTunnel — open-source инструмент для туннелирования с поддержкой HTTP, TCP и UDP — но принципы применимы к любому решению.
Краткая справка: все 20 практик
Вот все практики одним взглядом. Используйте как чек-лист.
| # | Категория | Практика | Приоритет |
|---|---|---|---|
| 1 | Безопасность | Всегда используйте туннели с TLS-шифрованием | Критический |
| 2 | Безопасность | Останавливайте туннели, когда они не нужны | Критический |
| 3 | Безопасность | Никогда не пробрасывайте продакшен-данные | Критический |
| 4 | Безопасность | Валидируйте подписи вебхуков | Высокий |
| 5 | Безопасность | Используйте переменные окружения для токенов | Высокий |
| 6 | Безопасность | Выбирайте open-source инструменты | Средний |
| 7 | Безопасность | Обновляйте клиент | Средний |
| 8 | Производительность | Выбирайте правильный протокол туннеля | Высокий |
| 9 | Производительность | Используйте health check перед открытием туннеля | Высокий |
| 10 | Производительность | Выбирайте relay-сервер ближе к пользователям | Средний |
| 11 | Производительность | Мониторьте задержки и пропускную способность | Средний |
| 12 | Производительность | Используйте инспектор трафика для отладки | Высокий |
| 13 | Команда | Стандартизируйте запуск туннелей через wrapper-скрипт | Высокий |
| 14 | Команда | Документируйте URL туннелей в общих каналах | Средний |
| 15 | Команда | Используйте кастомные домены для стабильных URL | Средний |
| 16 | Команда | Отдельный туннель для каждого микросервиса | Высокий |
| 17 | CI/CD | Автоматизируйте создание туннелей в пайплайнах | Высокий |
| 18 | CI/CD | Генерируйте preview URL для каждого PR | Высокий |
| 19 | CI/CD | Запускайте E2E-тесты через URL туннеля | Средний |
| 20 | CI/CD | Автоматически закрывайте туннели | Критический |
Безопасность (практики 1-7)
Безопасность – это фундамент. Туннель создаёт точку входа из интернета в вашу локальную машину, и относиться к этому стоит так же серьёзно, как к продакшен-серверу. Тема шифрования подробнее раскрыта в статье TLS 1.3 в туннелировании.
Практика 1: Всегда используйте туннели с TLS-шифрованием
Каждый байт данных между вашей машиной и relay-сервером должен быть зашифрован. Без TLS любой участник сетевого пути — ваш провайдер, оператор Wi-Fi, атакующий — может прочитать ваш трафик. Это касается API-токенов, сессионных cookies и тел запросов.
fxTunnel шифрует все соединения через TLS 1.3 по умолчанию. Настраивать ничего не нужно:
# TLS работает автоматически — каждый туннель зашифрован
fxtunnel http 8080
# -> https://abc123.fxtun.dev (TLS 1.3)
Проверка версии TLS для любого туннеля:
# Проверяем версию TLS
openssl s_client -connect your-tunnel.fxtun.dev:443 2>/dev/null | grep "Protocol"
# -> Protocol : TLSv1.3
Действие: Если ваш текущий инструмент не шифрует трафик по умолчанию — переходите на тот, который шифрует.
Практика 2: Останавливайте туннели, когда они не нужны
Каждый запущенный туннель — это открытая дверь. Закончили работу — закройте его. Звучит очевидно, но забытые туннели — проблема номер один в командах, которые используют туннелирование ежедневно.
# Запустите туннель, поработайте, затем остановите
fxtunnel http 8080
# Нажмите Ctrl+C по завершении
# Для скриптовых туннелей используйте trap для гарантированной очистки
fxtunnel http 8080 &
TUNNEL_PID=$!
trap "kill $TUNNEL_PID 2>/dev/null" EXIT
Действие: Добавьте trap в каждый скрипт, запускающий туннель. Поставьте напоминание, если склонны забывать.
Практика 3: Никогда не пробрасывайте продакшен-данные
Туннель должен указывать на dev-сервер с тестовыми данными, тестовыми ключами API и тестовыми аккаунтами. Никогда не создавайте туннель к продакшен-базе данных, продакшен-API или сервису, работающему с реальными данными пользователей.
# Правильно: туннель к dev-серверу с тестовыми данными
DATABASE_URL="postgres://dev:dev@localhost:5432/testdb" npm run dev
fxtunnel http 3000
# Неправильно: туннель к продакшен-базе
# fxtunnel tcp 5432 # указывает на продакшен PostgreSQL — НИКОГДА ТАК НЕ ДЕЛАЙТЕ
Действие: Создайте чек-лист для команды, явно запрещающий создание туннелей к продакшен-сервисам.
Практика 4: Валидируйте подписи вебхуков
Даже при наличии TLS всегда проверяйте подписи вебхуков на сервере. Stripe, GitHub, Telegram и другие сервисы подписывают payload вебхуков. Валидация подписи гарантирует, что запрос действительно пришёл от ожидаемого сервиса, а не от атакующего, обнаружившего URL вашего туннеля.
# Запускаем туннель для тестирования вебхуков
fxtunnel http 8080
# -> https://wh-dev.fxtun.dev
# В коде сервера всегда проверяйте подпись:
# Stripe: stripe.webhooks.constructEvent(body, sig, secret)
# GitHub: crypto.timingSafeEqual(expectedSig, actualSig)
Гайд по тестированию вебхуков описывает полный процесс.
Действие: Добавьте валидацию подписи к каждому эндпоинту вебхуков до начала тестирования через туннель.
Практика 5: Используйте переменные окружения для токенов
Никогда не хардкодьте токены туннеля, API-ключи или секреты в скриптах и конфигурационных файлах. Используйте переменные окружения.
# Храните токен fxTunnel в переменной окружения
export FXTUNNEL_TOKEN="your-token-here"
# Клиент считывает его автоматически
fxtunnel http 8080
# В CI/CD используйте секреты
# GitHub Actions:
# env:
# FXTUNNEL_TOKEN: ${{ secrets.FXTUNNEL_TOKEN }}
Действие: Проверьте скрипты и конфиги на наличие захардкоженных токенов. Перенесите их в переменные окружения или менеджер секретов.
Практика 6: Выбирайте open-source инструменты
Open-source туннель позволяет проверить реализацию TLS, изучить обработку данных и провести аудит кодовой базы. С closed-source инструментом вы доверяете слову вендора. fxTunnel полностью открыт на GitHub — каждая строка кода доступна для аудита.
Статьи ngrok vs Cloudflare vs fxTunnel и обзор инструментов туннелирования сравнивают open-source и закрытые решения бок о бок.
Действие: Проверьте, является ли ваш текущий инструмент для туннелирования open-source. Если нет — оцените альтернативы.
Практика 7: Обновляйте клиент
Каждый релиз fxTunnel включает обновлённый runtime Go с последними патчами безопасности для crypto/tls. Устаревшие клиенты могут содержать известные уязвимости.
# Обновляем fxTunnel до последней версии
curl -fsSL https://fxtun.dev/install.sh | bash
# Или через Go
go install github.com/mephistofox/fxtun.dev/cmd/fxtunnel@latest
# Проверяем текущую версию
fxtunnel --version
Действие: Поставьте ежемесячное напоминание для обновления клиента. В CI/CD всегда устанавливайте последнюю версию.
Производительность (практики 8-12)
Туннель добавляет задержку, потому что трафик проходит через relay-сервер. Эти практики помогут минимизировать накладные расходы и получить максимальную производительность.
Практика 8: Выбирайте правильный протокол туннеля
fxTunnel поддерживает три протокола: HTTP, TCP и UDP. Правильный выбор протокола убирает лишние накладные расходы.
# Веб-приложение — HTTP-туннель (оптимизирован для HTTP-трафика)
fxtunnel http 3000
# Доступ к базе данных — TCP-туннель
fxtunnel tcp 5432
# Игровой сервер или данные IoT-датчиков — UDP-туннель
fxtunnel udp 27015
HTTP-туннели оптимизированы для веб-серверов и API. TCP подходит для баз данных, SSH и других потоковых протоколов. UDP – для real-time нагрузок, чувствительных к задержкам. Различия подробно разобраны в статье «TCP и UDP туннелирование».
Действие: Проверьте свои команды запуска туннелей. Убедитесь, что используете правильный протокол для каждого сервиса.
Практика 9: Используйте health check перед открытием туннеля
Не запускайте туннель, пока приложение не готово принимать запросы. Туннель, указывающий на сервер, который ещё загружается, будет отдавать ошибки всем, кто зайдёт по URL.
#!/bin/bash
# start-with-tunnel.sh — запуск приложения, ожидание health check, затем туннель
# Запускаем приложение
npm run dev &
APP_PID=$!
# Ждём готовности приложения
echo "Ожидание запуска приложения..."
for i in $(seq 1 30); do
if curl -sf http://localhost:3000/health > /dev/null 2>&1; then
echo "Приложение готово."
break
fi
if [ "$i" -eq 30 ]; then
echo "Приложение не запустилось за 60 секунд."
kill $APP_PID 2>/dev/null
exit 1
fi
sleep 2
done
# Запускаем туннель
fxtunnel http 3000 &
TUNNEL_PID=$!
# Очистка при выходе
trap "kill $APP_PID $TUNNEL_PID 2>/dev/null" EXIT
wait $APP_PID
Действие: Оберните запуск туннеля в скрипт с ожиданием health check.
Практика 10: Выбирайте relay-сервер ближе к пользователям
Если вы показываете демо клиенту в Европе, а relay-сервер находится в Азии — каждый запрос добавляет 200+ мс задержки. В fxTunnel SaaS relay выбирается автоматически. Для self-hosted развёртываний размещайте сервер географически близко к тем, кто будет обращаться к туннелю.
# SaaS — выбор relay автоматический
fxtunnel http 8080
# Self-hosted — разверните сервер рядом с пользователями
fxtunnel server --listen :443 --tls-cert cert.pem --tls-key key.pem
Действие: Для self-hosted конфигураций разверните relay в том же регионе, где находится основная аудитория.
Практика 11: Мониторьте задержки и пропускную способность
Если туннель кажется медленным — измерьте. Простой тест с curl покажет, виноват ли туннель или ваше приложение.
# Измеряем время ответа через туннель
curl -o /dev/null -s -w "DNS: %{time_namelookup}s\nConnect: %{time_connect}s\nTLS: %{time_appconnect}s\nTotal: %{time_total}s\n" https://your-tunnel.fxtun.dev/api/health
# Сравниваем с прямым доступом к localhost
curl -o /dev/null -s -w "Total: %{time_total}s\n" http://localhost:8080/api/health
Разница между двумя измерениями — это накладные расходы туннеля. Обычно это 20-80 мс для правильно настроенного туннеля.
Действие: Добавьте измерение задержек в ваш workflow тестирования через туннель.
Практика 12: Используйте инспектор трафика для отладки
Встроенный инспектор трафика fxTunnel показывает каждый запрос и ответ, проходящие через туннель, в реальном времени. Это быстрее, чем настраивать отдельный прокси вроде mitmproxy или Charles.
# Запускаем туннель с инспектором
fxtunnel http 8080
# Инспектор доступен в дашборде fxTunnel
# Повтор конкретного запроса для отладки
# Используйте кнопку replay в интерфейсе инспектора
Инспектор показывает заголовки, тела, статус-коды и тайминги для каждого запроса. Replay позволяет повторно отправить запрос без повторного срабатывания оригинального события — идеально для отладки обработчиков вебхуков. Возможности инспектора подробно описаны в статье об отладке запросов.
Действие: Используйте инспектор вместо добавления debug-логов в приложение при устранении неполадок с туннелем.
Командная работа (практики 13-16)
Когда несколько разработчиков в команде используют туннели, координация становится важна. Эти практики предотвращают конфликты и путаницу.
Практика 13: Стандартизируйте запуск туннелей через wrapper-скрипт
Вместо того чтобы каждый разработчик запускал fxtunnel с разными флагами, создайте проектный wrapper-скрипт, стандартизирующий конфигурацию.
#!/bin/bash
# scripts/tunnel.sh — проектный запуск туннеля
# Использование: ./scripts/tunnel.sh [service] [port]
SERVICE=${1:-"web"}
PORT=${2:-"3000"}
# Проверяем, запущено ли приложение
if ! curl -sf http://localhost:$PORT/health > /dev/null 2>&1; then
echo "Ошибка: нет сервиса на порту $PORT"
echo "Сначала запустите: npm run dev"
exit 1
fi
echo "Запускаем туннель для $SERVICE на порту $PORT..."
fxtunnel http $PORT --log-file "/tmp/tunnel-${SERVICE}.log" &
TUNNEL_PID=$!
# Ждём URL
for i in $(seq 1 10); do
TUNNEL_URL=$(grep -oP 'https://[a-z0-9-]+\.fxtun\.dev' "/tmp/tunnel-${SERVICE}.log" 2>/dev/null || true)
if [ -n "$TUNNEL_URL" ]; then
echo "Туннель активен: $TUNNEL_URL -> localhost:$PORT"
break
fi
sleep 1
done
trap "kill $TUNNEL_PID 2>/dev/null; echo 'Туннель остановлен.'" EXIT
wait $TUNNEL_PID
Добавьте этот скрипт в репозиторий, чтобы каждый член команды использовал единый workflow.
Действие: Создайте scripts/tunnel.sh в проекте и закоммитьте его в репозиторий.
Практика 14: Документируйте URL туннелей в общих каналах
Когда вы открываете туннель для демо или ревью, отправьте URL в Slack-канал команды (или аналогичный). Укажите, куда ведёт туннель, сколько он будет активен и кто его запустил.
Простой формат:
Туннель активен:
URL: https://abc123.fxtun.dev
Сервис: frontend (порт 3000)
Кто: @alice
Время: ~30 минут
Действие: Договоритесь о формате и канале, где публикуются URL туннелей.
Практика 15: Используйте кастомные домены для стабильных URL
Случайные поддомены вроде abc123.fxtun.dev меняются при каждом перезапуске туннеля. Для демо, QA и интеграций, которым нужен стабильный URL, используйте кастомный домен. fxTunnel поддерживает кастомные домены через любого DNS-провайдера на платных тарифах.
# С настроенным кастомным доменом
fxtunnel http 3000
# -> https://dev.yourcompany.com -> localhost:3000
Это особенно важно для OAuth callback URL, которые требуют фиксированного redirect URI. Гайд по OAuth callback описывает настройку пошагово.
Действие: Настройте кастомный домен для наиболее используемого туннеля, если вы на платном тарифе.
Практика 16: Отдельный туннель для каждого микросервиса
Если ваш проект состоит из нескольких сервисов (фронтенд, бэкенд API, воркер), создайте отдельный туннель для каждого вместо маршрутизации всего через один. Это упрощает отладку и делает URL предсказуемыми.
# Терминал 1: Фронтенд
fxtunnel http 3000
# -> https://fe-xyz.fxtun.dev
# Терминал 2: Бэкенд API
fxtunnel http 4000
# -> https://api-xyz.fxtun.dev
# Терминал 3: Админ-панель
fxtunnel http 5000
# -> https://admin-xyz.fxtun.dev
На бесплатном тарифе количество одновременных туннелей не ограничено. Платные тарифы добавляют именованные туннели с кастомными доменами.
Действие: Составьте карту ваших сервисов и назначьте каждому свой туннель.
CI/CD (практики 17-20)
Туннели в CI/CD-пайплайнах открывают preview-окружения, E2E-тестирование через реальные URL и автоматизированные тесты интеграции с вебхуками. Полный процесс описан в гайде по preview-окружениям.
Практика 17: Автоматизируйте создание туннелей в пайплайнах
Установите fxTunnel в CI-раннере и создавайте туннели программно. Это основа для всех CI/CD-workflow с туннелями.
# .github/workflows/tunnel-test.yml
name: Tunnel Integration Test
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Start application
run: |
docker compose up -d --build
for i in $(seq 1 30); do
curl -sf http://localhost:8080/health && break
sleep 2
done
- name: Install fxTunnel
run: curl -fsSL https://fxtun.dev/install.sh | bash
- name: Create tunnel
id: tunnel
run: |
fxtunnel http 8080 --log-file /tmp/tunnel.log &
echo "tunnel_pid=$!" >> "$GITHUB_OUTPUT"
sleep 5
TUNNEL_URL=$(grep -oP 'https://[a-z0-9-]+\.fxtun\.dev' /tmp/tunnel.log)
echo "url=$TUNNEL_URL" >> "$GITHUB_OUTPUT"
- name: Run tests against tunnel URL
run: |
curl -sf ${{ steps.tunnel.outputs.url }}/api/health
echo "Tunnel is working: ${{ steps.tunnel.outputs.url }}"
- name: Cleanup
if: always()
run: |
kill ${{ steps.tunnel.outputs.tunnel_pid }} || true
docker compose down
Действие: Добавьте шаг с туннелем в ваш CI-пайплайн и проверьте работу простым health check.
Практика 18: Генерируйте preview URL для каждого PR
Самый мощный сценарий использования туннелей в CI/CD: автоматические preview-окружения. Каждый pull request получает публичный URL с работающим приложением. Ревьюеры кликают по ссылке вместо того, чтобы локально переключаться на ветку.
# Ключевой шаг: комментарий с preview URL в PR
- name: Comment PR with preview URL
uses: actions/github-script@v7
with:
script: |
const url = '${{ steps.tunnel.outputs.url }}';
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `## Preview\n\n| | |\n|---|---|\n| **URL** | ${url} |\n| **Commit** | \`${context.sha.substring(0, 7)}\` |`,
});
Полный workflow с Docker Compose, очисткой и примерами для GitLab CI – в статье о preview-окружениях.
Действие: Настройте preview-окружение для самого активного репозитория.
Практика 19: Запускайте E2E-тесты через URL туннеля
Туннель даёт публичный HTTPS URL, который ведёт себя как реальный деплой. Используйте его для E2E-тестирования с Playwright, Cypress или Selenium.
# Запускаем туннель, затем E2E-тесты
fxtunnel http 3000 --log-file /tmp/tunnel.log &
sleep 5
TUNNEL_URL=$(grep -oP 'https://[a-z0-9-]+\.fxtun\.dev' /tmp/tunnel.log)
# Playwright
npx playwright test --base-url="$TUNNEL_URL"
# Cypress
npx cypress run --config baseUrl="$TUNNEL_URL"
Тестирование через URL туннеля ловит проблемы, которые тестирование на localhost пропускает: проблемы CORS, предупреждения о смешанном контенте, обработка TLS-сертификатов и реальное разрешение DNS.
Действие: Добавьте шаг E2E-тестирования через туннель в ваш CI-пайплайн.
Практика 20: Автоматически закрывайте туннели
Забытый туннель в CI — это и угроза безопасности, и пустая трата ресурсов. Всегда выполняйте очистку.
#!/bin/bash
# ci-tunnel-wrapper.sh — запуск туннеля с автоматической очисткой
cleanup() {
echo "Закрываем туннель..."
kill $TUNNEL_PID 2>/dev/null
docker compose down 2>/dev/null
}
trap cleanup EXIT INT TERM
# Запускаем сервисы и туннель
docker compose up -d --build
fxtunnel http 8080 --log-file /tmp/tunnel.log &
TUNNEL_PID=$!
# Ждём URL туннеля
sleep 5
TUNNEL_URL=$(grep -oP 'https://[a-z0-9-]+\.fxtun\.dev' /tmp/tunnel.log)
echo "Туннель: $TUNNEL_URL"
# Запускаем тесты или ждём ручной проверки
"$@"
# Очистка происходит автоматически через trap
В GitHub Actions используйте concurrency с cancel-in-progress: true и отдельный workflow очистки, срабатывающий при закрытии PR.
Действие: Убедитесь, что каждая CI-джоба, создающая туннель, также его уничтожает — даже при падении джобы.
Паттерны переменных окружения для работы с туннелями
Вот справочник по переменным окружения, упрощающим работу с туннелями в различных контекстах.
# Локальная разработка
export FXTUNNEL_TOKEN="your-token" # Токен для платных функций
export TUNNEL_PORT="8080" # Порт по умолчанию
export TUNNEL_LOG="/tmp/tunnel.log" # Путь к лог-файлу
# CI/CD (GitHub Actions)
# Сохраните FXTUNNEL_TOKEN как секрет репозитория
# Ссылайтесь в workflow:
# env:
# FXTUNNEL_TOKEN: ${{ secrets.FXTUNNEL_TOKEN }}
# Docker Compose
# Передайте URL туннеля как переменную окружения другим сервисам:
# environment:
# - API_URL=${TUNNEL_URL}
# .env файл (НЕ коммитьте в git)
FXTUNNEL_TOKEN=your-token
TUNNEL_PORT=8080
Добавьте .env в .gitignore, чтобы предотвратить случайный коммит токенов.
Выбор тарифа под ваш workflow
fxTunnel предлагает три уровня, соответствующих разным потребностям:
| Функция | Бесплатно | От $5/мес | От $10/мес |
|---|---|---|---|
| HTTP/TCP/UDP туннели | Без ограничений | До 5 именованных | 10+ именованных |
| Трафик и соединения | Без лимитов | Без лимитов | Без лимитов |
| Кастомные домены | Нет | Да (любой DNS) | Да (любой DNS) |
| Инспектор трафика | Нет | Да | Да |
| Replay | Нет | Да | Да |
| Подходит для | Соло-разработчик, тестирование | Небольшие команды, демо | Растущие команды, CI/CD |
Соло-разработчикам и для базового тестирования хватает бесплатного тарифа. Командам, которым нужны стабильные URL и отладка вебхуков, подойдёт тариф $5/мес. Если в CI/CD крутится 10+ туннелей, тариф $10/мес масштабируется под такой workflow.
Типичные анти-паттерны
Вот ошибки, которые мы видим регулярно. Избегайте их.
Анти-паттерн: туннель к продакшену
Никогда не создавайте туннель к продакшен-базе данных, API или сервису. Используйте исключительно тестовые окружения.
Анти-паттерн: токены в коде
Токены в исходном коде оказываются в истории git, логах CI и скриншотах. Всегда используйте переменные окружения или менеджер секретов.
Анти-паттерн: туннель 24/7
Туннель — это временный инструмент. Если нужен постоянный доступ, задеплойте приложение как положено, за обратным прокси с правильным TLS и мониторингом.
Анти-паттерн: один туннель на всё
Маршрутизация нескольких сервисов через один туннель превращает отладку в мучение. Используйте один туннель на сервис.
Анти-паттерн: игнорирование логов
Логи клиента туннеля содержат ошибки соединения, события переподключения и назначение URL. Читайте их, когда что-то идёт не так.
# Всегда используйте лог-файл для фоновых туннелей
fxtunnel http 8080 --log-file /tmp/tunnel.log &
# Проверяйте логи при отладке
tail -f /tmp/tunnel.log
Всё вместе: полная настройка проекта
Вот реальный пример, объединяющий несколько практик в единый workflow разработчика.
#!/bin/bash
# dev-tunnel-setup.sh — полный workflow для мультисервисного проекта
set -euo pipefail
# Конфигурация
FRONTEND_PORT=3000
BACKEND_PORT=4000
LOG_DIR="/tmp/tunnels"
mkdir -p "$LOG_DIR"
# Обработчик очистки
cleanup() {
echo "Останавливаем все туннели..."
kill $FE_TUNNEL_PID $BE_TUNNEL_PID 2>/dev/null || true
echo "Готово."
}
trap cleanup EXIT INT TERM
# Проверяем, запущены ли сервисы
echo "Проверяем сервисы..."
curl -sf http://localhost:$FRONTEND_PORT > /dev/null || { echo "Фронтенд не запущен на порту $FRONTEND_PORT"; exit 1; }
curl -sf http://localhost:$BACKEND_PORT/health > /dev/null || { echo "Бэкенд не запущен на порту $BACKEND_PORT"; exit 1; }
# Запускаем туннели
echo "Запускаем туннели..."
fxtunnel http $FRONTEND_PORT --log-file "$LOG_DIR/frontend.log" &
FE_TUNNEL_PID=$!
fxtunnel http $BACKEND_PORT --log-file "$LOG_DIR/backend.log" &
BE_TUNNEL_PID=$!
# Ждём URL
sleep 5
FE_URL=$(grep -oP 'https://[a-z0-9-]+\.fxtun\.dev' "$LOG_DIR/frontend.log" || echo "pending")
BE_URL=$(grep -oP 'https://[a-z0-9-]+\.fxtun\.dev' "$LOG_DIR/backend.log" || echo "pending")
echo ""
echo "========================================="
echo " Туннели активны"
echo "========================================="
echo " Фронтенд: $FE_URL -> localhost:$FRONTEND_PORT"
echo " Бэкенд: $BE_URL -> localhost:$BACKEND_PORT"
echo "========================================="
echo ""
echo "Нажмите Ctrl+C для остановки всех туннелей."
# Ждём
wait
Этот скрипт реализует health check (практика 9), использует лог-файлы (предотвращение анти-паттерна), разделяет туннели по сервисам (практика 16) и гарантирует очистку при выходе (практика 20).
FAQ
Сколько туннелей можно запустить одновременно на бесплатном тарифе?
Жёсткого лимита нет – запускайте столько, сколько нужно. Бесплатный тариф не ограничивает ни количество туннелей, ни трафик, ни соединения. Платные тарифы добавляют кастомные домены, инспектор трафика и replay начиная с $5/мес.
Стоит ли использовать туннель в продакшене?
Туннели заточены под разработку и тестирование. Продакшен-нагрузки лучше размещать за полноценным reverse proxy. Но для staging-окружений, внутренних инструментов и длительных демо платные тарифы (от $5/мес) поддерживают кастомные домены и стабильные туннели, которые хорошо справляются с такими задачами.
Как сделать URL туннеля стабильным между перезапусками?
По умолчанию при каждом запуске назначается новый случайный поддомен. Если нужен постоянный адрес – настройте кастомный домен через вашего DNS-провайдера (доступно на платных тарифах от $5/мес). Такой URL переживает перезапуски и переподключения.
Можно ли использовать туннели в CI/CD-пайплайнах?
Да – установите fxTunnel в CI-раннере, поднимите туннель в фоне, вытащите URL из лога и передайте его E2E-тестам или preview-окружению. В разделе CI/CD выше есть готовые скрипты для GitHub Actions.
Какая самая частая ошибка безопасности при работе с туннелями?
Забыть выключить туннель после окончания работы. Каждый активный туннель – открытая точка входа в вашу машину. Возьмите за привычку жать Ctrl+C по завершении сессии и используйте trap в скриптах, чтобы очистка происходила даже при сбое.