Ports
Shipper uses a small, fixed port set. Open the inbound ports before installation and keep them open for certificate renewal.
Inbound
Section titled “Inbound”| Port | Protocol | Purpose | Required |
|---|---|---|---|
80 |
TCP | ACME HTTP-01 challenge and HTTP to HTTPS redirect | Yes for public HTTPS |
443 |
TCP | Dashboard and application HTTPS | Yes for public HTTPS |
8080 |
TCP | First-run setup and direct recovery path to the control plane | Yes for setup and recovery |
Port 8080 is not a public application port. It is the control-plane listener. Keep it reachable from your own addresses, and do not remove it until the dashboard domain has been verified.
Outbound
Section titled “Outbound”| Destination | Port | Purpose |
|---|---|---|
ghcr.io |
443 | Shipper release images |
raw.githubusercontent.com |
443 | Update channel metadata |
github.com and api.github.com |
443 | Release links, repository checks, GitHub connections |
| Your Git hosts | 443 or 22 | Source clones |
| Container registries | 443 | Image pulls |
| Let’s Encrypt ACME endpoints | 443 | Certificate issuance and renewal |
| Your S3-compatible endpoint | 443 | Off-server backup uploads |
| SMTP provider | 465 or 587 | Optional notification email |
| Webhook destinations | 443 | Optional notifications |
Outbound HTTPS is required for updates. A host that cannot reach GHCR and the selected raw GitHub feed cannot use managed updates.
Internal ports
Section titled “Internal ports”| Port | Where | Purpose |
|---|---|---|
8780 |
Docker host, default manual install | Traefik HTTP published port |
8743 |
Docker host, default manual install | Traefik HTTPS published port |
8080 |
Application container, static Apache | Apache inside a static site container |
3000 |
Application container, default | Runtime port when nothing else is declared |
A managed install publishes Traefik on 80 and 443. A manual install defaults to 8780 and 8743. SHIPPER_PROXY_BIND controls the host address Traefik binds to.
The application’s public hostname routes to its container port through Traefik. The container port does not need to be published on the host.
Open the firewall
Section titled “Open the firewall”On Ubuntu with UFW:
sudo ufw allow 80/tcpsudo ufw allow 443/tcpsudo ufw allow 8080/tcpsudo ufw status verboseAt the cloud provider, allow the same inbound TCP ports. A host firewall rule does not help when the provider firewall drops the packet first.
Test from outside the server:
nc -vz shipper.example.com 80nc -vz shipper.example.com 443nc -vz shipper.example.com 8080A successful TCP connection is not proof that the application responds. Follow with:
curl -sS -o /dev/null -w '%{http_code}\n' http://shipper.example.comcurl -sS -o /dev/null -w '%{http_code}\n' https://shipper.example.comCheck listeners on the host
Section titled “Check listeners on the host”ss -ltnp 'sport = :80 or sport = :443 or sport = :8080'Expected on a managed install:
- Port 8080 belongs to the Shipper control-plane container.
- Ports 80 and 443 belong to the proxy container.
If a different process owns 80 or 443, the proxy cannot start. Stop the conflicting process or move it to another host.
Docker socket
Section titled “Docker socket”The Docker socket is not a network port. On a managed install it is mounted into the control-plane container read-only at /var/run/docker.sock.
A Docker socket still grants host-level control even when the mount is read-only. Do not expose it over TCP. Keep the dashboard private.
Change the published ports
Section titled “Change the published ports”Changing published ports, the proxy bind address, or static ACME settings requires a maintenance window:
- Remove only the instance’s labelled proxy container.
- Keep its proxy data volume.
- Change the setting.
- Restart Shipper so the proxy is recreated.
Do not delete acme.json or the proxy volume as part of an ordinary port change. The dashboard domain is a live setting and does not require this maintenance window.
Common port failures
Section titled “Common port failures”| Symptom | Cause | Fix |
|---|---|---|
| Installer refuses a fresh host | Port 80, 443, or 8080 already in use | Stop the conflicting service |
| Certificate challenge fails | Port 80 blocked | Allow inbound TCP 80 |
| HTTPS works locally, not publicly | Provider firewall or NAT | Forward 443 to the server |
| Dashboard unreachable after domain change | DNS or 443 blocked | Use http://<server-ip>:8080, fix DNS and firewall |
| Application unreachable but container healthy | Route target or port mismatch | Check the container port and Domains route |
| Proxy cannot start | 80 or 443 owned by another process | Stop the other process |