Named URLs for every local service
You’re running Redis Commander on :8081, pgAdmin on :5050, Mailhog on :8025, and Sidekiq web on :9292. Four port numbers to remember, none of them HTTPS. Treeline’s router already maps branch names to ports — aliases let you route anything else through the same system.
The scenario
Your app has sidecars — database UIs, mail catchers, job queues, monitoring dashboards. Each one listens on its own port. You bookmark localhost:8081, but so does your teammate, and their Redis Commander is on :8083 because something else grabbed 8081. Port numbers are meaningless across machines. Named URLs aren't.
If the HTTPS router is running (set up during gtl install or via gtl serve install), giving a sidecar a name is one command. No extra infrastructure, no config files to share, no Docker networking.
Option A: Personal aliases (per machine)
Use gtl serve alias when the service is something you run locally that isn't part of the project config — your personal Grafana instance, a pgweb you installed via Homebrew, a monitoring tool on a custom port.
$ gtl serve alias redis-ui 8081
Alias redis-ui.prt.dev → :8081
The router will pick this up on next refresh (~5s).
That's it. Open https://redis-ui.prt.dev in your browser — trusted HTTPS, no port number, same certificate authority as your branch URLs.
# List all personal aliases
$ gtl serve alias
User aliases:
redis-ui → :8081
pgweb → :8082
grafana → :3100
# Remove an alias
$ gtl serve alias --remove redis-ui
Removed alias "redis-ui".
Personal aliases are stored in your user config (~/.config/git-treeline/config.json) under router.aliases:
{
"router": {
"aliases": {
"redis-ui": 8081,
"pgweb": 8082,
"grafana": 3100
}
}
} Option B: Project aliases (shared with your team)
When the sidecar is part of the project — everyone on the team needs a mail catcher, or the app ships with a Sidekiq dashboard — define the alias in .treeline.yml. The router picks up project-level aliases from every registered worktree automatically.
project: myapp
aliases:
mailhog: 8025
sidekiq: 9292
hooks:
post_setup:
- mailhog &
- bundle exec sidekiq &
After any teammate runs gtl setup or creates a worktree with gtl new, the router learns these aliases within ~5 seconds. Everyone on the team gets https://mailhog.prt.dev and https://sidekiq.prt.dev without any per-machine configuration.
This is the key difference: personal aliases live in your user config and travel with you. Project aliases live in .treeline.yml and travel with the repo. The router merges both.
What this looks like in practice
$ gtl serve status
Router: running on port 3001 (HTTPS)
CA: installed
Port forwarding: active (443 → router)
Routes (5):
https://myapp-main.prt.dev → :3002
https://myapp-feature-auth.prt.dev → :3012
Aliases (3):
https://mailhog.prt.dev → :8025 (project)
https://sidekiq.prt.dev → :9292 (project)
https://grafana.prt.dev → :3100 (user)
Branch URLs, project sidecars, and personal tools — all in one route table, all HTTPS, all named. The service doesn't need to know about Treeline. It just listens on a port. The router handles the rest.
When to use which
| Situation | Where to define it |
|---|---|
| Personal tool only you run (Grafana, pgweb) | gtl serve alias grafana 3100 |
| Sidecar the whole team needs (Mailhog, Sidekiq) | aliases: in .treeline.yml |
| Service managed by another GTL project | {resolve:…} — see multi-repo |
Read next
- Networking feature page — how
serve, proxy, tunnel, and share work together - Docs: networking — router install, status, hosts sync, and alias reference
- Why port 3000 stays free — the proxy facade for OAuth, Stripe, and CORS