Redirecting www to non-www in Caddyfile

1. Caddy version (caddy version):

2

2. How I run Caddy:

Caddy is started by Docker Compose and I pass in a SERVER_NAME environment variable.

a. System environment:

Docker Compose that runs a Symfony PHP application.

b. Command:

SERVER_NAME=example.com docker-compose up -d

c. Service/unit/compose file:

docker-compose.yaml

version: "3.7"
services:
    caddy:
        build:
            context: .
            target: api_caddy
        depends_on:
            - php
        environment:
            SERVER_NAME: ${SERVER_NAME:-localhost, caddy:80}
        restart: unless-stopped
        volumes:
            - php_socket:/var/run/php
            - caddy_data:/data
            - caddy_config:/config
        ports:
            # HTTP
            - target: 80
              published: 80
              protocol: tcp
            # HTTPS
            - target: 443
              published: 443
              protocol: tcp
            # HTTP/3
            - target: 443
              published: 443
              protocol: udp
    php:
        build:
            context: .
            target: php_prod
        volumes:
            - php_socket:/var/run/php

volumes:
    php_socket:
    caddy_data:
    caddy_config:

d. My complete Caddyfile or JSON config:

Caddyfile

{
    # Debug
    {$DEBUG}
    # HTTP/3 support
    servers {
        protocol {
            experimental_http3
        }
    }
}

{$SERVER_NAME}

log

route {
    root * /srv/api/public

    php_fastcgi php:9000
    encode zstd gzip
    file_server
}

3. The problem I’m having:

I am unable to figure out how to get www.example.com to redirect to example.com.

4. Error messages and/or full log output:

When I run everything as set up above, I can only access the site through example.com. If I try to access it through www.example.com I get the following:

This site can’t provide a secure connection

www.example.com sent an invalid response.

ERR_SSL_PROTOCOL_ERROR

This makes sense since I am only creating a certificate for example.com and not www.example.com. However, I am having a hard time figuring out how to add www to non-www redirection with my current setup.

5. What I already tried:

I’ve seen examples online saying to do the following:

www.example.com {
    redir https://example.com{uri} permanent
}

But when I add this, I get a 522 connection timeout on example.com and the same ERR_SSL_PROTOCOL_ERROR when going to www.example.com.

The full Caddyfile, I added looked like this:

{
    # Debug
    {$DEBUG}
    # HTTP/3 support
    servers {
        protocol {
            experimental_http3
        }
    }
}

{$SERVER_NAME}

www.example.com {
    redir https://example.com{uri} permanent
}

log

route {
    root * /srv/api/public

    # php_fastcgi unix//var/run/php/php-fpm.sock
    php_fastcgi php:9000
    encode zstd gzip
    file_server
}

Now, I’d obviously like to use the $SERVER_NAME to make this dynamic but I figured I should try the less dynamic approach first to see if I could get the

6. Links to relevant resources:

Inspiration for Caddyfile and have removed services I do not use: api-platform/Caddyfile at main · api-platform/api-platform · GitHub

If you want to use more than one site block, you must wrap each site with { } braces. See the docs for the structure of the Caddyfile:

In particular, you’ll need to change the {$SERVER_NAME} to open a block by adding { at the end of the line, then indent everything below it once. Then you can put your www.example.com site either before that site block, or after it.

1 Like

Thanks, @francislavoie!

The site blocks makes a lot of sense after reading the provided document.

I’ve set up a demo site dev.projectwatts.com and see that typing the following URLs into the browser redirect appropriately:

  • dev.projectwatts.comhttps://dev.projectwatts.com/
  • http://dev.projectwatts.comhttps://dev.projectwatts.com/
  • www.dev.projectwatts.comhttps://dev.projectwatts.com/
  • http://www.dev.projectwatts.com/https://dev.projectwatts.com/

However, when I type in https://www.dev.projectwatts.com, I get the following error:

This site can’t provide a secure connection
www.dev.projectwatts.com uses an unsupported protocol.
ERR_SSL_VERSION_OR_CIPHER_MISMATCH

I’ve updated the Caddyfile to the following:

{
    # Debug
    {$DEBUG}
    # HTTP/3 support
    servers {
        protocol {
            experimental_http3
        }
    }
}

{$SERVER_NAME} {

    log

    route {
        root * /srv/api/public

        php_fastcgi php:9000
        encode zstd gzip
        file_server
    }

}

https://www.{$SERVER_NAME}, http://www.{$SERVER_NAME}, www.{$SERVER_NAME} {
    redir https://{$SERVER_NAME}{uri}
}

Any idea why all the other URLs would work correctly but trying to navigate to https://www.dev.projectwatts.com would fail?

Thank you very much for taking your time, it is much appreciated!

Looking at the response from a request to dev.projectwatts.com, it looks like your server is fronted by CloudFlare. It’s not reaching Caddy directly. I think CloudFlare isn’t configured with www.dev.projectwatts.com probably.

1 Like

That was indeed the issue. Thank you very much for taking the time to help me debug this!

1 Like

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