Prerequisite: Readers should be conversant with the concept of load balancers and be familiar with Linux (Ubuntu).
Setting Up the VagrantBoxes
Start by installing VirtualBox and Vagrant.
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ brew install --cask virtualbox
$ brew install --cask vagrant
$ brew install --cask vagrant-manager
$ vagrant init ubuntu/xenial64
In your terminal, navigate to any directory of your choice and create a VagrantBox (create two VagrantBoxes in different directories).
$ vagrant up
$ vagrant ssh
Enable port forwarding in one of the VagrantBoxes, by editing the Vagrantfile
located in the directory your box was created.
Note In both VagrantFiles, uncomment the config.vm.network
"public_network"
and pick 1
which is WiFi
, this is to allow your VMs to be on the same network:
Vagrant.configure("2") do |config|
config.vm.box = "your_box_name"
config.vm.network "forwarded_port", guest: 8000, host: 8000
config.vm.network "forwarded_port", guest: 80, host: 80
end
Exit out of the Vagrantfile and run,
$ vagrant reload
For the second box, remember to uncomment the config.vm.network
"public_network"
and pick 1
which is WiFi
, while editing the Vagrantfile:
Vagrant.configure("2") do |config|
config.vm.box = "your_box_name"
config.vm.network "forwarded_port", guest: 8080, host: 8080
end
Exit out of the Vagrantfile and run,
$ vagrant reload
The snippet specifies forwarding ports 80, 8080 and 8000 from the guest machine to ports 80 (load balancing), 8080 and 8000 (for the individual websites) on the host machines.
This means that any traffic coming to ports 80, 8080 and 8000 on your host machine will be redirected to ports 80, 8080 and 8000 respectively on the guest machine. This enables access to the websites' URLs from a browser.
Setting Up Nginx and the Websites
Install Nginx (from source) on both boxes, by running this script. Save the script and grant it execute
permission.
#!/bin/sh
# Install Dependencies
sudo apt update -y && sudo apt-get install -y git build-essential libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev libgd-dev libxml2 libxml2-dev uuid-dev
# Download Nginx Source Code
wget http://nginx.org/download/nginx-1.24.0.tar.gz
tar -zxvf nginx-1.24.0.tar.gz
cd nginx-1.24.0
# Build & Install Nginx
sudo ./configure \
--prefix=/etc/nginx \
--conf-path=/etc/nginx/nginx.conf \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--pid-path=/run/nginx.pid \
--sbin-path=/usr/sbin/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_stub_status_module \
--with-http_realip_module \
--with-file-aio \
--with-threads \
--with-stream \
--with-stream_ssl_preread_module
sudo make && sudo make install
# Set NGINX systemd service file path
nginx_service_file="/lib/systemd/system/nginx.service"
# Create NGINX systemd service file
sudo tee $nginx_service_file > /dev/null <<EOT
[Unit]
Description=Nginx Custom From Source
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT \$MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOT
# Enable and Start Nginx service
sudo systemctl daemon-reload
sudo systemctl enable nginx
sudo systemctl start nginx
Run the script:
$ chmod u+x script.sh
$ ./script.sh
Clone the repository on the boxes
$ git clone https://github.com/Mbaoma/deimos-internship.git
Setting Up Box One as a Web server and Load Balancer
Move the website's folder into the /var/www/html
folder and start the app:
$ cd Module\1
$ sudo mv /website1 /var/www/html
$ cd /var/www/html/website1
$ sudo apt-get update
$ sudo apt-get install nodejs npm -y
$ npm install
$ npm install express
$ sudo ln -s /usr/bin/nodejs /usr/bin/node
$ nohup node main.js &
Setup the configuration by editing the default
file in the sites-available
folder,
$ sudo nano /etc/nginx/sites-available/default
Then copy and paste this snippet in the file:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html/website2;
index index.html index.htm;
server_name _;
location / {
try_files $uri $uri/ =404;
proxy_pass http://localhost:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Since I will also be using this VagrantBox (Virtual Machine), as my load balancer; I have to edit the configuration in the /etc/nginx/sites-enabled/default
# Create a symbolic link to enable the configuration
$ sudo ln -s /etc/nginx/sites-enabled/default
$ sudo nano /etc/nginx/sites-enabled/default
Copy ad paste this snippet into the file:
#setup loadbalancing
# Define the load balancing configuration
load_balancing_config='
http {
upstream backend {
server <vm-ip>:80;
server <vm-ip>:8000;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}
}
You can get the VM's IP by running:
$ ip addr show
In another box, move the website's folder into the /var/www/html
folder and start the app:
$ cd Module\1
$ sudo mv /website2 /var/www/html
$ cd /var/www/html/website2
$ sudo apt-get update
$ sudo apt-get install nodejs npm -y
$ npm install
$ npm install express
$ sudo ln -s /usr/bin/nodejs /usr/bin/node
$ nohup node main.js &
At each step, when you set up a configuration, confirm if your configuration is correct by running:
# Verify the Nginx configuration
$ sudo nginx -t
$ sudo systemctl daemon-reload
# Restart Nginx for the changes to take effect
$ sudo systemctl restart nginx
Confirm if all works as expected
VM 1 - http://localhost:8080/ or http://<ivm-ip>:8080/
VM 2 - http://localhost:8000/ or http://<vm-ip>:8000/
Load balancer - http://<vm1-ip>
Refer to this repository, for more information and troubleshooting.
Toodles and good luck ✨.