Skip to content
Deploying / Ports

Ports

Publishing raw TCP and UDP that kamal-proxy cannot front.

kamal-proxy fronts HTTP. Anything that is not HTTP – SMTP, IMAP, a game server, a database you are exposing on purpose – has to be published on the machine itself.

Environment → Hosts → Ports. Add the port to publish, the protocol (tcp or udp), and optionally a different port inside the container. Left blank, the container listens on the same port it is published on.

KamalCloud writes these into the destination config in Docker’s own publish form, which Kamal passes through as a role option.

TCP 80 and 443 are not available

kamal-proxy holds both on every machine Kamal touches, so Docker would refuse a container asking for either, and KamalCloud refuses them first. Only TCP is refused: UDP 443 is free, for anything that wants it. Serve HTTP through domains instead; that is what the proxy is for.

The firewall

A published port is behind the account’s cloud firewall until it is told about it. Every releasing deployment opens the environment’s published ports on the provider’s firewall, so adding a port and deploying is enough on an API-managed machine.

On a self-hosted machine there is no cloud firewall to open. Whatever firewall the machine itself runs is yours to configure.

Deploys with published ports

Kamal boots the new container before stopping the old one, and two containers cannot hold the same host port. So when an environment publishes ports, KamalCloud splits the deploy: build and deliver the image first, then stop, then boot with --skip-push. That means a short outage on those ports at every deploy, which is unavoidable and better than a deploy that fails on a port conflict.

Uniqueness

A published port is unique per environment and protocol: the same number on tcp and udp is two entries. Two environments on the same machine publishing the same port is a conflict Docker will refuse – KamalCloud cannot see it coming, so it is worth keeping in mind on a shared box.

Outbound port 25

Worth saying because it catches everyone: Hetzner, DigitalOcean and AWS block outbound port 25 on new accounts until asked. Publishing 25 inbound is fine; sending mail out needs a ticket to the provider or a relay.