Experimental with 3 Container Docker, which is 1 Container for Nginx Load Balancer Reverse and 2 Container for Nginx Node
We will try to implement SSL + Auto Redirect + Load Balancer + Hostname Access Restrict
Ubuntu 20.04 LTS
Docker
3 Nginx Container
apt install -y docker.io
docker pull nginx
docker run --name nginx-lb -d -p 80:80 -p 443:443 nginx
docker run --name nginx-1 -d nginx
docker run --name nginx-2 -d nginx
docker ps
In my case, i have an Docker Container IP like this :
Nginx-LB : 172.17.0.2
Nginx-1 : 172.17.0.3
Nginx-2 : 172.17.0.4
And then, i define labs.com for Domain experimental.
The default configurations is RoundRobin LoadBalancer Mode, if you want to use Least Connection or IP Hash Model please add this on /etc/nginx/conf.d/default :
Least Connection :
---
upstream backend {
least_conn;
server 172.17.0.3;
server 172.17.0.4;
}
---
IP Hash :
---
upstream backend {
ip_hash;
server 172.17.0.3;
server 172.17.0.4;
}
---
docker exec -it nginx-lb bash
nano /etc/nginx/conf.d/default.conf
upstream backend {
server 172.17.0.3;
server 172.17.0.4;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 412;
}
server {
listen 80;
server_name labs.com www.labs.com;
location / {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://backend;
}
}
Make sure you have an SSL Certificate, you can generate from Valid DNS or Self Signed with OpenSSL.
Or you can goes to my Previos Topic about OpenSSL [https://gist.github.com/gilangvperdana/74ab7eb4e7d5e4ca76663334ed905bae]
apt install -y openssl
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Labs Inc./CN=labs.com' -keyout localhost.key -out localhost.crt
docker cp localhost.crt nginx-lb:/etc/ssl/certs/
docker cp localhost.key nginx-lb:/etc/ssl/certs/
nano /etc/nginx/conf.d/default.conf
# SSL | Load Balancing | Restrict Access | Redirect to 443
# LOAD BALANCING NODE IP :
upstream backend {
server 172.17.0.3;
server 172.17.0.4;
}
# RESTRICT ACCESS, MUST BE WITH SAME/CONFIGURED HOSTNAME TO ACCESS PAGE (REDIRECT TO 443) :
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
# RESTRICT ACCESS, MUST BE WITH SAME/CONFIGURED HOSTNAME TO ACCESS PAGE :
server {
listen 443 default_server;
listen [::]:443 default_server;
ssl_certificate /etc/ssl/certs/localhost.crt;
ssl_certificate_key /etc/ssl/private/localhost.key;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
server_name _;
return 412;
}
# ACCESS ON PORT 80 THEN REDIRECT TO 443 :
server {
listen 80;
return 301 https://$server_name$request_uri;
}
# ACCESS WITH labs.com ON 443 :
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
ssl_certificate /etc/ssl/certs/localhost.crt;
ssl_certificate_key /etc/ssl/private/localhost.key;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
server_name labs.com labs.com;
location / {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://backend;
}
}
Add telco.com for new domain.
nano /etc/nginx/conf.d/default.conf
# SSL | Load Balancing | Restrict Access | Redirect to 443
# LOAD BALANCING NODE IP :
upstream backend {
server 172.17.0.3;
server 172.17.0.4;
}
# RESTRICT ACCESS, MUST BE WITH SAME/CONFIGURED HOSTNAME TO ACCESS PAGE (REDIRECT TO 443) :
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
# RESTRICT ACCESS, MUST BE WITH SAME/CONFIGURED HOSTNAME TO ACCESS PAGE :
server {
listen 443 default_server;
listen [::]:443 default_server;
ssl_certificate /etc/ssl/certs/localhost.crt;
ssl_certificate_key /etc/ssl/private/localhost.key;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
server_name _;
return 412;
}
# ACCESS ON PORT 80 THEN REDIRECT TO 443 :
server {
listen 80;
return 301 https://$server_name$request_uri;
}
# ACCESS WITH labs.com ON 443 :
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
ssl_certificate /etc/ssl/certs/localhost.crt;
ssl_certificate_key /etc/ssl/private/localhost.key;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
server_name labs.com labs.com;
location / {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://backend;
}
}
# ACCESS WITH telco.com ON 443 :
server {
listen [::]:443 ssl http2;
listen 443 ssl http2;
ssl_certificate /etc/ssl/certs/localhost.crt;
ssl_certificate_key /etc/ssl/private/localhost.key;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
server_name telco.com telco.com;
location / {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://backend;
}
}
service nginx reload
You can access on for 1Host Version :
http://labs.com for Non-SSL,
https://labs.com for SSL.
You can access on for 2Host Version :
http://labs.com for Non-SSL,
https://labs.com for SSL.
and
http://telco.com for Non-SSL,
https://telco.com for SSL.
You can see how much active connection with simple metrics expose from Nginx.
Goes to Nginx-lb
docker exec -it nginx-lb bash
Execute this :
nginx -V 2>&1 | grep -o with-http_stub_status_module
Edit default.conf
nano /etc/nginx/conf.d/default.conf
Add this on bottom of the line :
---
server {
listen 443;
listen [::]:443;
ssl_certificate /etc/ssl/certs/all-labs.crt;
ssl_certificate_key /etc/ssl/private/all-labs.key;
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
server_name stat.labs.com stat.labs.com;
location /nginx_status {
stub_status on;
access_log off;
}
}
---
Access simple metrics on https://stat.labs.com/nginx_status
If you want to try as fast as possible, you can use my Docker Image on Docker Hub with :
docker network create --subnet=172.19.0.0/16 nginxnet
docker run --net nginxnet --ip 172.19.0.10 --name nginx-lbs -d -p 80:80 -p 443:443 gilangvperdana/research:nginx-lbs
docker run --net nginxnet --ip 172.19.0.11 --name nginx-1 -d gilangvperdana/research:nginx-1
docker run --net nginxnet --ip 172.19.0.12 --name nginx-2 -d gilangvperdana/research:nginx-2
docker run --net nginxnet --ip 172.19.0.13 --name nginx-3 -d gilangvperdana/research:nginx-3
docker run --net nginxnet --ip 172.19.0.14 --name nginx-final -d gilangvperdana/research:nginx-f
Access on https://labs.com OR https://telco.com
or you can use Nginx Load Balancer (nginx-lbs) with Metrics, you can use this image :
docker run --net nginxnet --ip 172.19.0.10 --name nginx-lbs -d -p 80:80 -p 443:443 gilangvperdana/research:nginx-lbs-metrics
Then, you can access metrics on :
https://stat.labs.com/nginx_status