# Public and private ports

https://instabox.sh/docs/ports.md

Give a web server in a machine an HTTPS URL, for anyone or only for people with the link.

```
instabox port publish dev 3000 --name 'Web app'   # prints the URL; anyone can open it
instabox port publish dev 3000 --private          # prints a link with ?_token=; only it opens the URL
instabox port publish dev 3000 --private --rotate-token   # a new link; the old one stops working
instabox port publish dev 3000 --public           # anyone again
instabox port ls dev
instabox port unpublish dev 3000
```
Inside the machine, an agent does the same with `instabox-port` (`instabox port setup dev` installs it where it is missing):
```
instabox-port publish 3000 --name 'Web app'
instabox-port publish 3000 --private
instabox-port serve ./report --port 8080          # serve a folder with an index.html
```
- The URL is `https://<port>-<machine id without m_>.<domain>/`. It is not a secret: once published **public** (the default), anyone can reach the whole service until you unpublish it.
- A **private** port answers only requests that carry its token. Share the printed link (the URL with `?_token=ibp_…`): a browser that opens it is redirected to the plain URL with a cookie set (`__Host-instabox_port_auth`), and every later request from that browser, WebSockets included, gets through; scripts send `Authorization: Bearer ibp_…` instead. Everyone else gets 401, and such requests never wake the machine. The link is printed once (the server keeps only a hash): `--private --rotate-token` prints a new one and ends the connections of the old. Renaming a private port keeps it private; `--public` drops the token.
- A visit wakes a machine that paused itself for being idle (the 30-minute idle pause): the request waits for it to resume, so a phone app or webhook can reach the URL without starting it first. `instabox wake <machine>` does the same without a request. A machine you paused or stopped stays offline until you resume or start it, at the same URL. After a stop, start your server again.
- Up to 16 published ports per machine. In the dashboard, a machine's **Ports** tab publishes and unpublishes them and marks private ones.
- To reach a port only from your own computer, without any URL (a database, a debugger, anything TCP), use `instabox port-forward dev 8080:3000` (see [Connecting over SSH](https://instabox.sh/docs/ssh.md)).
- Raw TCP (Postgres, Redis, ...), where the server enables it: `instabox port publish dev 5432 --tcp` prints `5432-<id>.<tcp domain>:443`. Connect with TLS and that name as SNI: `psql "host=5432-<id>.<tcp domain> port=443 sslmode=require user=postgres"` (psql/libpq 14+, which send SNI; PG17+ may add `sslnegotiation=direct`; older clients: stunnel or `instabox port-forward`), or `openssl s_client -connect <address> -servername <host>`. The service in the machine sees plain TCP and must use its own password; a raw TCP port is always public (no `--private`). In preview (admins only) until the server opens it to everyone; then paid plans only, up to 5 per workspace. A connection counts as activity only while bytes flow: an idle pooled connection does not keep the machine awake, so keep pool idle timeouts under 30 minutes or send keepalives.
