donnfelker/kamal-skills · Archived

proxy

Configure and operate kamal-proxy, the reverse proxy that gives Kamal zero-downtime deploys on ports 80 and 443. Use when the user wants to route a domain (host/hosts), enable automatic HTTPS via Let's Encrypt (ssl), point the proxy at their app's port (app_port), tune the deploy healthcheck (/up), or adjust response_timeout and buffering — and when they say things like "configure the kamal proxy," "set up SSL for my domain," "add my custom domain," "the proxy isn't routing," "reboot the proxy,…

First seen Jul 6, 2026

Installation

$ npx skills add donnfelker/kamal-skills --skill proxy

Summary

  • Configure and operate kamal-proxy, the reverse proxy that gives Kamal zero-downtime deploys on ports 80 and 443.
  • Use when the user wants to route a domain (host/hosts), enable automatic HTTPS via Let's Encrypt (ssl), point the proxy at their app's port (app_port), tune the deploy healthcheck (/up), or adjust response_timeout and buffering — and when they say things like "configure the kamal proxy," "set up SSL for my domain," "add my custom domain," "the proxy isn't routing," "reboot the proxy," "upgrade kamal-proxy," or run kamal proxy boot/reboot/start/stop/details/logs.
  • Covers the proxy config block and the kamal proxy command.
  • For full deploys, see deploy.
  • For enabling the proxy per role, see servers.
  • For starting and stopping the app container, see app.
  • For migrating from Kamal 1.x to kamal-proxy, see upgrade.

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from donnfelker/kamal-skills · top by installs.

npx skills add donnfelker/kamal-skills

Browse all from donnfelker/kamal-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

License LICENSE
Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Version1.0.0
More metadata
version
1.0.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 10,612 B
  • docs SUMMARY.md 841 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

kamal-proxy

You are an expert in deploying applications with Kamal. Your job is to configure and operate kamal-proxy so the user's app serves traffic with gapless, zero-downtime deploys.

How kamal-proxy works

Kamal uses kamal-proxy to provide gapless deployments. It runs on ports 80 and 443 and forwards requests to the application container.

You configure it in the root configuration under proxy. These options are set when deploying the application, not when booting the proxy. They are application-specific, so they are not shared when multiple applications run on the same proxy.

During a deploy, Kamal:

  1. Ensures kamal-proxy is running and accepting traffic on ports 80 and 443.
  2. Starts a new container with the new version of the app.
  3. Tells kamal-proxy to route traffic to the new container once it responds with 200 OK to GET /up.
  4. Stops the old container.

Because routing only switches after the new container passes its healthcheck, getting proxy right is what makes deploys seamless.

Before you configure

Read the user's existing setup before asking questions:

  • config/deploy.yml — look for an existing proxy: block and the servers: roles so you know what is already set.
  • .kamal/secrets — needed only if you are loading a custom SSL certificate from secrets (see step 3).

If there is no proxy: block yet, you are starting from a clean slate and only need to add the keys the user actually wants.

Walkthrough: configure the proxy

All of the following keys live under a single proxy: block in config/deploy.yml.

1. Route your domain with host

The hosts that will be used to serve the app. The proxy only routes requests for these hosts to your app. Specify one of host or hosts.

proxy:
  host: app.example.com

For multiple domains, use hosts:

proxy:
  hosts:
    - app.example.com
    - www.example.com

If no hosts are set, all requests are forwarded to the app, except requests matching other apps deployed on that server that do have a host set.

2. Point at your app's port with app_port

The port the application container is exposed on. Defaults to 80. Set it to match the port your app listens on inside the container:

proxy:
  app_port: 3000

3. Turn on HTTPS with ssl

kamal-proxy can provide automatic HTTPS via Let's Encrypt. Defaults to false.

proxy:
  host: app.example.com
  ssl: true

Automatic SSL has requirements:

  • You must be deploying to one server, and the host option must be set.
  • The host value must point to the server you are deploying to.
  • Port 443 must be open for the Let's Encrypt challenge to succeed.
  • The host's DNS must resolve directly to the server during issuance. If it is

proxied through a CDN (Cloudflare's orange cloud, etc.), the Let's Encrypt HTTP-01 challenge reaches the CDN instead of kamal-proxy and issuance fails or loops. Point an A record at the server IP in "DNS only" (grey cloud) mode — not a CNAME to the CDN. kamal-proxy also auto-renews the certificate using the same HTTP-01 challenge, so the record must stay grey-cloud the whole time ssl: true is set — re-enabling the orange cloud later silently breaks renewal ~60 days on. To keep a CDN in front permanently, stop using Let's Encrypt and load a CDN origin certificate via the custom certificatepem/privatekey_pem block below.

When ssl: true, kamal-proxy stops forwarding headers to your app unless you explicitly set forwardheaders: true. By default, kamal-proxy will not forward the X-Forwarded-For and X-Forwarded-Proto headers when ssl is true, and will forward them when ssl is false. Set forwardheaders: true if you are behind a trusted proxy and your app needs those headers.

Host-header trust: Separately from forwarded headers, some frameworks validate the raw Host header against an allowlist and reject requests arriving through kamal-proxy until explicitly told to trust it — Rails' config.hosts, Django's ALLOWED_HOSTS, Auth.js/NextAuth's trustHost: true (required for any deploy outside Vercel). The symptom is an UntrustedHost-style error or an unexplained redirect loop on auth routes right after deploying, even though the app worked when run directly without the proxy. Add the deployed host to the framework's allowlist alongside setting proxy.host.

By default, kamal-proxy redirects all HTTP requests to HTTPS when SSL is enabled. To pass HTTP traffic through to your app alongside HTTPS, set ssl_redirect: false.

Custom certificate instead of Let's Encrypt: If you can't use Let's Encrypt — for example, you deploy from more than one host, or you already have a certificate from another CA — load the certificate from secrets by mapping certificatepem and privatekey_pem to secret names:

proxy:
  ssl:
    certificate_pem: CERTIFICATE_PEM
    private_key_pem: PRIVATE_KEY_PEM

Those names reference entries in .kamal/secrets. If the certificate or key is missing or invalid, deployments will fail. Never hard-code certificates or private keys in source control.

4. Tune the deploy healthcheck

When deploying, the proxy hits /up once every second until the deploy timeout, with a 5-second timeout for each request. Once the app is up, the proxy stops hitting the healthcheck endpoint. Override any of these:

proxy:
  healthcheck:
    path: /health
    interval: 3
    timeout: 3
Key What it sets Default
path Endpoint the proxy checks /up
interval Seconds between checks 1
timeout Seconds to wait per check 5

5. Set the response timeout and buffering

Response timeout — how long to wait for requests to complete before timing out. Defaults to 30 seconds:

proxy:
  response_timeout: 10

Buffering — whether to buffer request and response bodies in the proxy. By default, buffering is enabled with a max request body size of 1GB and no limit for response size. The memory limit defaults to 1MB; anything larger is written to disk.

proxy:
  buffering:
    requests: true
    responses: true
    max_request_body: 40_000_000
    max_response_body: 0
    memory: 2_000_000

A complete example

proxy:
  host: app.example.com
  app_port: 3000
  ssl: true
  healthcheck:
    path: /up
    interval: 3
    timeout: 3
  response_timeout: 10

Apply your changes

Proxy options are applied at deploy time. After editing the proxy: block, run a deploy to push the new configuration:

kamal deploy

For more proxy keys — path-based routing (pathprefix, pathprefixes, strippathprefix), request logging, and the full run (boot) configuration — see [references/config-reference.md](references/config-reference.md).

Operating the proxy with kamal proxy

The kamal proxy command manages the proxy container itself on your servers. The most common subcommands:

Subcommand What it does
kamal proxy boot Boot the proxy on servers
kamal proxy reboot Reboot the proxy (stop container, remove container, start a new container)
kamal proxy restart Restart the existing proxy container on servers
kamal proxy start Start the existing proxy container on servers
kamal proxy stop Stop the existing proxy container on servers
kamal proxy details Show details about the proxy container from servers
kamal proxy logs Show log lines from the proxy on servers
kamal proxy remove Remove the proxy container and image from servers

For the full subcommand list and the (deprecated) boot_config, see [references/commands-reference.md](references/commands-reference.md).

Inspecting the proxy

When routing or SSL is misbehaving, start with details and logs:

kamal proxy details
kamal proxy logs

Upgrading or rebooting the proxy

When you want to upgrade kamal-proxy, run kamal proxy reboot. This causes a small outage on each server and prompts for confirmation.

kamal proxy reboot

To avoid restarting on all servers simultaneously, use a rolling reboot:

kamal proxy reboot --rolling

You can also use the pre-proxy-reboot and post-proxy-reboot hooks to remove and add servers to upstream load balancers as you reboot them.

Boot (run) configuration

Options used when booting the proxy container — published ports, log size, registry/repository, and the pinned version of the kamal-proxy image — live under proxy/run in your config. This replaces the deprecated kamal proxy boot_config. See the run table in [references/config-reference.md](references/config-reference.md).

Enable or disable the proxy per role

The proxy is enabled by default on the primary role. Disable it by setting proxy: false in that role:

servers:
  web:
    hosts:
      - ...
    proxy: false

It is disabled by default on all other roles. Enable it with proxy: true, or by providing a proxy configuration for that role:

servers:
  web:
    hosts:
      - ...
  web2:
    hosts:
      - ...
    proxy: true

Related Skills

  • deploy: Run kamal deploy to apply proxy configuration and roll out new versions through the proxy.
  • servers: Define servers roles and control which roles run the proxy.
  • app: Start, stop, and inspect the app container that the proxy routes to.
  • upgrade: Migrate from Kamal 1.x to 2.0 and kamal-proxy.