Configure redirection from http to https in a local environment

1. The problem I’m having:

I can’t configure redirection from http to https in a docker environment.
When I tried to reach http://localhost:8080 I’m redirected to http://localhost instead of https://localhost:8081. Btw, when I go to https://localhost:8081 it’s works perfectly.

2. Error messages and/or full log output:

curl -vL localhost:8080
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.1.2
> Accept: */*
>
< HTTP/1.1 302 Found
< Location: https://localhost:443/
< Server: Caddy
< Date: Sat, 10 Jun 2023 15:51:36 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact
* Clear auth, redirects to port from 8080 to 443
* Issue another request to this URL: 'https://localhost:443/'
*   Trying 127.0.0.1:443...
* connect to 127.0.0.1 port 443 failed: Connection refused
*   Trying [::1]:443...
* connect to ::1 port 443 failed: Connection refused
* Failed to connect to localhost port 443 after 0 ms: Couldn't connect to server
* Closing connection 1
curl: (7) Failed to connect to localhost port 443 after 0 ms: Couldn't connect to serverp

3. Caddy version:

2.5.2

4. How I installed and ran Caddy:

I’ve installed caddy through a docker container.

docker-compose.yml

version: '3.9'

services:
  caddy:
    image: caddy:2.5.2
    restart: unless-stopped
    environment:
      SERVER_NAME: ${SERVER_NAME:-localhost}
    ports:
      - "${CADDY_PORT:-8080}:80"
      - "${CADDY_HTTPS_PORT:-8081}:443"
    volumes:
      - './.docker/caddy/Caddyfile:/etc/caddy/Caddyfile:ro'
      - ./public:/srv/app/public

  php:
    build:
      context: .docker/php
      dockerfile: Dockerfile.dev
    restart: unless-stopped
    depends_on:
      - caddy
    volumes:
      - ./:/srv/app

Dockerfile.dev

FROM php:8.2-fpm

RUN apt-get update -y

RUN apt-get install -y \
    libicu-dev \
    zip \
    libzip-dev \
    gettext \
    libpq-dev;

RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql

RUN docker-php-ext-install \
    pdo \
    pdo_pgsql \
    pgsql \
    zip \
    intl;

USER www-data

WORKDIR /srv/app

COPY --chown=www-data:www-data . .

a. System environment:

Docker

b. Command:

docker compose up

c. Service/unit/compose file:

d. My complete Caddy config:

{$SERVER_NAME}:80 {
    redir https://{$SERVER_NAME}:443{uri}
}

{$SERVER_NAME}:443 {
    root * /srv/app/public
    php_fastcgi php:9000
    encode zstd gzip
    file_server
}

You can configure the http_port and https_port global options to configure the port Caddy uses for listening and for redirects:

Remember to adjust your container port mappings afterwards to match.

The reason this doesn’t work is you’re using port 443 here which obviously isn’t the port you need to use externally to connect. If you wrote 8081 there it would work.

That’s quite an old version at this point. Please upgrade to the latest, v2.6.4.

You’re missing a volume for /data, which is important to avoid losing certificates when the container is recreated. See our recommended docker-compose setup:

Thank you. It works :). I’ve also updated the the docker-compose file with the volumes.
It’s possible to add a certificate to avoid the browser asking me to accept the risk to reach the site?

There is a link to get the different environment variables available (for example the https port)?

{$SERVER_NAME}:80 {
    redir https://{$SERVER_NAME}:8081{uri}
   # redir https://{$SERVER_NAME}:{$CADDY_HTTPS_PORT}{uri} doesn't work :(
}

{$SERVER_NAME}:443 {
    root * /srv/app/public
    php_fastcgi php:9000
    encode zstd gzip
    file_server
}

Yes, see that last link I sent above, it explains how to get the Caddy’s root CA cert out of your container so your host machine trusts it.

Environment variables are things you define.

If you mean global options, I linked that above.

Ok thx. Then this line redir https://{$SERVER_NAME}:{$CADDY_HTTPS_PORT}{uri} doesn’t work. I’m redirected to localhost. Same curl output. But this work redir https://{$SERVER_NAME}:8081{uri}

Did you define that env var on your container? Did you recreate the container after setting that env var?

Yes.

version: '3.9'

services:
  caddy:
    image: caddy:2.6.4
    restart: unless-stopped
    environment:
      SERVER_NAME: ${SERVER_NAME:-localhost}
    ports:
      - "${CADDY_PORT:-8080}:80"
      - "${CADDY_HTTPS_PORT:-8081}:443"
    volumes:
      - './.docker/caddy/Caddyfile:/etc/caddy/Caddyfile:ro'
      - ./public:/srv/app/public
      - caddy_data:/data
      - caddy_config:/config
docker compose up --build --force-recreate -d

Edit: My bad. I was using the variable define in port and not in environment

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