Converting some Apache host-based routing and reverse proxy


1. The problem I’m having:

None, just wondering how to convert some Apache configuration to Caddy, perhaps in a better way.

In particular, I have the following apache.conf part that handles some rewrite rules depending on the value of the hostname being served, and doing some path rewrite and reverse proxy:

RewriteCond  %{HTTP_HOST} !
RewriteRule . - [S=6]
RewriteRule    plnext/rest/(.*)$                           $1                                                             [P,NC]
RewriteRule    core/(.*)$                                  $1                                                             [P,NC]
RewriteRule    xbox/(.*)$                                  $1                                                             [P,NC]
RewriteRule    acpui/maestro/?$                                                                      [P,NC]
RewriteRule    acpui/maestro/(.*)$                         $1                                                  [P,NC]
RewriteRule    /(.*)$                                      $1                                           [P,NC]

This section reads as:

  1. If host is not
  2. Skip the next 6 rules
    n+1: if path match this, capture the end of the path, and reverse proxy it to a specific domain and path

I have about 10 sections like that, each containing not 6 but 19 rules.

See section on caddy file for the way I’m tackling this.

2. Error messages and/or full log output:


3. Caddy version:


4. How I installed and ran Caddy:

via brew (brew install caddy), and running it as “caddy run”.

a. System environment:

Mac OS, Apple M2.

b. Command:

caddy run

c. Service/unit/compose file:


d. My complete Caddy config:

:8080 {
	@p1 {

	handle @p1 {
		handle_path /plnext/rest/* {
			rewrite * /core/*
			reverse_proxy {
				header_up Host {upstream_hostport}
		handle_path /core/* {
			rewrite * /core/*
			reverse_proxy {
				header_up Host {upstream_hostport}
        # Same for each and every rule

5. Links to relevant resources:


Would you see a different way?

I thought about writing a section instead of @p1 matcher, but this causes too much duplication (because some handlers not shown here are the exact same for all domains).

That’s what snippets are for:

This won’t work, this will rewrite the URL to literally /core/*. You probably want rewrite * /core{uri}

You can use handle instead of handle_path + rewrite here, it’s redundant to strip /core from the URL and then re-add it.

If each route may change the upstream address, you could set the upstream address with vars (Caddyfile directive) — Caddy Documentation and then only have one reverse_proxy at the end which reads the address with {vars.upstream} or whatever.

Make sure to configure reverse_proxy > transport http > tls though, because https:// scheme can’t be used when using a placeholder for the address (see the last paragraph in this section of the docs: reverse_proxy (Caddyfile directive) — Caddy Documentation)

Thank you very much for all those suggestions!

Thanks again for the suggestions, as it’s working nicely!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.