Expose your local application to the public internet — no port forwarding, no NAT, no DNS setup.
Portal is a self-hosted relay network. You can connect to any relay or run your own.
Publishing a local service to the internet is often complicated. It usually requires opening inbound ports, configuring NAT or firewalls, managing DNS, and terminating TLS.
Portal removes this complexity by inverting the connection model. Applications establish outbound connections to a relay, which exposes the service to the public internet and routes incoming traffic back to the application while preserving end-to-end TLS.
Unlike other tunneling services, Portal is self-hosted and permissionless. You can run your own relay on your domain or connect to any relay.
- NAT-friendly connectivity: Works behind NAT or firewalls without opening inbound ports
- Automatic subdomain routing: Gives each app its own subdomain (
your-app.<base-domain>) - End-to-end encryption: Supports TLS passthrough with relay keyless certificates
- Permissionless Hosting: Anyone can run their own Portal — no approval needed
- One-Command Setup: Expose any local app with a single command
- UDP Relay (Experimental): Supports raw UDP relay use cases, but the transport model and operational behavior may still change
- Relay: A server that routes public requests to the right connected app.
- Tunnel: A CLI agent that proxies your local app through the relay.
git clone https://github.com/gosuda/portal
cd portal
docker compose upFor deployment to a public domain, see docs/deployment.md.
- Run your local service.
- Open the Portal relay site.
- Click
Add your serverbutton. - Use the generated command to connect your local service.
See portal-toys for more examples.
See docs/architecture.md. For architecture decisions, see docs/adr/README.md.
| Example | Description |
|---|---|
| nginx reverse proxy | Deploy Portal behind nginx with L4 SNI routing and TLS termination |
| nginx + multi-service | Run Portal alongside other web services behind a single nginx instance |
If you operate a public Portal relay, open a Pull Request to add your relay URL to registry.json. Keeping the registry updated makes public relays easier for the community to discover.
We welcome contributions from the community!
- Fork the repository
- Create a feature branch (git checkout -b feature/amazing-feature)
- Commit your changes (git commit -m 'Add amazing feature')
- Push to the branch (git push origin feature/amazing-feature)
- Open a Pull Request
MIT License — see LICENSE

