Skip to main content

Port Manager for Development Environments

Project description

Portman

Port Manager for Development Environments

Portman automatically manages port allocations across multiple git worktrees and development contexts, preventing port conflicts when running Docker services.

The Problem

When working on multiple branches or worktrees of the same project, Docker services (PostgreSQL, Redis, etc.) conflict on ports. You end up manually managing port assignments, which is error-prone and time-consuming.

Example: Running PostgreSQL on port 5432 in worktree A crashes when you start the same service in worktree B.

The Solution

Portman provides:

  • Automatic port allocation - Each worktree gets unique ports
  • Machine-wide uniqueness - No conflicts across any projects
  • Context-aware - Automatically detects your project and branch
  • direnv integration - Ports are automatically available as environment variables
  • Docker Compose discovery - Auto-detects services from docker-compose.yml
  • Zero configuration - Works out of the box

Installation

Using uv (recommended)

uv tool install portman-cli

Using pip

pip install portman-cli

From source

git clone https://github.com/jpoutrin/portman-cli.git
cd portman-cli
uv pip install -e .

Quick Start

1. Basic Usage

Book a port for a service in your current worktree:

portman book postgres

Get the allocated port:

portman get postgres
# Output: 5432

2. Auto-discovery from docker-compose.yml

If you have a docker-compose.yml file, Portman can automatically discover and book ports for all services:

portman book --auto

This scans your docker-compose.yml and allocates ports for each service.

For custom compose file names:

portman book --auto --compose-file docker-compose.prod.yml

3. direnv Integration (Recommended)

Add to your .envrc:

eval "$(portman export --auto)"

Then allow direnv:

direnv allow

Now your environment variables are automatically set:

echo $POSTGRES_PORT
# Output: 5432

echo $REDIS_PORT
# Output: 6379

When you switch worktrees, the ports change automatically!

Common Workflows

Working with Multiple Worktrees

# In worktree main
cd ~/projects/myapp-main
portman book postgres
portman get postgres
# Output: 5432

# In worktree feature
cd ~/projects/myapp-feature
portman book postgres
portman get postgres
# Output: 5433  (different port, no conflict!)

Using with Docker Compose

Update your docker-compose.yml to use environment variables:

services:
  postgres:
    image: postgres:15
    ports:
      - "${POSTGRES_PORT:-5432}:5432"

  redis:
    image: redis:7
    ports:
      - "${REDIS_PORT:-6379}:6379"

Then in your .envrc:

eval "$(portman export --auto)"

For custom compose files:

eval "$(portman export --auto --compose-file docker-compose.prod.yml)"

Working with Multiple Compose Files

If your project uses different compose files for different environments:

# Development environment
portman book --auto --compose-file docker-compose.dev.yml

# Production environment
portman book --auto --compose-file docker-compose.prod.yml

# Staging environment
portman book --auto --compose-file compose.staging.yaml

The --compose-file option works with both relative and absolute paths.

Manual Port Allocation

Prefer a specific port:

portman book postgres --port 5555

Book multiple services:

portman book postgres
portman book redis
portman book mongodb

List All Allocations

See all port allocations across all contexts:

portman list

See allocations for the current context only:

portman list --current

Clean Up

Release a specific service in the current context:

portman release postgres

Release all ports for the current context:

portman release --all

Remove allocations for deleted worktrees:

portman prune

Remove stale allocations (not accessed in 30 days):

portman prune --stale 30

Commands Reference

portman book

Book a port for a service.

# Book with auto-assigned port
portman book <service>

# Book with preferred port
portman book <service> --port <port>

# Auto-discover from docker-compose.yml
portman book --auto

# Auto-discover from custom compose file
portman book --auto --compose-file docker-compose.prod.yml
portman book --auto -f compose.staging.yaml

portman get

Get the allocated port for a service (for scripting).

portman get <service>

# With quiet output (just the port number)
portman get <service> --quiet

portman export

Export environment variables for direnv.

# Manual services
portman export postgres redis

# Auto-discover from docker-compose.yml
portman export --auto

# Auto-discover from custom compose file
portman export --auto --compose-file docker-compose.prod.yml

# With custom format
portman export postgres --format "POSTGRES_URL=postgresql://localhost:{port}/db"

portman list

List all port allocations.

# All contexts
portman list

# Current context only
portman list --current

# Show system ports
portman list --system

portman release

Release port allocations.

# Release specific service
portman release <service>

# Release all in current context
portman release --all

portman prune

Clean up orphaned or stale allocations.

# Dry run (show what would be removed)
portman prune --dry-run

# Remove orphaned allocations
portman prune

# Remove allocations not accessed in N days
portman prune --stale 30

# Force without confirmation
portman prune --force

portman init

Initialize direnv integration.

# Add export to .envrc
portman init

# Just show the command
portman init --print

portman config

Manage port ranges.

# Show current configuration
portman config --show

# Set port range for a service
portman config --set-range postgres:5400-5500

portman status

Show system information and diagnostics.

portman status

portman discover

Discover services from docker-compose files without booking them.

# Discover from standard compose files
portman discover

# Discover from custom compose file
portman discover --compose-file docker-compose.prod.yml
portman discover -f compose.staging.yaml

Shows what services would be booked with portman book --auto.

How It Works

  1. Context Detection: Portman generates a unique hash based on your project path and git worktree
  2. Database: Port allocations are stored in a SQLite database at ~/.local/share/portman/allocations.db
  3. Port Allocation:
    • Checks if port is already allocated for this context
    • Scans system for ports in use
    • Allocates from service-specific ranges (e.g., 5432-5532 for PostgreSQL)
    • Guarantees machine-wide uniqueness
  4. direnv Integration: Exports environment variables that update automatically when you switch directories

Configuration

Port ranges are configurable per service. Default ranges:

  • PostgreSQL: 5432-5532
  • Redis: 6379-6479
  • MongoDB: 27017-27117
  • MySQL: 3306-3406

Set custom ranges:

portman config --set-range postgres:5400-5500

Requirements

  • Python 3.10 or higher
  • Git (for context detection)
  • direnv (optional, for automatic environment variable management)

License

MIT

Contributing

Contributions are welcome! Please open an issue or pull request on GitHub.

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

portman_cli-1.1.0.tar.gz (64.2 kB view details)

Uploaded Source

Built Distribution

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

portman_cli-1.1.0-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

File details

Details for the file portman_cli-1.1.0.tar.gz.

File metadata

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

File hashes

Hashes for portman_cli-1.1.0.tar.gz
Algorithm Hash digest
SHA256 31ab93a1d362178ac6a2ac2c1d8df7dc9140905b2f29ca07d4674e1b064fdbac
MD5 e0e048c1ca1607953424b1556fef4408
BLAKE2b-256 e9909a415e43720f6fd416817e9dc6543a8b530f44c1375899be07f06642c6a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for portman_cli-1.1.0.tar.gz:

Publisher: release.yml on jpoutrin/portman-cli

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

File details

Details for the file portman_cli-1.1.0-py3-none-any.whl.

File metadata

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

File hashes

Hashes for portman_cli-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1cb077adfe1291e74b2588944da6b6e85c5da4d9877a51bbb6b92e0eaa58d7ed
MD5 5062c131cfbbc1d32ec7c8d728814ece
BLAKE2b-256 9d77e1eb047190c0eb5fbc36771a73adf8d92fcef003bb9ed882a1d8030b243d

See more details on using hashes here.

Provenance

The following attestation bundles were made for portman_cli-1.1.0-py3-none-any.whl:

Publisher: release.yml on jpoutrin/portman-cli

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