This docker-compose.yml users the official nginx and the official certbot container. It has optimized nginx configuration to be used as a https proxy together with certbot. Following my instructions you should get an A+ rating at ssllabs.com.
The container will use the network www-network as a proxy-tier. Add every container to this network that servers as a upstream http host.
How To Use
Docker Swarm
Update
Nginx
Let's Encrypt SSL Certificates
Let's Encrypt SSL Certificates on Swarm Mode
Get A+ SSL Rating
Password protection
IP-based protection
GeoIP blocking
.
├── conf.d # Site-specific configuration
│ ├── example.com.conf
│ ├── ...
├── protect # HTTP Password Protection
│ ├── .htpasswd
├── snippets # Config we want to reuse at conf.d files
│ ├── certbot-webroot.conf # Serves Let's encrypt .well-known files
│ ├── certbot-standalone.conf # as alternative method
│ ├── proxy.conf
│ ├── ssl.conf
mkdir -p /docker/00-nginx-proxy
cd /docker/00-nginx-proxy
git clone https://github.com/sebastian13/docker-compose-nginx-proxy.git .
mkdir -p ./ssl/test
openssl req -x509 -nodes -days 3650 -newkey rsa:4096 \
-keyout ./ssl/test/selfsigned.key \
-out ./ssl/test/selfsigned.crt
# Optional, run in a separate session
screen
openssl dhparam -out ssl/dhparams4096.pem 4096
cp conf.d/{example.com,yoursite.com.conf}
Replace example.com with your domain, and set your $upstream container.
cp conf.d/custom-nginx{,.conf}
docker network create www-network
docker compose up -d
To run this project on a docker stack, skip 5. and 6. and continue here:
If you previously used the www-network
, stop all containers and remove the network. The stack will recreate the network in swarm scope.
docker stop $(docker ps -q)
docker network remove www-network
docker swarm init
docker stack deploy proxystack -c swarm.yml
# Alternatively, run the helper script
cd swarm-scripts
./stack-deploy.sh
To get the most recent version of this repo run:
git fetch --all && \
git reset --hard origin/master && \
docker compose pull && \
docker compose down && \
docker compose up -d
I'm using the official nginx container here. All volumes will be mounted read-only.
As you change site-specific configuration in conf.d, you should consider reloading the configuration instead of restarting the container. This is because your container will not start if the configuration contains errors.
docker exec nginx-proxy nginx -s reload
You can use the free monitoring tool NGINX Amplify the following way:
- Create a amplify.env containing
AMPLIFY_IMAGENAME=example.com
API_KEY=123456
- Start the container the following way:
docker compose -f nginx-amplify.yml up -d --build
If using docker swarm, jump to Let's Encrypt SSL Certificates on Swarm Mode
docker compose run --rm certbot certonly \
--agree-tos --no-eff-email --hsts --webroot -w /var/www \
--rsa-key-size 4096 --cert-name=example.com \
-m [email protected] -d example.com
Then, link the certificate in your nginx site.conf + reload the nginx-proxy.
docker compose run --rm certbot certificates
docker compose run --rm certbot delete --cert-name example.com
Define a Cronjob like this, to renew the certificates periodically. Use chronic from moreutils if you like.
0 0 * * * cd /docker/00-nginx-proxy && chronic docker compose run --rm --use-aliases certbot renew && chronic docker exec nginx-proxy nginx -s reload
To manually check your certificates for renewal run docker compose up certbot
.
./swarm-scripts/certbot-certonly.sh -m [email protected] -d example.com -d www.example.co
./swarm-scripts/certbot.sh certificates
./swarm-scripts/certbot.sh delete --cert-name example.com
./swarm-scripts/certbot-renew.sh
Define a Cronjob like this, to renew the certificates periodically. Use chronic from moreutils if you like.
0 0 * * * chronic /docker/00-nginx-proxy/swarm-scripts/certbot-renew.sh
- Generate your own Diffie-Hellman parameters. Put it inside the directory ssl.
openssl dhparam -out ssl/dhparams4096.pem 4096
- Include the ssl.conf snippet at your site specific configuration. Also, include the ssl_trusted_certificate.
server {
...
ssl_trusted_certificate /etc/nginx/ssl/live/example.com/chain.pem;
include /etc/nginx/snippets/ssl.conf;
...
}
To protect your site with basic http authentication, create a .htpasswd file, spin up an apache container by running the following.
docker run -i --rm -v /docker/00-nginx-proxy/protect:/etc/nginx/protect httpd /bin/bash
For every user run the following. You will be asked to supply and confirm a password.
htpasswd -c /etc/nginx/protect/.htpasswd first_user
htpasswd /etc/nginx/protect/.htpasswd another_user
In the site's .conf file add the following.
server {
...
location / {
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/protect/.htpasswd;
}
}
You can find detailed instructions at digitalocean
Add your IP Address to the domain's .conf file, and deny everyone else.
server {
...
location / {
allow 1.2.3.4;
deny all;
}
}
mkdir geoip
cd geoip
curl -O https://centminmod.com/centminmodparts/geoip-legacy/GeoIP.dat.gz
curl -o GeoLiteCity.dat.gz https://centminmod.com/centminmodparts/geoip-legacy/GeoLiteCity.gz
gunzip *.gz
add to nginx.conf after pid ... :
load_module modules/ngx_http_geoip_module.so;