Skip to main content

Lightweight local development domain router with ASGI middleware support

Project description

🌐 Devhost

CI Release

Secure, flexible local domain routing for developers.

Devhost allows you to map subdomains of a base domain (default: localhost, e.g. myapp.localhost) to local app ports, with optional HTTPS and wildcard routing via Caddy and a Python backend.

Features

  • Map domains like app.localhostlocalhost:1234
  • Map domains to remote IPs (e.g. rpi.localhost192.168.1.100:8080)
  • HTTPS support via Caddy's internal CA (use --https)
  • Add/remove routes using a single CLI command
  • Wildcard reverse proxy using Python (FastAPI)
  • Custom base domain (e.g. hello.flask)
  • Supports macOS, Linux, and Windows (native PowerShell shim)

Benefits for Devs

  • No need to remember localhost:PORT combos
  • Clean and memorable dev URLs
  • HTTP by default; HTTPS available with --https
  • Works with any language/framework running locally

Quickstart

1. Clone the project

git clone https://github.com/Patoruzuy/devhost.git
cd devhost
python install.py --linux
devhost add hello 3000
devhost list
devhost remove hello

Visit hello.localhost in your browser.

Note: the devhost CLI is implemented in Python (cross-platform).

Installation Options

The installer supports various flags to customize the setup process:

Flag Description Platforms
--yes Accept all prompts automatically (non-interactive mode) All
--dry-run Show what would be done without making any changes All
--domain <name> Set custom base domain (default: localhost) All
--start-dns Automatically start DNS service (dnsmasq) macOS, Linux
--install-completions Install shell completions for bash/zsh macOS, Linux
--caddy Install and configure Caddy web server Windows
--clean Remove existing installation before reinstalling Windows

Cross-platform installer (uses the Python CLI):

python install.py --linux

macOS example:

python install.py --macos --yes --start-dns --install-completions

Windows example (PowerShell):

python .\install.py --windows --caddy

To change the base domain (for example, hello.flask), set it once and re-run your installer to update DNS/resolvers:

devhost domain flask
python install.py --domain flask

Run the router locally (development):

cd router
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
uvicorn app:app --host 127.0.0.1 --port 5555 --reload

Run the router in Docker (quick):

docker compose up --build -d
# then open http://127.0.0.1:5555 with Host header set to <name>.localhost

docker-compose.yml mounts the repo devhost.json into the container so edits take effect immediately.

Notes & safety

  • install.py handles Linux/macOS/Windows and will prompt you about DNS changes. Review DNS/resolver changes before applying them on systems using systemd-resolved.
  • We now generate the project caddy/Caddyfile, the user ~/.config/caddy/Caddyfile, and (if present) /etc/caddy/Caddyfile to keep system Caddy installs in sync.
  • The router loads devhost.json per request so CLI changes take effect immediately without restarting the router.

Quick Commands

  • devhost add <name> <port|host:port> — add a mapping (e.g. devhost add hello 3000).
  • devhost add <name> <ip:port> — add remote IP mapping (e.g. devhost add rpi 192.168.1.100:8080).
  • devhost add <name> --http <port|host:port> — force HTTP when opening the dev URL.
  • devhost add <name> --https <port|host:port> — force HTTPS when opening the dev URL.
  • devhost remove <name> — remove a mapping.
  • devhost list — show active mappings.
  • devhost list --json — show mappings as JSON.
  • devhost url <name> — print the URL and press Ctrl+O to open it in the browser.
  • devhost open <name> — open the URL in the default browser.
  • devhost validate — quick health checks (config JSON, router health, DNS).
  • devhost export caddy — print the generated Caddyfile to stdout.
  • devhost edit — open devhost.json in $EDITOR (fallback: nano/vi).
  • devhost resolve <name> — show DNS resolution and port reachability for a mapping.
  • devhost doctor — deeper diagnostics (dnsmasq/systemd-resolved/Caddy).
  • devhost doctor --windows — Windows-specific diagnostics (Caddy, port 80, hosts).
  • devhost doctor --windows --fix — attempt Windows fixes (hosts sync + free port 80 + start Caddy).
  • devhost info — show all commands and usage.
  • devhost status --json — print router status as JSON (running, pid, health).
  • devhost domain [name] — show or set the base domain (default: localhost).
  • devhost hosts sync — re-apply hosts entries for all mappings on Windows (admin).
  • devhost hosts clear — remove all devhost entries from the Windows hosts file (admin).
  • devhost caddy start|stop|restart|status — manage Caddy on Windows.
  • devhost fix-http — convert all https:// mappings to http:// and regenerate Caddyfile.

Remote IP Support

Devhost supports mapping domains to devices on your local network, not just localhost ports. This is perfect for:

  • Raspberry Pi projects
  • IoT devices
  • Other computers on your network
  • Docker containers with bridge networking

Examples

Raspberry Pi running a web server:

devhost add rpi 192.168.1.100:8080
# Access at http://rpi.localhost

Network attached storage (NAS) web interface:

devhost add nas 192.168.1.50:5000
devhost open nas  # Opens http://nas.localhost

Remote development server:

devhost add staging 10.0.0.25:3000
# Access at http://staging.localhost

Docker container with bridge network:

devhost add docker 172.17.0.2:8080

Configuration Format

Remote IPs can be added in several formats:

  • 192.168.1.100:8080 - Full IP with port
  • 10.0.0.25:3000 - Any valid IPv4 address
  • Combined with other targets in devhost.json:
{
  "hello": 3000,
  "api": 8000,
  "rpi": "192.168.1.100:8080",
  "nas": "192.168.1.50:5000"
}

Notes

  • The remote device must be reachable from your machine
  • Ensure firewalls allow traffic to the target port
  • IP addresses are validated when adding routes
  • Use devhost resolve <name> to test connectivity

Configuration

The project uses a devhost.json file (project root) with a simple mapping of names to ports. Example:

{
	"hello": 3000,
	"api": 8000
}

This file is created/updated by the CLI and is meant to be local (it’s gitignored). The router reads DEVHOST_CONFIG if set; otherwise it looks for the project root devhost.json (even when run from router/). The base domain comes from DEVHOST_DOMAIN or .devhost/domain (default: localhost).

Router endpoints

  • GET /health — liveness + route count + uptime.
  • GET /metrics — basic request metrics (totals, per-status, per-subdomain).
  • GET /routes — current routes with parsed targets.
  • GET /mappings — current routes with basic TCP health checks.

Logging

  • DEVHOST_LOG_LEVEL controls router log verbosity (default: INFO).
  • DEVHOST_LOG_FILE writes logs to a file in addition to stdout.
  • DEVHOST_LOG_REQUESTS=1 enables per-request logging.

Quick test (curl)

Run the router (locally or via Docker) and test with curl by setting the Host header:

curl -H "Host: hello.localhost" http://127.0.0.1:5555/

Regenerating Caddyfile

The devhost CLI writes both the project caddy/Caddyfile (generated, gitignored) and, when present, the user ~/.config/caddy/Caddyfile. Inspect generated files before reloading system Caddy and, when appropriate, reload the service:

# inspect
less caddy/Caddyfile
# if using system Caddy (Linux)
sudo systemctl reload caddy

Troubleshooting

General Issues

  • Check mappings: devhost list - Verify your routes are configured correctly.
  • Router health: curl http://127.0.0.1:5555/health should return { "status": "ok" }.
  • Check router logs: Look for request IDs in logs to trace specific requests (X-Request-ID header).
  • Validate setup: devhost validate - Quick health checks for config, router, and DNS.
  • Deep diagnostics: devhost doctor - Comprehensive system diagnostics.

DNS & Domain Issues

  • Linux DNS issues: Check systemd-resolved and /etc/resolv.conf for unintended changes.
  • macOS DNS issues: Verify /etc/resolver/<domain> file exists and contains nameserver 127.0.0.1.
  • Windows DNS issues: Wildcard DNS requires a local resolver like Acrylic DNS. Alternatively, use devhost hosts sync to add individual entries to hosts file.
  • Domain resolution: devhost resolve <name> - Show DNS resolution and port reachability.

Windows-Specific Issues

Hosts File Management

When to use hosts file (Windows only):

  • You don't have a wildcard DNS resolver installed (like Acrylic DNS)
  • You want individual domain entries instead of wildcard DNS
  • Testing specific routes without full DNS setup

Admin elevation required:

  • devhost hosts sync - Adds/updates all routes in C:\Windows\System32\drivers\etc\hosts (requires admin)
  • devhost hosts clear - Removes all devhost entries from hosts file (requires admin)

Admin NOT required:

  • devhost add/remove/list - Regular route management
  • devhost start/stop/status - Router process management
  • devhost validate - Health checks

The hosts file commands modify system files and therefore require administrator privileges. The CLI will automatically attempt to relaunch with elevation if needed.

Other Windows Issues

  • Port 80 conflicts: Run devhost doctor --windows to check what's using port 80.
  • Port 80 auto-fix: devhost doctor --windows --fix - Attempts to free port 80 and start Caddy.
  • Caddy not running: devhost caddy status - Check Caddy status.
  • Start Caddy: devhost caddy start - Start Caddy web server.
  • Windows diagnostics: devhost doctor --windows - Windows-specific checks.

HTTPS & Certificate Issues

  • Browser forcing HTTPS: Clear HSTS settings for the domain or change base domain (devhost domain devhost2).
  • Caddy not running: Ensure Caddy is running if you depend on system TLS (systemctl status caddy on Linux).
  • Convert to HTTP: devhost fix-http - Convert all HTTPS mappings to HTTP.

Remote IP Issues

  • Remote device unreachable: Verify the remote IP/port is accessible from your machine (curl http://192.168.1.100:8080).
  • Network firewall: Ensure firewall rules allow traffic to the remote device.
  • Wrong IP address: Check the device's current IP (devhost list to see configured IPs).

Platform notes

  • install.py targets Linux/macOS/Windows; it reads DEVHOST_DOMAIN or .devhost/domain to configure DNS for the base domain.
  • On Windows, run the installer from an elevated PowerShell if you want hosts entries updated automatically, or use a local DNS resolver (Acrylic) for wildcard domains.

Release notes

See CHANGELOG.md for the v1.0.0 release notes.

macOS installer

Run the Python installer to generate the LaunchAgent plist (from router/devhost-router.plist.tmpl), create /etc/resolver/<domain>, and optionally start dnsmasq via Homebrew:

# dry-run (print actions)
python install.py --macos --dry-run

# run interactively (will prompt for username and uvicorn path)
python install.py --macos

Non-interactive example (accept all prompts and start dnsmasq if available):

python install.py --macos --yes --start-dns

To use a custom base domain on macOS:

devhost domain flask
python install.py --macos --domain flask

Windows installer

Run the Python installer from PowerShell to prepare the venv, router deps, and initial config:

python .\install.py --windows --caddy
python .\devhost add hello 8000

To clean and reinstall:

python .\install.py --windows --clean

If you want a shortcut in PowerShell without typing python, use:

.\devhost.ps1 add hello 8000
.\devhost.ps1 start

Note: the router requires a Host header. Don’t browse http://127.0.0.1:5555 directly — use devhost open <name> or:

curl -H "Host: hello.localhost" http://127.0.0.1:5555/

Tip (Windows): if your app only listens on IPv4, Devhost uses `127.0.0.1` for numeric ports to avoid IPv6 `::1` connection errors.

Tip: On Windows, devhost.ps1 start will try to start Caddy (if installed) before starting the router.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

devhost-2.1.2.tar.gz (30.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

devhost-2.1.2-py3-none-any.whl (31.7 kB view details)

Uploaded Python 3

File details

Details for the file devhost-2.1.2.tar.gz.

File metadata

  • Download URL: devhost-2.1.2.tar.gz
  • Upload date:
  • Size: 30.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for devhost-2.1.2.tar.gz
Algorithm Hash digest
SHA256 b14b0d9536b449a42562b915176bc4b28deddba967eaf550ea6e6ae9876ae36a
MD5 dea396265d8d78328aebbecbcd8f9217
BLAKE2b-256 052753ef86ce8a5a84812599a5df4942231be79a485ab6eddd95f00858cc3b56

See more details on using hashes here.

Provenance

The following attestation bundles were made for devhost-2.1.2.tar.gz:

Publisher: publish.yml on Patoruzuy/Devhost

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file devhost-2.1.2-py3-none-any.whl.

File metadata

  • Download URL: devhost-2.1.2-py3-none-any.whl
  • Upload date:
  • Size: 31.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for devhost-2.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 57d003b0bc4727a34f4137c876ee6368bd62c53baa5ebe8dbe6757ea47293040
MD5 0d9dc56d7a6ea6a02033ed809d57c314
BLAKE2b-256 3815c95ab66958a5b0105cd7b8bf5e05b5be5f32982fa2eb95697c55b9aa59b3

See more details on using hashes here.

Provenance

The following attestation bundles were made for devhost-2.1.2-py3-none-any.whl:

Publisher: publish.yml on Patoruzuy/Devhost

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page