I'm available to deliver your SaaS MVP in a few weeks, full-stack with the new Next.js App Router. Accelerate Your MVP Launch Now.

How to set up a website on Linux + Nginx

Learn how to set up a website or web app using the ultra-fast Nginx HTTP Server on Linux in 6 steps.

Flavio Silva
Flavio SilvaSeptember 10, 2014
Updated on April 6, 2023
How to set up a website on Linux + Nginx
Image by storyset on Freepik

Nginx is becoming the new standard HTTP server for new websites and web apps, especially high-traffic ones. It's blazing fast, powerful, simple, and secure. The more we use it, the safer it becomes, as always (or almost always!). It can handle thousands of requests per second using only 512MB RAM.

If you want to know how to install Nginx on Linux please read my article How to install Nginx on Linux (Ubuntu & Debian).

Do not type the $ sign you see in the command examples in this article. That's just an indicator that you should run the command that follows it in your command line tool.

Step 1. Creating directories for your websites' configuration files

First, go to your Nginx directory. For Ubuntu and Debian, that's /etc/nginx:

$ cd /etc/nginx

Now, check if the directories for the configuration files already exist by running:

$ ls -la

If you can see two directories named sites-available and sites-enabled you're good to go. Otherwise create them by running:

$ sudo mkdir sites-available && sudo mkdir sites-enabled

sites-available will contain configuration files for all websites you want to try at any time, preferably one file for each website / web app. But files in this folder will not be enabled by default, i.e., they'll not be loaded into Nginx. That way you can safely create new files in this folder. Then we create symbolic links into sites-enabled folder.

That way, as a sysadmin, it's straightforward for you to enable and disable websites without having to duplicate files for backup purposes when disabling websites. To disable a website, you just delete its symlink file using the standard rm linux command.

Don't worry. That's pretty easy to manage, as we'll see next.

If those directories were already there, you should see a file named default into sites-available and a symlink (symbolic link) into sites-enabled. You can look at that file if you want. It's a template configuration file. Anyway, I'm providing you with a fully functional one based on it below.

Step 2. Creating your website's configuration file

Now, let's create your website's configuration file:

(Replace flsilva.com.conf by your domain name. Make sure your file ends with .conf)

$ sudo nano sites-available/flsilva.com.conf

Copy and paste the following content to your file:

server {
listen 80;
server_name www.flsilva.com;
rewrite ^/(.*) http://flsilva.com/$1 permanent;
server {
listen 80;
server_name flsilva.com;
root /var/www/flsilva.com/public;
error_log /var/log/nginx/flsilva.com.error.log;
access_log /var/log/nginx/flsilva.com.access.log;
location / {
index index.html index.htm;
error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/flsilva.com/public;

Do not forget to replace all occurences of flsilva.com by your domain.

Save the changes by hitting Control-X, then Y, and then Enter.

It's a good practice to check for any common errors after changing your website config files. To do that, run the following command:

$ sudo nginx -t

You should get the following output:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Otherwise, you'll see some errors.

Next, you'll understand a little bit about this configuration file.

Canonical URL

The first server block is there for SEO purposes. It's a technique called canonical URL. Here we're redirecting all requests coming to www.flsilva.com to just flsilva.com. If we don't take care of that, SEO ranking factors get split between more than one URL showing the same content. Doing that (using the permanent keyword, which translates to HTTP 301 status code - "Moved Permanently") we're essentially communicating to search engines that they should always consider our canonical flsilva.com URL, and that's great for SEO.

Note that you need to configure www in your DNS service (www is really a subdomain, like any other). You probably want to do that because you don't want your users to see an error page if they type www.yourdomain.com, right?

But if you're creating a subdomain, you should remove this first server block entirely, as your users shouldn't be typing www.yoursubdomain.yourdomain.com, but just yoursubdomain.yourdomain.com.

Standard port 80

This is the first line of the server block:

listen 80;

It defines that you're exposing your website through port 80. Port 80 is the default HTTP port. When you use your browser to navigate the web, it'll communicate to webservers through port 80. If you defined a different port, than you and your users would have to type the port ot access your website, like http://yourdomain.com:8123. That's commonly used for applications to communicate with each other, but not for your end users.

Your domain name

The second line defines what's the URL that it handles:

server_name flsilva.com;

Root directory

The next line defines the path for the root directory of your website:

root /var/www/flsilva.com/public;

You're going to create that directory in the next step.

Log files

The following two lines define where Nginx will create access and error log files. On Ubuntu and Debian, that directory is automatically created. So Nginx will be able to create log files there. You can look at those files to see how things are going on your website.

Default index file

Next are the lines that define the index file (index.html and index.html). You can change that if you want to use a different one.

404 Error page

Next is defined a custom 404 error page (404.html), located at the website's root. You can change the path, but if you don't have a custom error page, comment out that line, putting the # character at the beginning of the line.

Internal error pages (50x status code)

The last block defines the same for 50x errors, indicating that the files will be in the root of the website.

Step 3. Creating your website's root directory

Now, let's create your website's root directory. But first, an important detail: if you're not logged in as a root user, and you plan to deploy your website / web app using a different user, which I recommend in my How to securely set up a VPS server on Linux (Ubuntu & Debian) article, you'll also have to run the chown command that you see next (so don't forget to replace deploy by the username you're going to use to deploy your website). But you shouldn't run that command if you're using your root user to log in and plan to use it to deploy.

$ cd /var
$ sudo chown deploy:deploy www
$ cd www
$ mkdir flsilva.com
$ cd flsilva.com
$ mkdir public

Now you just have to deploy your website to that public directory (i.e. put your index.html file in there).

You created your website's configuration file inside the sites-available directory. To make it available, we will create a symlink for it. A symlink is a special file containing a reference to another file. In some situations, like this one, it's better than a simple copy & paste because you can change any file (the original one or the symlink), and both will keep in sync. But if you delete your symlink, nothing happens to the original file.

Let's create your symlink now:

$ sudo ln -s /etc/nginx/sites-available/flsilva.com.conf /etc/nginx/sites-enabled/flsilva.com.conf

Don't forget to replace flsilva.com by your domain.

PS: In my tests, that didn't work with relative paths, so make sure to use absolute ones.

That's it. Now you should be able to see your symlink file into sites-enabled directory pointing to the original file, like this:

flsilva.com.conf -> /etc/nginx/sites-available/flsilva.com.conf

If you want to disable any website configured like that, delete the symlink file and reload the Nginx's configuration file (nginx.conf - see next steps). You don't need to touch the files in sites-available. And if you need to get back a website, create a new symlink again!

Now remember that default configuration file? Yep, it's working since there's a symlink created for it in the sites-enabled folder. For our own website to work, we need to remove it since it's also listening to the standard 80 port.

To do that run the following command:

$ sudo rm /etc/nginx/sites-enabled/default

Step 6. Reloading Nginx

Every time you make a change to some website configuration file or even add or remove a symlink, you need to reload Nginx so it can take those changes into account. To do that run the following command:

$ sudo systemctl reload nginx

You'll get an error message if there's an error in any configuration file. Otherwise, you won't get any feedback.

And that's it.

Now you can start serving your website using the ultra fast Nginx HTTP Server. If you have any problems or suggestions please let me know!

Following are some common configurations that you probably want to do.

Some optimization

multi_accept is a configuration disabled by default. That means a worker process will accept only one new connection at a time. That's a waste of power, so it's useful to turn it on, then Nginx will accept as many connections as possible.

To do so, first open Nginx' configuration file:

$ sudo nano /etc/nginx/nginx.conf

Now, inside the block events {} you should find it commented out like this:

# multi_accept on;

Uncomment it by deleting the # character. You should have this instead:

multi_accept on;

Save the changes by hitting Control-X, then Y, and then Enter.

Allow underscores in client's request header

Another useful configuration is to allow the use of underscores by clients on Request Headers. That's disabled by default but is very simple to change, and will make it a little more flexible. To do that copy and paste the following line to your Nginx's configuration file (/etc/nginx/nginx.conf), inside the http{} block, usually after the default_type application/octet-stream; line:

underscores_in_headers on;

Save the changes by hitting Control-X, then Y, and then Enter.

Avoiding the “increase server_names_hash_bucket_size error”

To avoid the increase server_names_hash_bucket_size error, which occurs for long server_name values, first open Nginx' configuration file (/etc/nginx/nginx.conf):

$ sudo nano /etc/nginx/nginx.conf

Now, inside the block http {} you should find it commented out like this:

# server_names_hash_bucket_size 64;

Uncomment it by deleting the # character. You should have this instead:

server_names_hash_bucket_size 64;

Save the changes by hitting Control-X, then Y, and then Enter.

Do not forget to reload Nginx's configuration file after doing such changes:

$ sudo /etc/init.d/nginx reload

That's it. Please let me know if you have any questions or problems.

How to password-protect content on Linux + Nginx
Wildcard HTTPS on Linux + Let's Encrypt + Nginx
What are HTTPS, TLS certificates, and Let's Encrypt?
How to install Nginx on Linux
How to set up a Linux VPS

Nginx - Wikipedia


"Virtual Private Server - Wikipedia" Wikipedia , n.d. Web. 06 May 2014 <http://en.wikipedia.org/wiki/Virtual_private_server>

How to set up a website on Linux + Nginx by Flavio Silva is licensed under a Creative Commons Attribution 4.0 International License.

Leave a comment using your GitHub account

© 2024 Flavio Silva