sajad torkamani

One of the advantages of using web servers like Nginx or Apache is that you can host multiple domains on a single Linux server. For example, you can configure things so that both and are routed to the same server.

Assuming we already have Nginx installed, let’s set up a simple HTML website on a local Nginx installation. Most of the steps will also be applicable to a production environment.

Create example website

mkdir -p $HOME/sites/example
touch $HOME/sites/example/index.html

Populate index.html with some dummy content:

<h1>Example website</h1>
<p>Isn't this great?</p>

It’s a convention to place hosted websites under /var/www so let’s create a symlink that points from /var/www/example to $HOME/sites/example:

sudo ln -s $HOME/sites/example /var/www 

Create Nginx server block

We typically create a single configuration file for each domain under /etc/nginx/sites-available. Although the file name doesn’t matter, I personally like to name it the same as the domain name with a suffix of .conf (the suffix helps some IDEs / editors identify the file as Nginx).

So assuming we’ll be running our simple website locally on the example.test domain, let’s create the corresponding config file:

touch /etc/nginx/sites-available/example.test.conf

Populate it with the following:

server {
  listen 80;
  server_name example.test www.example.test;

  root /var/www/example;
  index index.html;

  location / {
    try_files $uri $uri/ =404;

This is the most minimal configuration required. Let’s take a look at each directive:

  • listen: what port Nginx should listen on. This is almost always either 80 (HTTP) or 443 (HTTPS)
  • server_name: what domain name this server block applies to. In other words, we only want to apply the rules inside this server block to requests to http://example.test.
  • root: sets the root directory for the request. Since we’ve placed this directive directly inside a server instead of a location context, we’ve defined a default root directory for all requests. We can set different root directories for different request patterns by placing a root directive inside a location context.
  • index: what index files we should serve and in what priority.
  • location: sets configuration depending on the request URI. Here, we’re telling Nginx to resolve all requests by first trying to serve a file that matches the URI ( e.g., try serving /var/www/example/foo/bar.png for requests to http://example.test/foo/bar.png). Failing this, it should try to serve an index file at the URI (e.g., serve /var/www/example/foo/index.html for requests to http://example.test/foo). If both methods fail, it should return a 404 not found response.

By default, Nginx only picks up configs in /etc/nginx/sites-enabled so let’s create a symlink to activate our new config:

sudo ln -s /etc/nginx/sites-available/example.test.conf /etc/nginx/sites-enabled

Execute ls -la /etc/nginx/sites-enabled and you should see the symlink created:

drwxrwxr-x 2 root admin 4096 Apr 20 09:31 .
drwxrwxr-x 9 root admin 4096 Apr 19 17:47 ..
lrwxrwxrwx 1 root root    44 Apr 20 09:31 example.test.conf -> /etc/nginx/sites-available/example.test.conf

Test and activate config

We can test that our configuration is valid and doesn’t have any syntax errors:

sudo nginx -t

Assuming all is well, we can reload Nginx so it picks up the new configuration changes:

sudo systemctl reload nginx

Update /etc/hosts

This last step is only needed in a development environment where we have the freedom to map any domain to our local machine. On production servers, you can skip this step but you need to own any domains you want to use and you’ll also need to configure some DNS settings. See this article for more info. Let’s focus on a development setup for now.

Open /etc/hosts and add the following line to the end of the file:    example.test

This essentially tells our Ubuntu machine to intercept all requests to example.test and route it to (localhost). Thus, when we use a browser like Chrome and navigate to example.test, our machine will actually route this request to localhost and then our Nginx configuration can kick in to serve the correct response – in this case, our dummy HTML page.

Visit website

We configured our Nginx server block from earlier to listen on port 80 for requests to example.test. Thus when we visit example.test, we should see our dummy HTML page.

Dummy HTML page

That’s it. This process covers a basic but very common use case of Nginx. The Nginx Beginner’s Guide is a good place to go for more info.


Tagged: Nginx