Deploying docker in windows 11
and working with docker-composer
, I am trying to enable the ssl
certificate for my setup where I want to enable nginx as a reverse proxy to allow secure websockets wss://
and for this to be redirected to my web server container, I show a Continuation of the files:
System structure:
docker-compose.yml
file:
version: "3.8"
services:
reverse-proxy:
env_file:
- .env
container_name: Proxy-Server
image: jwilder/nginx-proxy:alpine
restart: always
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
- ${LH_CERTBOT}:/etc/nginx/certs:ro
ports:
- "${LH_HOST_MACHINE_UNSECURE_HOST_PORT:-80}:80"
- "${LH_HOST_MACHINE_SECURE_HOST_PORT:-443}:443"
depends_on:
- webserver
- phpmyadmin
networks:
- lamp-network
extra_hosts:
- "${LH_WEB_SERVER_DOMAIN}:127.0.0.1"
- "${LH_PHPMYADMIN_DOMAIN}:127.0.0.1"
environment:
- DEFAULT_HOST=${LH_WEB_SERVER_DOMAIN}
- TRUST_DOWNSTREAM_PROXY=true
- ENABLE_WEBSOCKETS=true
labels:
- "lh2.setup.description=Proxy Server"
- "lh2.setup.role=reverse-proxy"
certbot:
env_file:
- .env
container_name: SSL-Generator
build:
context: ./bin/certbot
volumes:
- ${LH_CERTBOT}:/etc/app/update-ssl.sh
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DOCKER_HOST=unix:///var/run/docker.sock
depends_on:
- reverse-proxy
networks:
- lamp-network
webserver:
env_file:
- .env
container_name: ${LH_SYSTEM_NAME}-Web-Server
build:
context: ./bin/${LH_PHP_ENVIRONMENT}
restart: always
expose:
- 80
- 443
networks:
- lamp-network
depends_on:
- database
volumes:
- ${LH_PROJECT_ROOT}:/var/www/html:rw
- ${LH_PROJECT_ROOT}${LH_DOCUMENT_ROOT}:/var/www/html/public:rw
- ${LH_VHOSTS_DIR}:/etc/apache2/sites-enabled
- ${LH_PHP_INI}:/usr/local/etc/php/php.ini
- ${LH_LOG_DIR}:/var/log/apache2
- ${LH_LOG_CRON}:/var/log/cron
environment:
LH_WEB_MASTER: ${LH_WEB_MASTER}
VIRTUAL_HOST: ${LH_WEB_SERVER_DOMAIN}
LH_APACHE_DOCUMENT_ROOT: ${LH_APACHE_DOCUMENT_ROOT}
LH_DOCUMENT_ROOT: ${LH_DOCUMENT_ROOT}
HOST_MACHINE_MYSQL_PORT: ${LH_HOST_MACHINE_MYSQL_PORT}
MYSQL_DATABASE: ${LH_MYSQL_DATABASE}
MYSQL_ROOT_PASSWORD: ${LH_MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${LH_MYSQL_USER}
MYSQL_PASSWORD: ${LH_MYSQL_PASSWORD}
extra_hosts:
- "host.docker.internal:host-gateway"
labels:
- "lh2.setup.description=Web Server"
- "lh2.setup.role=webserver"
...
networks:
lamp-network:
name: lamp-network
driver: bridge
in my Dockerfile:
FROM certbot/certbot
CMD chmod +x /etc/app/update-ssl.sh && ./etc/app/update-ssl.sh
What I was hoping to do:
my main idea is to set up certbot and share the interaction between containers once certbot
has been completely started; execute the certificate generation using the file /etc/app/update-ssl.sh
and restart the nginx service in the reverse-proxy
container so that it reads and obtains the ssl
certificate
The Error I get: but even though the certbot container is assembled, it does not start and the log shows this error:
2023-09-25 16:09:10 usage: 2023-09-25 16:09:10 certbot [SUBCOMMAND] [options] [-d DOMAIN] [-d DOMAIN] ... 2023-09-25 16:09:10 2023-09-25 16:09:10 Certbot can obtain and install HTTPS/TLS/SSL certificates. By default, 2023-09-25 16:09:10 it will attempt to use a webserver both for obtaining and installing the 2023-09-25 16:09:10 certificate. 2023-09-25 16:09:10 certbot: error: Unable to open config file: chmod +x /etc/app/update-ssl.sh && ./etc/app/update-ssl.sh. Error: No such file or directory
Expectation:
Although the errors are related to mounting and executing the file, fixing it does not guarantee that my script /etc/app/update-ssl.sh
will do what I expect:
File /etc/app/update-ssl.sh
:
#!/bin/sh
# Define variables
WEB_ROOT="${LH_PROJECT_ROOT}${LH_DOCUMENT_ROOT}"
# Run Certbot to obtain the SSL certificate
certbot certonly --webroot --webroot-path="$WEB_ROOT" --email "${LH_WEB_MASTER}" --agree-tos -d "${LH_WEB_SERVER_DOMAIN}" -d "${LH_PHPMYADMIN_DOMAIN}"
# Check if the certificate was obtained successfully
if [ $? -eq 0 ]; then
echo "Certificate obtained successfully. Restarting Nginx in the reverse-proxy container..."
# Restart Nginx in the reverse-proxy container using Docker
docker exec -it reverse-proxy service nginx restart
else
echo "Certificate acquisition failed."
fi
# Start Certbot's renewal process in the background
certbot renew --quiet --no-self-upgrade &
# Keep the container running
exec "$@"
In short, I don't even know if what I'm doing will work or if I'm already doing the SSL certificate implementation wrong to begin with.
Questions:
I am in the right way to get it working like expected? sug: yes/notHow do I solve the error of mounting the.sh
file to run it fromCMD
(when the container starts up).Although I have not yet tried the script file/etc/app/update-ssl.sh
I would like it, it is not clear to me if it will fulfill the intention of restarting the nginx service in a separate container.
Final Objective: Enable websocket in a LAMP+reverse-proxy environment in docker, for the development of subsystems: chat, notifications and product inventory balance in real time.
Context: Before making this publication I have tried to exhaust my research capacity and the publications on this site and the site in English, even other sites are not focused on covering the scenario that I present, therefore, the progress I have is a hybrid of several setups.
--UPDATE--
I have been investigating the issue and from the result I have apparently managed to install the certificate, at least I have not lost access via port 80, but now it gives me an error 500, which I cannot find in the error logs, to get to At this point I have updated the setup, the environment configuration code in docker-compose.yaml
is no longer the same:
version: "3.8"
services:
reverse-proxy:
env_file:
- .env
container_name: Proxy-Server
image: nginxproxy/nginx-proxy
restart: always
volumes:
- conf:/etc/nginx/conf.d
- certs:/etc/nginx/certs
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- dhparam:/etc/nginx/dhparam
- /var/run/docker.sock:/tmp/docker.sock:ro
ports:
- "${LH_HOST_MACHINE_UNSECURE_HOST_PORT:-80}:80"
- "${LH_HOST_MACHINE_SECURE_HOST_PORT:-443}:443"
depends_on:
- webserver
- phpmyadmin
networks:
- lamp-network
environment:
- TRUST_DOWNSTREAM_PROXY=true
- ENABLE_WEBSOCKETS=true
labels:
com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"
privileged: true
nginx-ssl:
env_file:
- .env
container_name: SSL-Generator
image: nginxproxy/acme-companion
volumes:
- certs:/etc/nginx/certs
- acme:/etc/acme.sh
- vhost:/etc/nginx/vhost.d
- dhparam:/etc/nginx/dhparam
- html:/usr/share/nginx/html
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
NGINX_PROXY_CONTAINER: Proxy-Server
DEFAULT_EMAIL: ${LH_WEB_MASTER}
depends_on:
- reverse-proxy
networks:
- lamp-network
webserver:
env_file:
- .env
container_name: ${LH_SYSTEM_NAME}-Web-Server
build:
context: ./bin/${LH_PHP_ENVIRONMENT}
restart: always
expose:
- 80
- 443
networks:
- lamp-network
depends_on:
- database
volumes:
- ${LH_PROJECT_ROOT}:/var/www/html:rw
- ${LH_PROJECT_ROOT}${LH_DOCUMENT_ROOT}:/var/www/html/public:rw
- ${LH_VHOSTS_DIR}:/etc/apache2/sites-enabled
- ${LH_PHP_INI}:/usr/local/etc/php/php.ini
- ${LH_LOG_DIR}:/var/log/apache2
- ${LH_LOG_CRON}:/var/log/cron
environment:
VIRTUAL_HOST: ${LH_WEB_SERVER_DOMAIN}
LETSENCRYPT_HOST: ${LH_WEB_SERVER_DOMAIN}
LH_WEB_MASTER: ${LH_WEB_MASTER}
LH_APACHE_DOCUMENT_ROOT: ${LH_APACHE_DOCUMENT_ROOT}
LH_DOCUMENT_ROOT: ${LH_DOCUMENT_ROOT}
HOST_MACHINE_MYSQL_PORT: ${LH_HOST_MACHINE_MYSQL_PORT}
MYSQL_DATABASE: ${LH_MYSQL_DATABASE}
MYSQL_ROOT_PASSWORD: ${LH_MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${LH_MYSQL_USER}
MYSQL_PASSWORD: ${LH_MYSQL_PASSWORD}
extra_hosts:
- "host.docker.internal:host-gateway"
labels:
- "lh2.setup.description=Web Server"
- "lh2.setup.role=webserver"
...
phpmyadmin:
env_file:
- .env
container_name: ${LH_SYSTEM_NAME}-phpmyadmin
image: phpmyadmin/phpmyadmin
restart: always
expose:
- 80
- 443
depends_on:
- database
environment:
VIRTUAL_HOST: ${LH_PHPMYADMIN_DOMAIN}
LETSENCRYPT_HOST: ${LH_PHPMYADMIN_DOMAIN}
PMA_HOST: database
PMA_PORT: 3306
PMA_USER: root
PMA_PASSWORD: ${LH_MYSQL_ROOT_PASSWORD}
MYSQL_ROOT_PASSWORD: ${LH_MYSQL_ROOT_PASSWORD}
MYSQL_USER: ${LH_MYSQL_USER}
MYSQL_PASSWORD: ${LH_MYSQL_PASSWORD}
UPLOAD_LIMIT: ${LH_UPLOAD_LIMIT}
MEMORY_LIMIT: ${LH_MEMORY_LIMIT}
volumes:
- /sessions
- ${LH_PHP_INI}:/usr/local/etc/php/conf.d/php-phpmyadmin.ini
networks:
- lamp-network
labels:
- "lh2.setup.description=phpMyAdmin"
- "lh2.setup.role=phpmyadmin"
...
volumes:
vhost:
html:
certs:
acme:
conf:
dhparam:
networks:
lamp-network:
name: lamp-network
driver: bridge
Actual context:
What I am trying is to be able to anchor the communication between the reverse-proxy and the webserver and phpmyamin container via docker's intranet... implementing VIRTUAL_HOST
, what I do believe is that the container that runs Apache, despite having the port 443 open the apache is not configured to do anything with it, I have added the configuration of that virtual host to this post previously, remember that I am doing all this from the YAML
file, I am looking for a way to avoid the terminal.. .for installation automation reasons, now all this revolves around websocket consumption; I don't see a way to anchor the SSL certificate to both the proxy and the web server, I thought the idea was to consume the SSL only with the proxy and for it to communicate only through port 80 to consume the containers... but my mistake now What I am paying for is wanting to also consume port 443 of the web server container, therefore also that of phpmyadmin... and to create compatibility with a future production environment if they are implementing it.