Public URLs

Give a port inside a box its own HTTPS link that anyone can open.

A box is private by default: nothing on the internet can reach it. A public URL changes that for one port. You pick the port, boxctl gives it an HTTPS address like https://my-box-k7f2q9xd.boxctl.app, and anyone who has that address can open it in a browser.

Public URLs are free on every plan. An account can have up to five at a time, across all of its boxes.

Use it to show someone a dev server, share a demo, or receive a webhook. For something only you should reach, use boxctl port-forward my-box 3000 from the command line instead; it needs no public address at all.

Making a port public

In the dashboard, open the Public URLs tab, pick the box, enter the port your app listens on, and choose Make public. Only running boxes are listed; resume a paused box first. The tab lists every public URL you have, across all your boxes, and is where you copy or remove one. A box with public URLs also shows how many it has in the box list.

From the command line:

boxctl expose my-box 3000     # prints the URL
boxctl expose my-box          # lists my-box's public URLs
boxctl unexpose my-box 3000   # takes one down

What your app has to do

Two things catch almost everyone the first time.

Listen on 0.0.0.0, not 127.0.0.1. A request reaches your app from outside the box, so an app bound to localhost never sees it. Most dev servers have a --host option:

vite --host 0.0.0.0
python3 -m http.server 3000 --bind 0.0.0.0

Accept the public hostname. Vite, Rails and Django refuse requests for a hostname they do not know. Either allow the hostname in the app's own settings, or set a Host header when you expose the port (--host-header localhost:3000 on the command line). Requests then arrive at your app under that name.

Who can see it

Anyone with the link. There is no sign-in in front of it.

The address contains eight random characters, so it cannot be guessed, and it is not published anywhere. Treat it like an unlisted link: fine for sharing with people you choose, not a substitute for a login on anything sensitive.

When the box is paused

A paused box keeps its public URLs, but they show a "not available" page until the box runs again. Resuming brings the same addresses back.

Visitors count as using the box. While people are opening its public URL, it is not auto-paused for being idle.

Removing one

Removing a public URL retires its address for good. If you expose the same port again later, it gets a new address, and links you shared before stop working. Deleting a box removes all of its public URLs.

Limits

  • Five public URLs per account, counting every box, paused ones included. Remove one to add another.
  • Web traffic only: HTTP, WebSocket and server-sent events. Other protocols, such as a database connection or SSH, do not work through a public URL.
  • Ports 22 and 5901 cannot be made public.
  • An upload larger than 100 MB is refused.
  • A request your app takes more than 100 seconds to start answering is cut off.