Tunnel Magic: From Backend to User-Friendly Control Panel

Building Tunnel Management: From Scratch to Production-Ready UI
The borisovai-admin project needed a proper way for users to manage network tunnels without touching SSH configs. That’s where the week went—transforming tunnel management from a backend-only concern into a full-featured UI experience with proper API endpoints and infrastructure tooling.
First thing I did was assess what we were working with. The project already had frp (a fast reverse proxy) in the deployment pipeline, but there was no user-facing interface to control tunnels. So I built tunnels.html—a dedicated management page that lets administrators create, monitor, and tear down tunnels without diving into configuration files. Behind it, I implemented five new API endpoints in server.js to handle the full tunnel lifecycle: creation, deletion, status checking, and configuration updates.
The tricky part came when integrating frp itself. It wasn’t just about adding the reverse proxy to the codebase—I had to ensure it worked seamlessly across different deployment scenarios. This meant updating install-all.sh, creating a dedicated install-frps.sh script, and building a frpc-template that teams could customize for their infrastructure. Deployment needed to be idempotent and predictable.
But then Traefik threw a curveball. The reverse proxy was timing out on large file transfers, particularly when GitLab was pushing artifacts through it. A quick investigation revealed the readTimeout was set too low—just 300 seconds. I bumped it to 600 seconds and added a dedicated serversTransport configuration specifically for GitLab to handle chunked uploads properly. The configure-traefik.sh script now auto-generates both the gitlab-buffering policy and the transport config based on environment variables.
Navigation mattered too. Users needed to discover the new Tunnels feature, so I added a consistent “Tunnels” link across all admin pages. Small change, huge UX improvement.
Unexpectedly, this prompted a documentation overhaul. With more features scattered across the codebase, the docs needed restructuring. I reorganized docs/ into logical sections: agents/, dns/, plans/, setup/, and troubleshooting/. Each section now has clear entry points rather than users hunting through one giant README.
I also worked on server configuration management—consolidating Traefik, systemd, Mailu, and GitLab configs into config/contabo-sm-139/ so teams could version control their entire infrastructure setup. The upload-single-machine.sh script was enhanced to handle these server-level configurations, making it a proper IaC companion piece.
Here’s something worth knowing about Traefik timeouts: they’re not just about being patient. Timeout values cascade—connection timeout, read timeout, write timeout, and idle timeout all interact. A 600-second read timeout is generous for most use cases, but when you’re streaming large files through a proxy, you need to account for network variance and the fact that clients might pause between chunks. It’s why a blanket increase can seem like a hack, but context-specific configs (like our GitLab transport) are the real solution.
What started as “add a UI for tunnels” expanded into infrastructure-as-code thinking, better documentation, and more robust deployment scripts. That’s how real projects grow—one feature request becomes a small architecture rethinking session, and suddenly your whole system is more maintainable.
😄 Documentation is like sex: when it’s good, it’s very good. When it’s bad, it’s better than nothing.
Metadata
- Branch:
- main
- Dev Joke
- Разработчик: «Я знаю Storybook». HR: «На каком уровне?». Разработчик: «На уровне Stack Overflow».