Code Monkey home page Code Monkey logo

portman's Introduction

portman

portman transforms your local project URLs from http://localhost:8080 and http://localhost:3000 into pretty URLs like https://app.localhost and https://project.localhost.

portman has three components:

  1. The CLI lets you register projects and assign unique autogenerated ports to each one.
  2. The shell integration automatically sets the PORT environment variable when you cd into the project's directory.
  3. The caddy integration automatically generates a Caddyfile that caddy will use to reverse-proxy your localhost:* urls to https://*.localhost URLs.

Installation

# Install portman CLI
brew install canac/tap/portman

# Start caddy
brew services start caddy

# Install shell integration (pick one the right one for your shell)
# Note that fish shell integration is automatically installed if you installed portman via Homebrew
echo "eval $(portman init bash)" >> ~/.bashrc
echo "portman init fish | source" >> ~/.config/fish/config.fish
echo "eval $(portman init zsh)" >> ~/.zshrc

Basic usage

# Create a new project and autogenerate a unique port for it
cd /projects/app
portman create

# Check that the shell integration automatically set the $PORT
echo "Port is $PORT"

# Run the project's dev server how you normally would
npm run dev

# Open the app in the browser
open "https://app.localhost"

Linked ports

In addition assigning unique, autogenerated ports to projects, portman can also link running servers to a specific port and dynamically change which project links to that port while those servers are running.

Suppose that you have a work project that needs to be run at http://localhost:3000 because of OAuth configuration that is outside of your control. Further suppose that you have three git worktrees for that project. That gives you an isolated development space for the feature you're working on, a bug you're fixing, and a co-worker's code you're reviewing locally. Without portman, to switch from running the feature worktree to the bugfix worktree you have to stop the feature worktree server listening on port 3000 and start the bugfix worktree server. To run your co-worker's code, you have to then stop the bugfix worktree server and start the code review worktree server. Stopping and restarting servers like this is tedious, especially when frequently switching between projects. portman provides a way to dynamically change which project port 3000 is linked to without needing to stop and restart servers.

First, create a project for one of the worktrees, run portman link with the port you want to access the project on, and start the server.

# In terminal tab 1...
cd /projects/worktree-feature
portman create
portman link 3000
npm run dev

Running portman link 3000 not only links the active project to port 3000, it also records the active project's origin git URL and will automatically link future projects with the same origin git URL to port 3000. Now you can create the rest of the projects and start the servers. Each one will use its unique, autogenerated port so they can all start simultaneously without conflict with each other.

# In terminal tab 2...
cd /projects/worktree-bugfix
# Create the project and link it to port 3000
portman create
npm run dev

# In terminal tab 3...
cd /projects/worktree-review
# Create the project and link it to port 3000
portman create
npm run dev

The last project to be linked to a port takes precedence, so http://localhost:3000 will be routed to the worktree-review server. portman achieves this by setting up a reverse-proxy that sends traffic from http://localhost:3000 to the port that the project is linked to. The port that localhost:3000 is linked to can be changed without stopping any servers by running portman link in the project's directory.

# Link http://localhost:3000 to the worktree-bugfix project
cd /projects/worktree-bugfix
portman link

# Sometime later...

# Link http://localhost:3000 to the worktree-review project
cd /projects/worktree-review
portman link

Projects can only be linked to one port at a time, so adding a new linked port removes the previous linked port.

portman link 3000 worktree-bugfix

# worktree-bug is linked to port 3001 and nothing is linked to port 3000
portman link 3001 worktree-bugfix

Gallery

portman provides a simple web server for graphically viewing all of your projects and some basic information about them. It is available at https://localhost.

Activation

When you create a project, portman remembers the current working directory and associates it with the project. Later when you cd to that directory again, portman activates the project by setting the $PORT environment variable to the project's port. Note that the shell integration must be enabled for portman to be able to detect changes to the current directory. During activation portman also sets $PORTMAN_PROJECT to the name of the active project and sets $PORTMAN_LINKED_PORT to the port linked to the active project if there is one.

To create a project without tying it to a specific directory, use the --no-activate flag. The project will not be linked to the current directory and therefore cannot be automatically activated. You must also manually provide a name for the project.

portman create service --no-activate
echo "Port for service is $(portman get service)"

Project names

portman can usually infer a reasonable name for a project when it is omitted from from create. The default project is based on the directory, and portman attempts to normalize it to a valid subdomain by converting it to lowercase, converting all characters other than a-z, 0-9, and dash (-) to dashes, stripping leading and trailing dashes, combining adjacent dashes into a single dash, and truncating it to 63 characters.

cd /projects/app
# Project name defaults to "app"
portman create

Projects that don't auto activate aren't associated with a directory. As a result, the project name cannot be inferred and must be provided manually.

# Project name is explicitly set to "app"
portman create app --no-activate

Configuration

portman has a few configuration parameters that can be tweaked. Run portman config show to locate the default config file location. Run portman config edit to open the configuration file with $EDITOR. You might want to copy the contents of the default_config.toml file as a starting point and then make your desired changes. The config file location can also be changed by setting the PORTMAN_CONFIG environment variable.

PORTMAN_CONFIG=~/portman.toml portman config show

The config file is in TOML format. This is the default config:

ranges = [[3000, 3999]]
reserved = []

ranges

ranges is an array of two-element [start, end] arrays representing the allowed port ranges. The first element is the beginning of the port range, inclusive, and the second element is the end of the port range, inclusive. For example, [[3000, 3999], [8000, 8099]] would assign ports from 3000-3999 and 8000-8099.

Defaults to [[3000, 3999]] if omitted.

reserved

reserved is an array of ports that are reserved and will not be assigned to any project. For example, if you want to assign ports between 3000 and 3999, but port 3277 is used by a something on your machine, set reserved to [3277] to prevent portman from assigning port 3277 to a project.

Defaults to [] if omitted.

Setting up DNS

Chromium-based browsers automatically resolve the localhost tld to 127.0.0.1. To use other browsers or other tools, you may need to configure your DNS to resolve *.localhost to 127.0.0.1. I use NextDNS for ad blocking, and it's trivial to add a rewrite in NextDNS for *.localhost domains.

Bonus: Starship integration

To show the active project's port in your Starship prompt, add this to your starship.toml:

[custom.port]
command = 'if test -n "$PORTMAN_LINKED_PORT"; then echo "$PORT -> $PORTMAN_LINKED_PORT"; else echo "$PORT"; fi'
when = 'test -n "$PORT"'
format = ':[$output]($style) '
shell = ['bash', '--noprofile', '--norc']

CLI API

portman -h, portman --help

Prints CLI usage information.

portman -V, portman --version

Prints portman version.

portman init [bash|bash|zsh]

Prints the shell configuration command to enable the shell integration for the specified shell. You can add it to your shell config as documented in installation. If you installed portman via Homebrew, fish shell is integration is automatically installed and you don't need to modify your fish shell config file.

portman create [project-name] [--no-activate|-A] [--no-link|-N] [--overwrite]

Creates a new project and assigns it a unique, autogenerated port. If project-name is not provided, a default is calculated based on the current directory. project-name is required if --no-activate is present. If --no-activate is present, the project is not associated with a directory and will never be activated by the shell integration. See project names for more details about default project names. By default, the project is linked to the port associated with its git repo if any, unless --no-link is provided. If --overwrite is present and the project already exists, it is updated instead of failing.

portman get [project-name] [--extended|-e]

Prints a project's port. project-name defaults to the active project. If --extended is present, the project's name, directory, and linked port are also printed in addition to the port.

portman delete [project]

Deletes a project. project-name defaults to the active project. Its autogenerated port may be assigned to another project in the future.

portman cleanup

Deletes all projects whose directories don't exist anymore.

portman list

Lists each project in alphabetical order with its ports, directory, and linked port.

portman link [port] [project-name] [--no-save|-S]

Links a project to the specified port. port defaults to the port associated with the active project's git repo. project-name defaults to the active project. By default, when portman link is given a port but no project name, it looks up the origin remote url of the active project's git repo and records the port that that repo is linked to, unless --no-save is provided. portman link uses this information when it is not given a port or a project name.

portman unlink <port>

Unlinks the port from the project it was linked to.

portman repo delete <repo>

Deletes the repo and its associated port.

portman repo list

Lists all repos and their associated ports.

portman caddyfile

Prints a valid Caddyfile that reverse-proxies all projects' ports to https://*.localhost URLs where the subdomain is the project name.

portman reload-caddy

Regenerates the Caddyfile and reloads the caddy config. portman updates the Caddyfile and reloads caddy whenever it makes changes, so this command should only be necessary if something else outside of portman's control is manipulating the Caddyfile or caddy config.

portman config show

Prints the configuration that is currently being used.

portman config edit

Opens the configuration file using the command in the $EDITOR environment variable.

portman's People

Contributors

canac avatar

Watchers

 avatar

portman's Issues

To Caleb

Hey Caleb,
Write back to me!
Difficult to get hold of you!
How are you doing?

-Rick

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.