This post has been cross-posted from my blog
Configuring nginx for subdomains in the same machine was confusing for me. So I am writing this tutorial primarily for (self)reference but people can find it useful. Without much ado, let's get started.
For those of you who don't know what nginx is exactly, head over to this freeCodeCamp article as a starting point.
I assume you're on a linux machine and you know what nginx means.
First and foremost, install nginx -
sudo apt-get install nginx
Second head over to /etc/nginx/sites-available/default
by opening it on vim/nano. You would come across something like this -
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass PHP scripts to FastCGI server
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php-fpm (or other unix sockets):
# fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# # With php-cgi (or other tcp sockets):
# fastcgi_pass 127.0.0.1:9000;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
# listen 80;
# listen [::]:80;
#
# server_name example.com;
#
# root /var/www/example.com;
# index index.html;
#
# location / {
# try_files $uri $uri/ =404;
# }.
#}
From the above you can gather the following points -
-
server {}
- that tells nginx that "Hey this is how I think you should configure the server" -
listen 80
- translates to "Listen to port 80, which is the default port for web clients" -
root /var/www/html;
- nginx understands that HTML file/files from that location can be served -
index index.html index.htm index.nginx-debian.html;
- this indicates that these kind of files should be served in a decreasing order of priority (left to right). -
server_name _;
- this conveys that_
is the server name. Assuming our domain to beexample.com
, the server name would beexample.com
. That's because when a request is received forexample.com
, nginx should whether to process it or not. -
location / {}
- this means that all requests must be handled by this server config. There is an option to handle specific requests as well. For example, requests starting with/server_1
can loadserver_1.html
and all other requests can loaddefault.html
.
Next obvious question is - how do I configure subdomains?
It's not that complicated. It involves 7 steps -
- Copy the default configuration and rename it as
subdomain1.example.com
.
cp /etc/nginx/sites-available/default /etc/nginx/sites-available/subdomain1.example.com
Note: You don't necessarily have to name the file subdomain1.example.com
. It's easier if you follow a convention that makes it easy for everybody involved.
- Open it and remove the term
default_server
besideslisten 80
and the line below it. This is crucial. - Change the
server_name
assubdomain1.example.com
& change the HTMLroot
that's being used - Then link that file to a file in nginx's sites-enabled directory. This is for nginx to understand that configuration
subdomain1.example.com
is enabled in the configuration.
sudo ln -s /etc/nginx/sites-available/subdomain1.example.com /etc/nginx/sites-enabled/subdomain1.example.com
- Write a HTML file inside
/var/www/html
forsubdomain1.example.com
- Restart the nginx server
- If you're using a DNS provider like Cloudflare, add the box's IP to it with an A record
subdomain1.example.com
. If not, then add the box's IP and subdomain1.example.com to /etc/hosts. - Load
subdomain1.example.com
on the browser to check how it loads. If everything is fine, you will see the HTML that you wrote for this subdomain.
Extend the same approach for any other domain or subdomain that you require.
Top comments (4)
Hi Santosh,
I've been struggling with setting up nginx subdomains on my linode instance and setting up CNAME redirects.
What I need is to be able to do:
First set up wildcard subdomains on my server (tinyadults.com), so that users can go to abc.tinyadults.com, xyz.tinyadults.com, etc.
My server is running nuxt.js on port 4001 (default port is 3000 but I chose to use 4001 as a non-standard port), so I guess I have to use reverse proxies:
proxy_pass localhost:4001;
Then for my users I need to set up CNAME redirects from domain1.com to abc.tinyadults.com, and from domain2.com to xyz.tinyadults.com, so that if I visit domain1.com , it would serve the contents (without redirecting me) of abc.tinyadults.com. For testing purposes I have an additional domain (passivefinance.com) that we could use.
However, I've not been able to get step 1 working. Any ideas?
Below is my nginx config from sites-available/tinyadults.com.conf:
Hi, I've set this up to use budgeterapi.talentexploitapi.co.uk and port 8081 (not sure if this is required).
If I call the usual request that worked on localhost, I get 404 error in postman.
Note, I've added the A record on Digitalocean as hostname: budgeterapi.talentexploitapi.co.uk, will direct to: 134.209.16.162 .
I would like to use the same domain name with a subdomain or alias or anything like that. Thanks.
THX. Was pretty helpful and consise.
Great stuff. Seems like every day I learn about a new nginx feature that changes everything.