This setup uses a global nginx proxy server to distribute incoming requests to different services based on their domain name. It eliminates the need for a local nginx server on the host and automates Let's Encrypt provisioning.
git clone --depth=1 --branch=main https://github.com/umexco/main-nginx-proxy.git \
&& rm -rf ./main-nginx-proxy/.gitBefore starting any docker containers, run
docker network create main-nginx-proxyto create a global proxy network.
All containers that need to communicate with the proxy server must join this network.
Customize the email address in docker-compose.yaml at DEFAULT_EMAIL= to obtain certificates
docker compose up -dTo make a service accessible through the proxy server,
set the following environment variables in its docker-compose.yaml file:
LETSENCRYPT_HOST: the target domain for the serviceVIRTUAL_HOST: the target domain for the serviceVIRTUAL_PORT: the service port where the service is accessible
To run a service behind a sub-route, also add the following environment variables:
VIRTUAL_PATH: path, e.g.VIRTUAL_PATH=/myappVIRTUAL_DEST=/as rewrite base
The VIRTUAL_PORT may vary depending on the configuration.
For example, if you started your application web server using php artisan serve --port=8765, the variable should be set to VIRTUAL_PORT=8765 accordingly.
services:
helloworld:
image: nginxdemos/hello
container_name: hello-world
environment:
- LETSENCRYPT_HOST=domain.com
- VIRTUAL_HOST=domain.com
- VIRTUAL_PORT=80
networks:
- main-nginx-proxy
restart: unless-stopped
networks:
main-nginx-proxy:
external: trueFinally start the service
docker compose up -dAfter a few seconds, the new service should be available at the configured domain. The nginx proxy automatically detects the new service after launch and obtains a certificate for the domain if required.
Finished
To make services that run on the host machine available through the proxy service, use the following steps.
We assume, the service should use the domain example.com and is running on port 8765
server {
listen 80;
server_name test123.com;
location / {
proxy_pass http://host.docker.internal:8765;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
listen 443 ssl;
ssl_certificate /etc/nginx/certs/test123.com.crt;
ssl_certificate_key /etc/nginx/certs/test123.com.key;
}volumes:
- ./docker/nginx/vhost/example.com.conf:/etc/nginx/vhost.d/example.com.confProbably recreate the container if your proxy service was already running.
docker compose up -d --force-recreate nginx
IMPORTANT: Before creating this vhost, make sure you have the cert for the TLD with LETSENCRYPT_HOST=domain.com,www.domain.com up and running!
environment:
- LETSENCRYPT_HOST=domain.com,www.domain.com
- VIRTUAL_HOST=domain.comFirst restart to obtain the www included cert:
docker compose up -d --force-recreate nginxThen create a config www.domain.com.conf with this content. Using variables in the SSL path is unfortunately not possible due to permissions.
server {
listen 80;
listen [::]:80;
server_name www.domain.com;
return 301 https://domain.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.domain.com;
ssl_certificate /etc/nginx/certs/domain.com.crt;
ssl_certificate_key /etc/nginx/certs/domain.com.key;
return 301 https://domain.com$request_uri;
}Mount it
volumes:
- ./docker/nginx/vhost/www.domain.com.conf:/etc/nginx/conf.d/www.domain.com.conf:roFinally restart the nginx-proxy
docker compose up -d --force-recreate nginxIf you need adjustments, e.g. to increase the file upload size you can adjust the ./docker/nginx/conf/custom.conf or create a new config file.
Make sure to reload or restart the nginx after it.
docker compose up -d --force-recreate nginx