Overview
Static routes let you register a persistent mapping from a.localhost name to a port without starting a process through portless. This is useful for:
- Docker containers
- Services started outside portless
- Long-running background processes
- External databases or tools
- Services that don’t accept
PORTenvironment variable
portless run or portless <name> <command>, static routes don’t launch a child process - they just register a route in the proxy.
Quick Start
The alias Command
Basic Usage
1
Start your service
Start your service on a specific port:
2
Register the route
Create a static route:
3
Access via portless
Access your service via the registered name:
Command Reference
Use Cases
Docker Containers
Register Docker containers by their published port:Multiple Docker Services
Existing Development Server
If you have a server already running that doesn’t use thePORT environment variable:
Background Services
Register long-running services that you start manually:Third-Party Tools
Register dev tools with UIs:Docker Compose Integration
Use static routes with Docker Compose:Overwriting Routes
Force Flag
By default,portless alias fails if a route is already registered:
--force to overwrite:
Conflict Behavior
When a route conflict occurs, portless checks if the owning process is still alive:- Process is dead - Route is overwritten automatically (no
--forceneeded) - Process is alive - Requires
--forceto overwrite - Static route (PID 0) - Requires
--forceto overwrite
Removing Routes
Removing a route doesn’t stop the underlying service - it only removes the proxy mapping. The service continues running on its original port.
Combining with Dynamic Routes
You can mix static routes with dynamicportless run routes:
State Persistence
Static routes are stored in the routes file alongside dynamic routes:~/.portless/routes.json
- Static routes have
"pid": 0 - Dynamic routes have a real PID
State Directory
Routes are stored based on proxy port:- Port >= 1024:
~/.portless/routes.json - Port < 1024 (sudo):
/tmp/portless/routes.json
Wildcard Routing with Static Routes
Static routes support wildcard routing just like dynamic routes:Host header and can route internally based on the subdomain.
Real-World Workflows
Microservices Development
Full-Stack with Docker
Monorepo Development
Listing Routes
View all routes (both static and dynamic):(static) or (PID 0). Dynamic routes show the managing process PID.
Troubleshooting
Route Registered But Connection Refused
The route is registered, but the service isn’t running on the target port:Port Already in Use
If the port you want to use is taken:Route Conflict
If you see “already registered” errors:Service Not Receiving Requests
Make sure your service is:- Listening on the correct port
- Binding to 127.0.0.1 or 0.0.0.0 (not just localhost in some configurations)
- Not behind another proxy that might interfere
Limitations
No Process Management
Static routes don’t manage the lifecycle of the target service. You’re responsible for:- Starting the service
- Stopping the service
- Restarting on crashes
- Ensuring it’s listening on the correct port
portless run or portless <name> <command> instead.
No Automatic Port Assignment
Unlike dynamic routes, static routes require you to specify the port manually. There’s no auto-assignment.Stale Routes
If you register a static route but later stop the service without removing the route, the route remains registered. Requests will fail with “connection refused”. Clean up manually:Comparison: Static vs Dynamic Routes
Reserved Names
These names are reserved for portless subcommands and cannot be used directly:runaliashostslisttrustproxy