I have configured 3 virtual servers for an application:
- Static file server (static.example.com)
- API server (api.example.com)
- Admin panel (web) server (admin.example.com)
I want to run all three of these servers on a single nginx
server by configuring three virtual servers in sites-available
, creating a systemic link into sites-enebled
and including them in the nginx.conf
file.
Here is the admin.example.com
file:
server {
server_name admin.example.com;
root /var/www/admin.example.com/build;
index index.html index.htm index.nginx-debian.html;
location / {
try_files $uri /index.html;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/admin.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/admin.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = admin.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name admin.example.com;
listen 80;
return 404; # managed by Certbot
}
Here is the static.example.com
file:
server {
server_name static.example.com;
root /usr/share/nginx/html/wellmate/;
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
sendfile on;
autoindex on;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/static.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/static.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = static.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name static.example.com;
listen 80;
return 404; # managed by Certbot
}
And here is the api.wellm8.com
file:
server {
server_name api.example.com;
location / {
include proxy_params;
proxy_pass http://192.168.100.2:5000;
}
location /socket.io {
include proxy_params;
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://192.168.100.2:5000/socket.io;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = api.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name api.example.com;
listen 80;
return 404; # managed by Certbot
}
Initially I had them all running under the same server_name
- localhost
, each on different port - 80
, 81
, 82
. This worked well for me, I had all three servers resolving connection to them. Then I set my A
records to direct to the IP address of the machine which runs the nginx
server - primary external address obtained from curl -4 icanhazip.com
.
I changed the server_name
's of each virtual server to its appropriate A
record host name and proceeded to wait for about 30 minutes for all the A
records to apply and refresh. I made sure using dig
that all the A
records were pointing to my server and started working on the SSL
certificates.
I have used certbot
in the past and I decided to use it again, so I installed certbot-nginx
plugin, generated three SSL cerificates
using the following commands:
sudo cerbot --nginx -d api.example.com
sudo cerbot --nginx -d admin.example.com
sudo cerbot --nginx -d static.example.com
I chose the redirect option from port 80 *TCP HTTP
to port 443 *TCP HTTPS
on all three and all three finished without an error or warning.
Then I tried to hit each server and only static.example.com
responded, all others respond with CONNECTION_REFUSED
. Any idea why this would occur? I have done this same setup dozens of times, the only difference is that I usually do it on digital ocean, this one is done on a virtual server (vmware with custom network and edge gateway configuration), but that shouldn't be the cause of the issue.
Edit: I just reactivated the server where these A
records were previously pointing and now when I hit api.example.com
and admin.example.com
I am hitting the other server for some reason. I tried accessing from a private browser in case cache but it still get the old server. When I go into my domain networking panel I see that the addresses are pointing to the correct IP.
Edit 2: Just checked in today, it appears that it took a little bit longer for the A
records to update. Not sure why dig
showed the correct IP's but all is resolved.