'docker-compose, wsl2 and self signed ssl certificate

So i'm using docker-compose to set up local dev environments while I'm working on Wordpress sites. And now i'm trying to fix so I can get an self signed ssl certificate for that local dev environment. But all I end up with when i'm trying to visit the site is ERR_CONNECTION_CLOSED and nothing in the error log or anything.

So this is how my docker-compose.yml file looks like:

version: '3.1'
services:

  wordpress:
    image: wordpress:5.8-fpm
    restart: always
    container_name: wordpress
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - ./wp:/var/www/html
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
    depends_on:
      - db

  db:
    image: mysql:5.7
    restart: always
    container_name: db
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql
    ports:
      - "8086:3306"

  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - '80:80'
      - '443:433'
    volumes:
      - ./nginx:/etc/nginx/conf.d
      - ./logs/nginx:/var/log/nginx
      - ./wp:/var/www/html
      - ./certs:/etc/cert
    depends_on:
      - wordpress
    restart: always

  mailhog:
    image: mailhog/mailhog
    ports:
      - "1025:1025" # smtp server
      - "8025:8025" # web ui

volumes:
  db:

And this is how my nginx config file looks like:

server {
    listen      80;
    listen [::]:80;
    server_name dev.mydomain.com;

     root /var/www/html;
     index index.php;

     access_log /var/log/nginx/access.log;
     error_log /var/log/nginx/error.log;

     location / {
         try_files $uri $uri/ /index.php?$args;
     }

     location ~ \.php$ {
         try_files $uri =404;
         fastcgi_split_path_info ^(.+\.php)(/.+)$;
         fastcgi_pass wordpress:9000;
         fastcgi_index index.php;
         include fastcgi_params;
         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
         fastcgi_param PATH_INFO $fastcgi_path_info;
     }

}

server {
    listen      443           ssl ssl;
    server_name               dev.mydomain.com;
    
    root /var/www/html;
    index index.php;

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ssl_certificate           /etc/cert/mydomain.com.crt;
    ssl_certificate_key       /etc/cert/mydomain.com.key;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass wordpress:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

and to create the cert files I used openssl on the wsl2 (ubuntu 20.04) with this command:

openssl req -newkey rsa:2048 -nodes -keyout mydomain.com.key -x509 -days 365 -out mydomain.com.crt

So I can visit the site without https, and everything is working fine. But when i'm trying to visit the site with https I get the error ERR_CONNECTION_CLOSED, and I have no idea where to start. I have tried many different solutions but so far no luck.

Also good to be know that I have pointed dev.mydomain.com to 127.0.0.1 in the dns. And also added it in my host file on Windows.

But I have a feeling that there is something i'm missing here.

And my plan is to have a wildcard domain pointed to localhost, and make the docker-compose installation more or less automatic to set up self signed certificates when I run docker-compose up -d

So I hope someone out there have the solution or can point me to the right direction :)



Solution 1:[1]

For anyone that will look at this, I found an solution that works really good for me. What I ended up doing was to run it with ngrok instead. And have that implement in the docker-compose file. I can choose to jsut run with an domain name that ngrok gives me. Or use my own(This needs a premium account if so). So this is how my docker-compose.yml file look like now:

version: '3.1'
networks:
  default:

services:

  wordpress:
    image: wordpress:5.9.0-php8.0-fpm
    restart: always
    container_name: wordpress
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - ./wp:/var/www/html
      - ./uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
    depends_on:
      - db

  db:
    image: mysql:5.7
    restart: always
    container_name: db
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql
    ports:
      - "8086:3306"

  nginx:
    image: nginx:latest
    container_name: nginx
    networks:
      - default
    ports:
      - '80:80'
    volumes:
      - ${NGINX_CONF_DIR:-./nginx}:/etc/nginx/conf.d
      - ${NGINX_LOG_DIR:-./logs/nginx}:/var/log/nginx
      - ${WORDPRESS_DATA_DIR:-./wp}:/var/www/html
    depends_on:
      - wordpress
    restart: always

  ngrok:
    image: wernight/ngrok:latest
    ports:
      - '4040:4040'
    links:
      - nginx
    environment:
      NGROK_PROTOCOL: http
      NGROK_REGION: eu
      NGROK_PORT: nginx:80
      NGROK_AUTH: my auth key
      NGROK_HOSTNAME: if I want my own domain otherwise comment this out
    depends_on:
      - nginx
    networks:
      - default

  mailhog:
    image: mailhog/mailhog
    ports:
      - "1025:1025" # smtp server
      - "8025:8025" # web ui

volumes:
  db:

As you can see here i'm using wernight/ngrok docker container to make this work

Solution 2:[2]

Local dev: Be your own CA

This is the best tuturial you would have on the web for creating ssl locally

https://www.youtube.com/watch?v=oxDUdjbdfR0&t=1558s

Make sure to install your root cert into the browser

otherwise, it won't work


Production : Just use certbot and it will do the trick command will be like this

certbot --nginx -d ${SERVER2} -d ${SERVER1}

Solution 3:[3]

Looks like you may have a DNS resolution problem. Use the Docker embeded DNS resolver inside the nginx location:

resolver 127.0.0.11

I would also recommend use of a root CA and the ssl_trusted_certificate directive.

CURITY EXAMPLE

For something to compare against, see this Curity example, which uses DNS via the hosts file, wildcard certs, a root CA, docker compose and nginx:

This is quite an advanced sample with two forms of Mutual TLS, though it also has a lot in common with your requirements. So hopefully it will help you to resolve your problem.

Solution 4:[4]

HTTPS uses port 443, but SSL/TLS does not itself use any port. In your docker config , there is a line that contains - '443:433' . Is this a typo or is your actual port mapping? For network port mapping, check this document: https://docs.docker.com/compose/networking/

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 zarex360
Solution 2 Abd-Elaziz Sharaf
Solution 3 Gary Archer
Solution 4 ssavva05