Public web agents

Any repo with a Dockerfile can be served on a public, no-login HTTPS URL. Maritime builds it, runs it serverlessly, puts it to sleep when idle, and wakes it on the next visit.

Deploy one

maritime create my-app --repo https://github.com/you/app --public
FlagDescription
-r, --repoGitHub repo to build (Dockerfile at the root). Combine with -b, --branch
--publicServe a public, no-login web URL for this agent
--portPort the public URL sends traffic to. Keep the default, 8080: Maritime forwards it to the PORT your app binds

The dashboard's New agent flow takes the same sources: a GitHub repo, a Docker image, or a ZIP upload. Repo and ZIP sources build on a dedicated build machine; see How builds work.

Visibility

Every agent that serves a port has its own address, https://<agent-id>.mtm.sh/, shown on its Overview as URL. It is private until you say otherwise.

  • Private (the default). A visitor needs a share link. Your backend mints one for a signed-in user with maritime.agents.shareLinks.create(agentId, { endUserExternalId }) and sends them to its url. The first visit swaps the secret for a cookie on that hostname, so pages, assets, and WebSockets all work. A link lasts one hour unless you choose up to 30 days, or no expiry. A link bound to an end user dies when you suspend that end user.
  • Public. Anyone with the URL may open it, and a visit wakes a sleeping agent. Pass --public at create, press Public on the Overview, or run maritime agents url visibility <agent-id> public. Needs a verified email.

The app sees its own Host and its own cookies. Agent URLs tell search engines not to index them. The older https://api.maritime.sh/a/<agent-id> path keeps working for public agents.

What your app must do

  • Ship a Dockerfile at the repo root. Whatever it builds is what runs.
  • Listen on 0.0.0.0:$PORT. Maritime sets PORT and forwards public traffic on port 8080 to it. Don't hardcode a port, and don't bind 8080 yourself.
  • Persist to /data only. It survives restarts, redeploys, and sleep/wake; the rest of the filesystem is disposable.

A web app does not need the chat contract; that is only for agents you want to talk to. If you want both (a web UI and a chattable agent), implement the two-endpoint contract from Deploy any container.

Sleep and wake

The app auto-sleeps when idle and any request to its public URL wakes it, in about a second, with state intact. Sleeping is not downtime: visitors just wake it. The first request after a sleep waits for the wake; every request after that is answered by a running machine.

Configure and observe

maritime env set my-app DATABASE_URL=postgres://... --reload   # encrypted secrets
maritime logs my-app -f                                        # stream logs
maritime history my-app                                        # every build/deploy attempt

Env vars, secrets, and sizing are covered in Env vars & sizing; the full flag set for create and deploy is in the CLI reference.