Use cases

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.

add an alias

$ 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.

manage aliases

# 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:

config.json
{
  "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.

.treeline.yml
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

All use cases