'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 |