Skip to main content
Portless stores its runtime state in a state directory that contains route registrations, process IDs, port assignments, and TLS certificates. The location of this directory depends on whether the proxy is running on a privileged or non-privileged port.

Directory Location

Portless automatically selects the state directory based on the proxy port:

Non-Privileged Ports

Ports >= 1024 (default: 1355)Location: ~/.portlessUser-specific state. Each user has their own isolated state directory.

Privileged Ports

Ports < 1024 (e.g., 80, 443)Location: /tmp/portlessSystem-wide state. Shared between root and non-root processes to enable apps to register routes when the proxy runs as root.

Why Different Directories?

Privileged ports (below 1024) require root access to bind. When you run sudo portless proxy start -p 80, the proxy process runs as root. If apps running as your regular user need to register routes, they must write to a shared location accessible by both root and non-root processes. The solution: privileged ports use /tmp/portless (world-writable), while non-privileged ports use ~/.portless (user-specific).

Directory Contents

The state directory contains the following files:

File Details

file
JSON array of active routes. Each route maps a hostname to a local port and process ID.Example:
This file is watched by the proxy and automatically reloaded when changed. Apps add and remove routes by writing to this file with file locking.
file
Contains the port number the proxy is listening on (e.g., 1355 or 80).Portless reads this file to discover which port to connect to when registering routes.
file
Contains the process ID of the running proxy server.Used by portless proxy stop to send a SIGTERM signal to the correct process.
file
Marker file that exists when the proxy is running with HTTPS/TLS enabled.Portless checks for this file to determine whether to use http:// or https:// URLs.
file
Contains stdout and stderr from the proxy when running in daemon mode (the default).Useful for debugging if the proxy fails to start.
file
The local Certificate Authority (CA) certificate, generated on first use of HTTPS mode.This CA is added to your system trust store so browsers trust certificates issued by it.
file
Wildcard certificate for *.localhost subdomains, signed by the local CA.This certificate is used by the proxy when serving HTTPS traffic.

Overriding the State Directory

You can override the automatic directory selection using the PORTLESS_STATE_DIR environment variable:
This is useful in scenarios where:
  • You want to isolate state for a specific project
  • You need consistent behavior regardless of the proxy port
  • You’re running in a containerized environment with specific mount points

State Discovery

When you run portless myapp npm start without the proxy running, Portless needs to discover whether a proxy exists and where its state is stored. The discovery process:
  1. Check PORTLESS_STATE_DIR: If set, use that directory and read proxy.port from it
  2. Check user directory (~/.portless): Read proxy.port and verify the proxy is actually listening
  3. Check system directory (/tmp/portless): Read proxy.port and verify the proxy is listening
  4. Fall back: Use the default port (from PORTLESS_PORT or 1355) and select the appropriate directory
This allows Portless to “just work” whether the proxy is running on the default port, a custom port, as root, or as your user.

Multi-User Considerations

When using privileged ports with /tmp/portless:
  • The directory and files are created with permissions allowing both root and non-root access
  • Apps running as different users can all register routes
  • File locking prevents race conditions when multiple apps modify routes.json simultaneously
  • The proxy automatically fixes file ownership after writing to ensure non-root processes can read them

Cleaning Up

To remove Portless state:
If you enabled hosts file syncing, also clean up /etc/hosts: