Kamal Proxy

repository·main·Indexed 22 days ago

https://github.com/basecamp/kamal-proxy

A minimal HTTP proxy designed for zero-downtime deployments. It manages traffic routing, health checks, and TLS (automatic, on-demand, or custom) to ensure seamless transitions between application versions. Features include host-based and path-based routing, request/response buffering, and Prometheus metrics support.

Tokens
7.4K
Snippets
40
Records
40
Agent score
71%

What's inside kamal-proxy

  1. Configure host-based routing

    main

    You can run multiple applications on a single Kamal Proxy instance by assigning each service to a specific host using the --host flag. Only one service can route a specific host at a time.

    # Route traffic for app1.example.com to service1
    kamal-proxy deploy service1 --target web-1:3000 --host app1.example.com
  2. Configure path-based routing

    main

    Path-based routing allows you to mount services under specific path prefixes using the --path-prefix flag.

    By default, the prefix is stripped from the request before it is forwarded upstream. To keep the prefix in the request sent to the upstream service, set --strip-path-prefix=false.

    # Route /api requests to service1 and strip the prefix
    kamal-proxy deploy service1 --target web-1:3000 --path-prefix=/api
    
    # Route /api requests to service1 but keep the prefix
    kamal-proxy deploy service1 --target web-1:3000 --path-prefix=/api --strip-path-prefix=false
  3. Manage Kamal Proxy via Docker Compose

    main

    When running Kamal Proxy inside a Docker container via Docker Compose, you can execute proxy commands by using docker compose exec proxy.

    Use the following commands to interact with the running proxy instance:

    • Deploy a service: Use kamal-proxy deploy service <service_name> --target <target_address> to deploy a specific service to a target.
    • List services: Use kamal-proxy ls to see all currently deployed services.
    # Deploy the first web server as a new service
    docker compose exec proxy kamal-proxy deploy service1 --target example-web-1
    
    # List currently deployed services
    docker compose exec proxy kamal-proxy ls
  4. Deploy a service instance

    main

    Deploying an instance registers a target (in hostname:port format) to a service name. Kamal Proxy will perform HTTP health checks on the target and only start routing traffic once the target is healthy.

    When a new deployment succeeds, Kamal Proxy immediately switches all new traffic to the new instance and waits for traffic to drain from the old instance before returning. This ensures zero-downtime deployments.

    # Deploy web-1:3000 to the service 'service1'
    kamal-proxy deploy service1 --target web-1:3000
  5. Run a deployment example with Docker Compose

    main

    You can spin up a local demonstration environment containing the Kamal Proxy and four instances of a simple web server using Docker Compose. This setup allows you to test proxy commands and deployment workflows locally.

    To start the services, run:

    docker compose up --build

    Once running, the proxy is accessible at http://localhost/.

  6. Run Kamal Proxy

    main

    To start the proxy, use the kamal-proxy run command. By default, it listens on port 80. You can customize the listening port using the --http-port flag or the HTTP_PORT (or KAMAL_PROXY_HTTP_PORT) environment variable.

    To see all available runtime options, run kamal-proxy help run.

    # Run on a specific port
    kamal-proxy run --http-port 8080
    
    # Run using environment variables
    HTTP_PORT=8080 kamal-proxy run
    
    # Run using prefixed environment variables
    KAMAL_PROXY_HTTP_PORT=8080 kamal-proxy run
  7. Configure Automatic TLS

    main

    Kamal Proxy can automatically manage TLS certificate issuance and renewal. To enable this, use the --tls flag during deployment.

    Requirements:

    • You must specify a --host (automatic TLS is not supported for generic routing).
    • When using path-based routing, TLS settings must be configured on the root path (/). All other services on that same host will inherit these settings.
    # Enable automatic TLS for a specific host
    kamal-proxy deploy service1 --target web-1:3000 --host app1.example.com --tls
  8. Configure request and response buffering

    main

    Buffering can be enabled to control how requests and responses are handled before being forwarded. When buffering is enabled, you can specify limits on the size of the data being buffered.

    Important Constraints:

    • --max-request-body can only be set if --buffer-requests is enabled.
    • --max-response-body can only be set if --buffer-responses is enabled.
    • Use --buffer-memory to set the maximum size of the memory buffer.
    deploy my-service --target http://127.0.0.1:8080 --buffer-requests --max-request-body 1048576
  9. Configure TLS for a service

    main

    To enable TLS, use the --tls flag. Note that TLS requires a non-empty --host to be specified. You can use Let's Encrypt (including the staging environment via --tls-staging) or provide your own PEM-formatted certificates.

    Custom Certificates: If using custom certificates, you must provide both the certificate and the private key:

    • --tls-certificate-path <path>
    • --tls-private-key-path <path>

    On-Demand TLS: Use --tls-on-demand-url <url> to allow the proxy to make an HTTP request to an external service to authorize certificate issuance for a host.

    deploy my-service --host example.com --target https://10.0.0.1:443 --tls --tls-staging
  10. Use custom TLS certificates

    main

    If you manage your own certificates or use a specific CA (like Cloudflare origin certificates), you can manually provide the certificate and private key paths during deployment.

    # Deploy with manual certificate paths
    kamal-proxy deploy service1 --target web-1:3000 --host app1.example.com --tls --tls-certificate-path cert.pem --tls-private-key-path key.pem
  11. Configure On-demand TLS

    main

    For scenarios where the set of hosts is dynamic (e.g., customer domains), you can use On-demand TLS. Instead of a static --host, provide a --tls-on-demand-url.

    Kamal Proxy will call this URL with a host query parameter (e.g., ?host=example.com) and a matching Host header. A 200 response allows the certificate to be issued.

    # Enable on-demand TLS via an external check URL
    kamal-proxy deploy service1 --target web-1:3000 --tls --tls-on-demand-url="http://localhost:4567/check"