Skip to content

Ingress and Firewall

Slipway has one default public traffic path:

text
Internet → Caddy (80/443) → Slipway dashboard or app container

Fresh installations publish only Caddy. The dashboard binds to 127.0.0.1:1337, deployed apps bind to loopback ports in 1338–1500, and Caddy reaches them over the private slipway Docker network.

What loopback means

127.0.0.1 is the server's loopback interface: a service bound there accepts connections originating on that same server only. It is not the server's public IP and it is not a private LAN address.

If you open 127.0.0.1 on your laptop, it refers to your laptop—not the VPS. This is why Slipway can keep internal ports available to Caddy and health checks without exposing those ports to the internet.

Default public VPS mode

PortDefault bindingPurpose
22Provider/host choiceSSH; Slipway does not change it
800.0.0.0Caddy HTTP and certificate challenges
4430.0.0.0Caddy HTTPS
1337127.0.0.1Slipway dashboard behind Caddy
1338–1500127.0.0.1App containers behind Caddy

The installer aligns active UFW or firewalld rules with these bindings. It does not enable a firewall or change SSH policy. At the VPS provider, allow inbound TCP 80 and 443, retain your chosen SSH rule, and deny the rest.

Inspect the effective bindings:

bash
sudo docker ps --format 'table {{.Names}}\t{{.Ports}}'
sudo ss -lntp

slipway-proxy should show public 80 and 443. The slipway dashboard and deployed apps should show 127.0.0.1 bindings.

Explicit raw IP and port access

Direct http://SERVER_IP:PORT URLs can help when diagnosing a deployment without DNS, but they bypass Caddy TLS and enlarge the public attack surface. Enable them deliberately:

bash
curl -fsSL https://raw.githubusercontent.com/sailscastshq/slipway/main/install.sh -o /tmp/install-slipway.sh
sudo env SLIPWAY_APP_PORT_HOST=0.0.0.0 bash /tmp/install-slipway.sh

Redeploy the app so Docker recreates its binding, then allow TCP 1338–1500 in the provider firewall. Verify from another network:

bash
curl -I --connect-timeout 5 http://SERVER_IP:ALLOCATED_PORT/health

Return to private app ports by rerunning the installer with SLIPWAY_APP_PORT_HOST=127.0.0.1, redeploying existing apps, and closing the range in the provider firewall.

Upgrading an older installation

The first upgraded installer preserves missing dashboard and app host settings as public. This prevents a security release from silently breaking an existing raw URL. Harden the host explicitly when you are ready:

bash
curl -fsSL https://raw.githubusercontent.com/sailscastshq/slipway/main/install.sh -o /tmp/install-slipway.sh
sudo env \
  SLIPWAY_DASHBOARD_HOST=127.0.0.1 \
  SLIPWAY_APP_PORT_HOST=127.0.0.1 \
  bash /tmp/install-slipway.sh

Redeploy existing apps, then remove 1337 and 1338–1500 from the provider firewall. Existing app containers keep their previous Docker binding until they are replaced.

Optional Cloudflare Tunnel mode

Tunnel mode changes the path to:

text
Internet → Cloudflare → outbound cloudflared tunnel → loopback Caddy → container

Install with a real dashboard hostname:

bash
curl -fsSL https://raw.githubusercontent.com/sailscastshq/slipway/main/install.sh -o /tmp/install-slipway.sh
sudo env \
  SLIPWAY_INGRESS=cloudflare-tunnel \
  SLIPWAY_URL=https://slipway.example.com \
  bash /tmp/install-slipway.sh

This binds Caddy, the dashboard, and app ports to loopback. Point the tunnel at http://127.0.0.1:80 and preserve the incoming hostname so Caddy can choose the correct Slipway route:

yaml
tunnel: YOUR_TUNNEL_UUID
credentials-file: /etc/cloudflared/YOUR_TUNNEL_UUID.json

ingress:
  - hostname: slipway.example.com
    service: http://127.0.0.1:80
  - hostname: '*.apps.example.com'
    service: http://127.0.0.1:80
  - service: http_status:404

Do not set httpHostHeader. Add each custom app domain as a tunnel public hostname, or use a wildcard for the generated app domain. Webhooks, SSE, telemetry, and CLI requests use the same HTTP route.

Cloudflare Tunnel makes outbound connections, so the provider firewall can deny all inbound Slipway ports. Restrictive egress firewalls must permit Cloudflare Tunnel on TCP/UDP 7844. See Cloudflare's tunnel firewall guide and ingress configuration reference. Tunnel mode adds Cloudflare as an availability and DNS dependency; default public VPS mode has fewer moving parts and remains the recommended starting point.

All open source projects are released under the MIT License.