Skip to content

Add support for kamal-proxy's path-prefix #1551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ACPK
Copy link

@ACPK ACPK commented May 13, 2025

This PR introduces support for kamal-proxy's new path-based routing feature. For applications that split their traffic to different services based on the request path, you can use path-based routing to mount services under different path prefixes.

Begin by deploying the primary app that doesn’t require a path_prefix. Once that’s live, deploy your secondary app with the same host and the path_prefix feature.

Example Usage

# config/deploy.yml
...
servers:
  web:
    - 192.168.0.1

proxy:
  # Don't include ssl (TLS) options
  hosts:
    - callred.com
  path_prefix: '/api'
  # strip_path_prefix: true
...

NOTE: SSL options (e.g., ssl: true) should be set in the proxy for the app without a path_prefix, so the app above uses SSL by inheritance. Repeating the SSL settings here will cause the deploy to fail with a TLS error in the console.

With the above configuration, all incoming requests to https://callred.com/api/* will be routed to your service. By default, the path prefix will be stripped from the request before it is forwarded upstream. So in the example above, a request to /api/users/123 will be forwarded to the secondary app as /users/123. To instead forward the request with the original path (including the prefix), set: strip_path_prefix: true

Testing until added to main branch

For testing, I used the following setup in my Gemfile:

gem 'kamal', require: false, git: 'https://github.com/acpk/kamal.git', branch: 'kamal-proxy-path-prefix'

Deployment was performed with:

bundle exec kamal deploy

@ACPK ACPK changed the title Add support for path-prefix in Kamal proxy configuration Add support for kamal-proxy's path-prefix May 14, 2025
Copy link

@brgmn brgmn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some small newline fixes. The rest looks fine! Thanks for your integration work! Looking forward to being able to use path_prefix natively in kamal!

#
# For applications that split their traffic to different services based on the request path,
# you can use path-based routing to mount services under different path prefixes.
path_prefix: '/api'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something seems to be wrong with newlines here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ACPK Sorry. My fault. I just didn't understand the markdown logic. After looking at it again everything seems to be fine.

@ACPK ACPK requested a review from brgmn May 15, 2025 18:29
@shiny
Copy link

shiny commented May 26, 2025

I was wondering if there's any update on merging the PR?

@olivermt
Copy link

I have been using it a bit from the fork and I wonder if we should land support for multiple paths before merging this?

Most scenarios where you need path routing its often complex enough that you need multiple sets.

Like I need to map up an img resizer proxy, oidc auth callbacks and an api to the same backend, but atm I am forced to put all that behind a common root.

Gradual migration is also impossible with the current config capabilities where you want to map one and one route over with the rest going to the legacy etc.

I can solve this in the load balancer layer in front, but then I cant multiplex my nodes anymore which gives a lot of redundancy for free.

@shainegordon
Copy link

I have been using it a bit from the fork and I wonder if we should land support for multiple paths before merging this?

Most scenarios where you need path routing its often complex enough that you need multiple sets.

Like I need to map up an img resizer proxy, oidc auth callbacks and an api to the same backend, but atm I am forced to put all that behind a common root.

Gradual migration is also impossible with the current config capabilities where you want to map one and one route over with the rest going to the legacy etc.

I can solve this in the load balancer layer in front, but then I cant multiplex my nodes anymore which gives a lot of redundancy for free.

I agree, regex patterns (like you can do with Nginx/Traefik) would be a great addition, but I still think this current PR, as is, can help a lot of people adopt Kamal, even if it does require some backend fudgery.

I’d rather this is merged now, and extended later, than having to wait (obviously there is the option of using the fork)

@olivermt
Copy link

I dont mean such complex things. As far as I can see you can supply multiple paths to the underlying kamal-proxy in go? I just mean having a list of paths as a config option.

Regex etc would be cool later.

@kevinmcconnell
Copy link
Collaborator

@ACPK we do support multiple path prefixes in the proxy now. (The comment you quoted was from before we added that ability, which is why it sounds like it's not supported. But it landed a little later on.)

I agree that allowing a list format makes sense here. Same as we do with host/hosts.

@aarroisi
Copy link

Also waiting for this to be merged. Very useful to simplify our setup.

@olivermt
Copy link

olivermt commented Jun 10, 2025

I have two questions..

  1. What is the process to getting this merged? It is listed as approved, what does that mean in practice, core commiter will merge it when they have time?
  2. Do you agree on getting a list of paths in to pass through @ACPK ? If so do you want help implementing it or do you want to take it on?

@ACPK
Copy link
Author

ACPK commented Jun 10, 2025

@olivermt Confirmed that this commit already supports multiple paths (e.g., path_prefix: '/api,/store').

@olivermt
Copy link

@ACPK ah we will not surface it as a "proper" yaml-list (as in dash list vertically)? I'll do some testing with the multiple paths right now in our staging env and report back :)

@kevinmcconnell
Copy link
Collaborator

Would be nice to support both path_prefix (a string) and path_prefixes (a list).

That's how host/hosts works at the moment, and it makes the yaml a bit more readable.

@ACPK
Copy link
Author

ACPK commented Jun 10, 2025

Would be nice to support both path_prefix (a string) and path_prefixes (a list).

That's how host/hosts works at the moment, and it makes the yaml a bit more readable.

@kevinmcconnell Don't see anything about that in Kamal-proxy's readme. I only saw the code below in a commit message that wasn't part of a pull request.

"kamal-proxy deploy myservice --path-prefix=/app,/api ....""

@olivermt
Copy link

Would be nice to support both path_prefix (a string) and path_prefixes (a list).
That's how host/hosts works at the moment, and it makes the yaml a bit more readable.

@kevinmcconnell Don't see anything about that in Kamal-proxy's readme ;) I only saw the code below in a commit message that wasn't part of a pull request.

"kamal-proxy deploy myservice --path-prefix=/app,/api ....""

He means that host / hosts is how we configure hosts in kamal I think?

I am suggesting that configuring host passes through as-is to --path-prefix=... where as hosts with list will construct a --path-prefix=string1,string2,string3.

@kevinmcconnell
Copy link
Collaborator

kevinmcconnell commented Jun 10, 2025

He means that host / hosts is how we configure hosts in kamal I think?

Exactly, yes! For most people, Kamal is the API they interact with, so Kamal Proxy's docs aren't super comprehensive at the moment. It's on my list to do big sweep and document everything soon, though!

FWIW the pattern we've been following on the proxy side for any items that can be lists is that you can either use the flag multiple times, or you can use a comma-delimited list. So you can do this:

--host=one --host=two --host=three ...

Or

--host=one,two,three ...

Or you can mix & match those forms if you want.

So on the Kamal side, we can allow people to enter items as a list, and Kamal can take care of formatting that into a suitable command line for the proxy. We can provide both path_prefix and path_prefixes options on the Kamal side, and both of those translate into some usage of Kamal Proxy's --path-prefix. (Same as @olivermt is suggesting.)

@ACPK
Copy link
Author

ACPK commented Jun 10, 2025

Thanks, @kevinmcconnell! The proxy-path issue, where commenters requested support for multiple paths, didn’t include any references to the implementation of the additional multiple paths feature (e.g., no linked commits), so we weren’t aware it was added later. @olivermt, feel free to submit a PR to tackle this! :)

@olivermt
Copy link

olivermt commented Jun 13, 2025

@ACPK I submitted a PR to your fork so your contribution would not disappear, you can update this PR once you merge to your fork.

Edit: I messed up when cleaning up the docs, please hold!

@olivermt
Copy link

@ACPK ok you're up! I didn't realize that if you comment out something from the sample yaml it wont validate, so when I cleaned up the docs and made PR it stopped working because the validator failed me :)

Works like a charm it seems, I have a fairly complex thing deployed now and the sort-by length seems to work exactly as advertised with /foo going to my little spa-hosting docker and /foo/files going to the backend server as one of 5-6 routes tackled by that service.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants