Таймлайн
24 дек ██ Первый прототип (3578 строк, HTTP/TCP/UDP)
25 дек ████████ Веб-панель, GUI, API, CI/CD, v1.0 (24000+ строк)
26 дек —
25 янв ░░░░░░░░ Месяц перерыва
26 янв ██ Деплой, IPv4/IPv6
27 янв ██ JWT auto-refresh, кастомная 404
28 янв ████ Полный редизайн GUI
29 янв ████████ Безопасность + тесты + race fixes + Docker
30 янв ██████ Производительность + инспекция трафика
Фактически — 7 рабочих дней. С месячным перерывом посередине.
Цифры
| Метрика | Значение |
|---|---|
| Go-код | 23 587 строк |
| Vue/TypeScript | 15 104 строки |
| Всего | ~38 700 строк |
| Коммитов | 179 |
| Релизов | 26 (от v1.0.0 до v1.14.0) |
| Первый коммит | 24 декабря 2025 |
| Последний | 30 января 2026 |
Что получилось
Полноценный self-hosted аналог ngrok: - 3 типа туннелей: HTTP (поддомены), TCP (порты), UDP - Кастомные домены с автоматическим TLS (Let's Encrypt) - Веб-панель с управлением пользователями, токенами, доменами - Десктопный GUI на Wails (15MB бинарник) - CLI-клиент под все платформы (Linux, macOS, Windows, ARM) - Инспекция трафика в реальном времени - Prometheus-метрики для мониторинга - Auto-deploy с откатом - Rate limiting, CORS, security-заголовки, interstitial - JWT + TOTP двухфакторка - Синхронизация настроек между устройствами Один сервер обслуживает всё: API, веб-панель, туннели, раздачу клиентов.
Что бы сделал иначе
Тесты с первого дня
Месяц без тестов — это месяц накопленного страха. «А если сломаю?» — и боишься трогать код. Когда добавил тесты — go test -race нашёл 20+ гонок. Они были там с первого дня.
Меньше, но чаще
Первый коммит GUI — 24 000 строк. Невозможно ревьюить, невозможно bisect'ить. Если бы заново — маленькие коммиты, каждый делает одну вещь.
CI перед кодом
Пять фиксов CI подряд — неприятно. Настрой линтер и тесты до первой строки кода. Или хотя бы запускай локально.
Дизайн-документы раньше
Инспекция трафика — единственная фича, начатая с дизайн-документа. И единственная, реализованная без переделок. Не совпадение.
Что работает хорошо
Go для сетевых сервисов
Горутины, каналы, net.Conn, io.Copy — всё заточено под сетевой код. Один бинарник, деплой копированием файла.
Wails для десктопа
15MB вместо 150MB Electron. Прямые биндинги Go → Vue. Есть шероховатости, но для такого проекта — то что нужно.
SQLite для self-hosted
Ноль администрирования. Файл рядом с бинарником. Бэкап = копирование файла.
release-please
Автоматические версии, changelog, GitHub Releases. Мержишь PR — релиз готов. 26 релизов, ни один вручную.
Открытые вопросы
- Горизонтальное масштабирование. Сейчас один сервер. Для моих нужд хватает. Для чего-то большего — нужен кластер.
- WebSocket-инспекция. HTTP-трафик инспектируется, WebSocket — пока нет.
- Плагины. Middleware для туннелей: basic auth, mock responses. Сделает fxTunnel инструментом для тестирования.
- Мобильный клиент. Wails пока не умеет мобильные платформы.
Главный вывод
Сначала сделай — потом улучшай. Первая версия была далека от идеала: монолитные коммиты, ноль тестов, отключённый линтер. Но она работала. И каждый следующий день делал её лучше. Можно бесконечно планировать идеальную архитектуру. А можно написать, выпустить и итерировать. Второй путь — быстрее. За 7 рабочих дней я сделал инструмент, которым пользуюсь каждый день. С нуля. Один. И мне нравится результат.
Все статьи серии: 1. Идея и первый прототип 2. От консоли к продукту за один день 3. Первый деплой и localhost 4. Auto-refresh, 404 и первая боевая фича 5. Полный редизайн GUI 6. Безопасность за один день 7. Тесты, гонки и паники 8. Выжимаем скорость 9. Инспекция трафика 10. Итоги (вы здесь) 11. Кастомные домены и автоматический TLS 12. Рефакторинг — разбиваем монолит 13. Полировка — graceful shutdown, авто-обновление и replay
fxTunnel — open source, self-hosted reverse tunneling. Один бинарник, ноль зависимостей, полный контроль.