Handle loadbalancing for multiple web hosts#1490
Handle loadbalancing for multiple web hosts#1490mhenrixon wants to merge 17 commits intobasecamp:mainfrom
Conversation
62f9b23 to
dbe2a5a
Compare
dbe2a5a to
3da7b51
Compare
3da7b51 to
a1d1046
Compare
…local-registry-login-for-remote-build' into feat/loadbalancing
Resolved conflicts: - lib/kamal/cli/proxy.rb: Combined upstream's host-specific proxy pattern (KAMAL.proxy(host)) with local info logging statements - test/integration/docker/deployer/app/config/deploy.yml: Kept both loadbalancer: false and run: registry: registry:4443 configurations
Update reference from Proxy::Boot::MINIMUM_VERSION to Proxy::Run::MINIMUM_VERSION after upstream refactoring moved the constant location.
- Create test/commands/loadbalancer_test.rb with 20 tests covering: - Container lifecycle (run, start, stop, start_or_run) - Deploy command with targets, SSL, and multiple hosts - Info, version, logs commands - Container/image removal and directory management - Add 11 loadbalancer CLI tests to test/cli/proxy_test.rb: - boot, reboot, details with loadbalancer - loadbalancer subcommands (info, start, stop, logs, deploy) - remove_container/remove_image with loadbalancer - Create test/fixtures/deploy_with_loadbalancer.yml fixture
When the loadbalancer is configured on a server that also runs a proxy (i.e., a web server), the loadbalancer now takes over the proxy role: - Skip booting separate proxy container on loadbalancer host - Loadbalancer container uses "kamal-proxy" name (not "load-balancer") - Loadbalancer uses proxy-compatible volume mounts for app deployments - Container label matches proxy for proper cleanup This eliminates the port conflict (both use 80/443) and reduces the number of containers needed when loadbalancer is on a web server. Changes: - Add loadbalancer_on_proxy_host? method to detect shared host - Update boot/reboot to skip proxy on loadbalancer host - Loadbalancer container_name is dynamic based on host type - Add proxy-compatible volume mounts when on proxy host Tests added for shared host scenario.
f48949f to
eeca4bf
Compare
|
@mhenrixon - Hey! Do you need any help on this PR to be merged? Also - question: this assumes that we have at least two different targets/hosts: 1) one running Kamal proxy and 2) the second one running like a replica. Nevertheless, if we are would want a "real" loadbalancer we would need at least 3 different hosts right? 1 for the loadbalancer, and 2 others to run 2 replicas Am I missing something one this? |
No, i have changed it so that the extra host shouldn't be needed. If the current host has a rails server (web ip), i combine the load balancer and proxy to be one. Works as long as we have the same docker image. |
Yeah! It makes total sense! If that server that is running the proxy+LB is unstable then we would have a problem of trying to route the requests |
Absolutely, I just wanted the to also offer the cheapest way possible to loadbalance. The thing is, the load balancer and kamal proxy is not the problem and if the rails server is having problems you can always separate the two. Since it is running docker containers you really shouldn't have any issues. I have used this on fairly large projects and never had any issues. |
|
isn't it better to send requests via private networks instead of public ips ? isn't it faster for the servers to communicate with each other ? I think there should be a configuration on the host where you can set both public and private IPs. |
There was a problem hiding this comment.
Pull request overview
This PR introduces optional load balancing support to Kamal’s proxy layer by adding a proxy.loadbalancer configuration key, wiring load balancer lifecycle/config updates into existing CLI flows, and adding test coverage/fixtures for the new behavior.
Tip
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.
Changes:
- Add
proxy.loadbalancerand load-balancing detection to proxy configuration/validation. - Add a new
Kamal::Commands::Loadbalancer+Kamal::Configuration::Loadbalancer, and expose management viakamal proxy loadbalancer .... - Update deploy/redeploy/boot/reboot flows and add fixtures + unit/CLI/integration tests for load balancing scenarios.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| test/integration/docker/deployer/app_with_roles/config/deploy.yml | Disables load balancer in an integration config to avoid interference. |
| test/integration/docker/deployer/app/config/deploy.yml | Disables load balancer in an integration config to avoid interference. |
| test/fixtures/deploy_with_loadbalancer_on_proxy_host.yml | Adds fixture where LB runs on a web/proxy host. |
| test/fixtures/deploy_with_loadbalancer.yml | Adds fixture where LB runs on a dedicated host. |
| test/configuration/proxy_test.rb | Adds configuration tests for loadbalancer/effective host and derived options. |
| test/commands/loadbalancer_test.rb | Adds command builder tests for new load balancer commands. |
| test/cli/proxy_test.rb | Adds CLI tests validating boot/reboot/details and LB subcommands/flows. |
| test/cli/cli_test_case.rb | Stubs load_balancing? by default to keep existing CLI tests stable. |
| lib/kamal/configuration/validator/proxy.rb | Adjusts proxy validation logic in presence of loadbalancer. |
| lib/kamal/configuration/role.rb | Adjusts SSL multi-host validation to account for load balancer usage. |
| lib/kamal/configuration/proxy.rb | Adds load balancer config accessors and load-balancing behavior. |
| lib/kamal/configuration/loadbalancer.rb | Introduces load balancer-specific configuration wrapper. |
| lib/kamal/configuration/docs/proxy.yml | Documents the new loadbalancer option in proxy configuration docs. |
| lib/kamal/configuration.rb | Adds top-level load_balancing? helper. |
| lib/kamal/commands/proxy.rb | Adds a load balancer command accessor on proxy commands. |
| lib/kamal/commands/loadbalancer.rb | Adds new command builder for load balancer lifecycle/config/logs. |
| lib/kamal/commander.rb | Adds load balancer configuration + command construction. |
| lib/kamal/cli/proxy.rb | Adds LB boot/reboot/details hooks and kamal proxy loadbalancer subcommand. |
| lib/kamal/cli/main.rb | Updates deploy/redeploy to push LB configuration updates post app boot. |
| lib/kamal/cli/build.rb | Changes registry login behavior during build push. |
| CLAUDE.md | Adds repository guidance documentation for Claude Code. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Adding Load Balancer to Kamal
This PR adds load balancing to Kamal with minimal changes. It spreads traffic across multiple app servers while keeping things simple.
Key Design Choices
Simple Approach
loadbalancerkey to your proxy settingsEasy Integration
Configuration Options
loadbalancer: lb.example.comWhy We Did It This Way
We built the load balancer into the proxy system because:
How It Works
Configuration Example
To turn off load balancing when using multiple roles:
Usage
Load balancing turns on when:
loadbalancersetting, ORBasic commands:
Future Plans
We can add more features later:
This simple approach makes load balancing available to everyone without complicated setup.