Www to non-www on :80 port server

1. The problem I’m having:

What I am doing

Hey everyone! So I have a setup with Docker Composer and Coolify. In that Docker container, I have my caddy container.
Setup: Caddy(coolify) → [MyCaddy(docker) → backend+frontend(docker)]

MyCaddy file is very simple; it just chooses when to redirect to the backend or to the frontend depending on the presence of ‘api’ in the URI.

My caddy does not provide https; that is handled by Coolify’s first caddy proxy.
This setup works fine in production with non-www.

The problem!

The problem is that I would like to redirect www to non-www for this use case, where I do not have a site like ‘example.com’ and instead I have ‘:80’. I am aware of this documentation Common Caddyfile Patterns — Caddy Documentation

2. Caddy version:

Running in docker. Container gotten from here https://hub.docker.com/_/caddy, with latest version (2.8.4 at the time of writing)

3. How I installed and ran Caddy:

With docker compose, where all my servers are run.

# docker-compose.yml
...
  caddy:
    image: "caddy"
    ports:
      - 8004:80
    volumes:
      - ./caddy:/etc/caddy
      - caddy_data:/data
      - frontend_build:/srv/frontend

a. My complete Caddy config:

:80 {
	handle /api/* {
		reverse_proxy backend:8000 {
			header_up X-Forwarded-Proto https
		}
	}

	handle {
		root * /srv/frontend/
		file_server
	}
}

4. Links to relevant resources:

My caddy file was based on: dist/config/Caddyfile at master · caddyserver/dist · GitHub

5. Last words

Thank you so much for taking the time, your help is much appreciated :slight_smile:

You can skip needing to do this if you configure trusted_proxies so that Caddy recognizes that the request comes from a trusted server, and to retain the original X-Forwarded-* headers.

I don’t really understand the question then. Why not follow that pattern? Shouldn’t you do that redirect on the Caddy server that handles TLS/certs? That makes the most sense, rather than trying to redirect on the deeper one which is closer to your app.

1 Like

Regarding the X-Forwarded-Proto, this is on my to-do list for sure, but it does not matter for this issue (I think). Sorry, I probably should have removed this part from the question to not distract from the problem at hand.

The question is:

Given my caddy file, how can I redirect www. requests to non-www, keeping in mind that my caddy file is defined as:

:80 {
	handle /api/* {
		...
  	}
	handle {
		...
	}
}

For example, if the user requests www.example1.com, my caddy will redirect to example.com.

The following is merely illustrative of what I am trying to accomplish; it does not work or exist:

# Bellow does not work
www* {
	redir https://{host}{uri}
}

:80 {
	handle /api/* {
		...
  	}
	handle {
		...
	}
}

Why is it like this?

R: Versatality

  1. I like having all my logic and communication between servers contained in a single docker-compose and network. This way, if I need to move my app elsewhere, it is easier; just grab the docker-compos file. I also like having a single entrypoint (my caddy) to worry about/configure and know that from that point on everything should work just like in local development.

  2. Having it on port 80 and taking advantage of the docker-compose profiles feature, I can easily swap between development and production environments; I just need to docker compose --prodile (prod or dev) up -d and be good to go. Having it work with ‘localhost’ and ‘example.com’ by just changing a word in the command.

  3. I want to keep the Coolify part as simple as possible so not to mess with its proxy (Caddy). If I desire to change it to something else like Versel or Dokploy (I think, not sure if they provide this), I will just grab the docker-compose file and make sure that my domain points to ‘my caddy’ deployed there. I do not want to have to learn about how to configure their proxies (let’s imagine the other uses Traefik or Nginx).

As it is currently in Coolify, I just need to present my docker-compose file and tell that ‘example. com’ points to the ‘my caddy’ container.

I imagine the alternatives are similar to this.

Because of those reasons, it is really useful to me to have something similar to the caddy file that I presented.

Sorry for the delay, busy summer.

Right, but you still need a certificate for it to work, and since you have a front instance of Caddy, you should do it in the same server that owns the certificate. It’s weird to proxy down to only get served a redirect.

That said, this should work:

:80 {
	@www header_regexp Host ^www.(.*)$
	redir @www https://{re.1}{uri} 308

	handle /api/* {
		...
	}
	handle {
		...
	}
}
1 Like

Hey there! Sorry for the late reply; I had to step away for a while. Just tested this and it works perfectly. Thank you so much for helping a stranger.

Cheers!

2 Likes

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