In this tutorial, we will set up an nginx reverse proxy using Docker and docker-compose. This will allow us to route HTTP requests arriving through different subdomains to web services running in different Docker containers. We will also set up a LetsEncrypt CertBot to automatically create and renew TLS certificates.
Create a new YAML file reverse-proxy.yml
and open it using an editor of your
choice:
vim reverse-proxy.yml
Insert the following:
version: '3'
services:
nginx:
image: jwilder/nginx-proxy
container_name: nginx-proxy
restart: always
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "1"
ports:
- '80:80'
- '443:443'
volumes:
- conf:/etc/nginx/conf.d
- certs:/etc/nginx/certs
- vhost:/etc/nginx/vohost.d
- html:/usr/share/nginx/html
- dhparam:/etc/nginx/dhparam
- '/var/run/docker.sock:/tmp/docker.sock:ro'
nginx-proxy-le:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: nginx-proxy-le
restart: always
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "1"
volumes:
- conf:/etc/nginx/conf.d
- certs:/etc/nginx/certs:rw
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- '/var/run/docker.sock:/var/run/docker.sock:ro'
environment:
NGINX_PROXY_CONTAINER: nginx-proxy
networks:
default:
external:
name: compose-net
volumes:
conf:
vhost:
html:
certs:
dhparam:
This docker-compose file will create two services: The nginx-proxy
container
will run the nginx reverse proxy, while nginx-proxy-le
will manage LetsEncrypt's TLS
certificates. Please note that the log files have a size limit to avoid running out of disk space.
You can of course change this. The nginx config can be found in the
conf
Docker volume (though it should not be necessary to edit it manually).
Run the following Docker command:
docker network create compose-net
If you are currently not the root
user and did not set up your user to
use Docker, you may have to run this command with sudo
privileges.
Use docker-compose to deploy both containers and auto-create the Docker network and volumes:
docker-compose -f reverse-proxy.yml up -d
Just as in Step 2, you might need sudo
privileges depending on your system
setup.
You can now set up your web services to be reachable under a given subdomain.
Just define the subdomain you want to route to a service using the VIRTUAL_HOST
environment variable. If you use a different docker-compose file for your
services, make sure to use the same Docker network as for the reverse proxy:
## my-service.yml
version: '3'
services:
whoami:
image: jwilder/whoami
environment:
- VIRTUAL_HOST=whoami.your-domain.de
networks:
default:
external:
name: compose-net
Make sure that your subdomain resolves to your server's public IP address, then deploy your web service:
docker-compose -f my-service.yml up -d
The LetsEncrypt companion container should now automatically request a TLS
certificate and set up the reverse proxy in order to route requests to your service
afterwards. Give it a few minutes (as key generation might take a while), then
try reaching your service at whoami.your-domain.de
(or whatever subdomain you
used) from your web browser.
This fully automated setup makes it easy to deploy multiple web services without having to use multiple IP addresses. It also handles TLS certificates for you, making it easy to make services publicly available.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
By making a contribution to this project, I certify that:
The contribution was created in whole or in part by me and I have the right to submit it under the license indicated in the file; or
The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same license (unless I am permitted to submit under a different license), as indicated in the file; or
The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.
I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the license(s) involved.