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.1.tar.gz (67.7 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.1-py3-none-any.whl (27.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: portman_cli-1.1.1.tar.gz
  • Upload date:
  • Size: 67.7 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.1.tar.gz
Algorithm Hash digest
SHA256 e809e33a848ca13e335b68f8778850768e67d32a50f790de7f1bd40233e9ff6f
MD5 6e50af83c5cb8af42b90c405ce22e6b7
BLAKE2b-256 5650c841dee1640a769e3e185ef2e3f9fa7797f33da9d97106ed72abb0b54001

See more details on using hashes here.

Provenance

The following attestation bundles were made for portman_cli-1.1.1.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.1-py3-none-any.whl.

File metadata

  • Download URL: portman_cli-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 27.1 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 cbc47ef3acebde9495ecb5462f8d54150c8a5b39a888474cbc3e0b39d426425a
MD5 131343d9357991f7572784d1ba2a53bb
BLAKE2b-256 f81c91e7d331b5d9c5da51e27c7a2c3794f2324d1541a844354db1ac36e3df3e

See more details on using hashes here.

Provenance

The following attestation bundles were made for portman_cli-1.1.1-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