Packages
Automatically finds an available local TCP port, so multiple Phoenix apps can run at once.
Current section
Files
Jump to
Current section
Files
README.md
<h1 align="center">AutoPort</h1>
<p align="center">
<a href="https://hex.pm/packages/autoport"><img src="https://img.shields.io/hexpm/v/autoport.svg" alt="Hex.pm"></a>
<a href="https://hexdocs.pm/autoport"><img src="https://img.shields.io/badge/hex-docs-blue.svg" alt="Hex Docs"></a>
<a href="https://hex.pm/packages/autoport"><img src="https://img.shields.io/hexpm/dt/autoport.svg" alt="Downloads"></a>
<a href="https://github.com/chrisgreg/autoport/blob/main/LICENSE"><img src="https://img.shields.io/hexpm/l/autoport.svg" alt="License"></a>
</p>
<p align="center"><strong>Never fight over port 4000 again.</strong></p>
A tiny, dependency-free Elixir library that finds an available local TCP port.
It exists to make running several Phoenix applications at the same time
painless: the first one takes `4000`, the next `4001`, the next `4002`, without
anybody editing config.
## Installation
Add `autoport` as a development-only dependency:
```elixir
def deps do
[
{:autoport, "~> 1.0", only: :dev}
]
end
```
## Phoenix usage
In `config/dev.exs`:
```elixir
config :my_app, MyAppWeb.Endpoint,
http: [
ip: {127, 0, 0, 1},
port: AutoPort.find(4000)
]
```
If `4000` is taken, AutoPort prints `Port 4000 is in use, using 4001` and your
app boots on the next free port.
### Choosing a port explicitly
`PORT` overrides whatever the config asks for, so you can pin a shell to a
known port:
```console
$ PORT=4050 iex -S mix phx.server
```
The search still walks upwards from there, so two shells that both export
`PORT=4050` land on `4050` and `4051` rather than one failing to boot.
Pass `env: false` to honour the configured target verbatim, or
`env: "MY_APP_PORT"` to read a different variable.
## API
```elixir
# First free port at or after 4000, raising only if 4000..65535 is fully taken.
AutoPort.find(4000)
#=> 4000
# Bounded search; raises AutoPort.Error if every port in the range is taken.
AutoPort.find(4000..4010)
#=> 4001
# Non-raising variant.
AutoPort.fetch(4000..4010)
#=> {:ok, 4001}
#=> {:error, "no available port found in 4000..4010"}
# Single-port check.
AutoPort.available?(4000)
#=> false
```
### Options
| Option | Default | Description |
| --- | --- | --- |
| `:ip` | `{127, 0, 0, 1}` | Interface the port is tested on. |
| `:verbose` | `true` | Print a message when the requested port is unavailable. |
| `:env` | `"PORT"` | Environment variable that overrides the target; `false` disables. |
```elixir
AutoPort.find(4000, ip: {0, 0, 0, 0}, verbose: false)
```
## Scope
AutoPort is framework-agnostic — no Phoenix, Plug, Bandit, or Cowboy
dependency. It is meant for local development; production deployments should
keep using deterministic, explicitly configured ports.
There is an inherent race between checking a port and binding it. In practice
this is a non-issue for local development, but it is another reason not to use
this in production.
## License
MIT.