Easy-to-use Docker container with Nginx configured to force HTTPS (thanks to Let's Encrypt) to any given HTTP backend server (configured via the $BACKEND
environment variable).
Before starting an instance of this container, you need to install Let's Encrypt certificates:
docker run -p 80:80 -v letsencrypt-data:/etc/letsencrypt/ \
michaelbaudino/nginx-letsencrypt-reverse-proxy \
letsencrypt-install --domain <example.com> --email <[email protected]>
ℹ️ Port 80 must not be already bound by another process/server and must be accessible from the outside world for this procedure to work.
To start an instance in foreground, use the following command:
docker run -p 80:80 -p 443:443 -v letsencrypt-data:/etc/letsencrypt/ -e BACKEND="<backend_url>" michaelbaudino/nginx-letsencrypt-reverse-proxy
Where <backend_url>
should be replaced by your application address in Nginx format, which is pretty much an URL without protocol (e.g. some.backend.com:8080
) or a Unix socket prefixed with unix:
(e.g. unix:/var/run/backend.sock
).
💡 If you'd rather start an instance running in the background, just add the
-d
switch (and eventually name your instance using the--name
switch for easier later use).
💡 Nginx logs are available using the
docker logs
command.
You can set optional settings using the following environment variables:
# Disable HTTPS Strict-Transport-Security (default: true)
HSTS=false
To renew Let's Encrypt certificates, run (the container must be already running):
docker exec -it <container> letsencrypt-renew
Where <container>
is either the container ID (as shown by docker ps
) or the container name (as assigned with the --name
switch of docker run
).
Adapt this sample docker-compose.yml
file to your own needs:
version: "2"
volumes:
letsencrypt-data:
driver: local
services:
nginx:
image: michaelbaudino/nginx-letsencrypt-reverse-proxy
ports:
- "80:80"
- "443:443"
volumes:
- letsencrypt-data:/etc/letsencrypt/
environment:
BACKEND: "your-backend:8080"
HSTS: true
depends_on: [your-backend]
your-backend:
image: ...
ports:
- "8080:8080"
ℹ️ The
nginx
service needs todepend_on
the backend service otherwise services boot order randomness might cause Nginx to fail to resolve the backend name.
Before starting an instance of this container, you need to install Let's Encrypt certificates:
docker-compose run nginx --service-ports --no-deps letsencrypt-install --domain <example.com> --email <[email protected]>
ℹ️ Port 80 must not be already bound by another process/server and must be accessible from the outside world for this procedure to work.
Just run as usual using:
docker-compose up
🐳 🎉
To renew Let's Encrypt certificates, run (the container must be already running):
docker-compose exec nginx letsencrypt-renew
- Clone this repository
- Do your changes
- Build with
docker build .
- If other people might benefit your changes, please submit a pull request
The --staging
switch can be appended to both letsencrypt-install
and letsencrypt-renew
commands for testing purposes: it retrieves certificates from the staging Let's Encrypt server to avoid reaching the production server rate limit.
The letsencrypt-renew
command also takes an optional --force-renew
switch (to renew certificates regardless their expiration date).
💡 Any valid
letsencrypt
/certbot
switches can actually been appended to bothletsencrypt-install
andletsencrypt-renew
commands: they will be passed as is. Check outletsencrypt
/certbot
documentation for more details.
If your Docker host is on an internal network (behind a router, not directly connected to Internet), you will need to add a NAT rule to your router configuration to redirect traffic on port 80 from the outside world to your private IP address.
Since the ACME protocol requires the use of port 80, there's no way to use another port.
This code is distributed under the MIT license terms (see LICENSE.md).
Logos concatenated in logo.svg are trademarks of their respective owners (Docker Inc., Nginx Inc. and Internet Security Research Group).