Introduction

Welcome to the first lesson of "Getting Started with NGINX Web Server"! In this lesson, we'll take our first practical steps with NGINX by installing it and configuring a basic web server. By the end of this lesson, you'll have a working NGINX server that can serve static content on your local machine.

We'll explore the fundamental configuration directives that form the backbone of any NGINX setup: defining server blocks, setting up listening ports, specifying document roots, and handling different URL paths. You'll also learn how to validate your configuration and see your first NGINX-powered website in action.

What is NGINX?

NGINX (pronounced "engine-x") is a web server—software that takes files from your computer and sends them to web browsers when people visit your website. When you type a URL into your browser, a web server like NGINX is what responds with the HTML, images, and other files that make up the page you see.

Here's how it works: When someone requests a page from your website, their browser sends a request to your server. NGINX receives that request, finds the appropriate files on your computer, and sends them back to the browser. This happens in milliseconds, and NGINX can handle many of these requests at the same time.

NGINX was created in 2004 to handle thousands of simultaneous visitors without consuming excessive computer resources. Today, it's grown beyond just serving files—it can route traffic to applications, manage connections, and perform various other tasks. But at its core, NGINX remains a web server: a reliable way to deliver your website's content to visitors around the world.

Why Use NGINX?

If you're new to web servers, you might wonder why you'd choose NGINX over other options. The answer comes down to three key strengths: speed, efficiency, and versatility.

NGINX is exceptionally fast at serving static files like HTML, CSS, JavaScript, and images while using minimal memory and CPU. This efficiency becomes critical as your website grows from a handful of visitors to thousands. Many of the world's busiest websites—including Netflix, Airbnb, and GitHub—rely on NGINX to handle massive traffic loads.

Beyond serving files, NGINX excels at being the "front door" to modern applications. It can distribute traffic to backend servers, protect against overload, and cache content to speed up your site.

For developers, NGINX offers a straightforward configuration syntax with powerful capabilities. Whether you're hosting a personal blog or building a production application, NGINX provides the performance and features you need.

Understanding NGINX Configuration Structure

Before we dive into code, let's understand how NGINX configurations are organized. NGINX uses a hierarchical, context-based configuration file where directives are grouped into blocks. Think of these blocks as containers that define different aspects of your server's behavior.

The main configuration file typically contains several key blocks:

  • Worker processes and events: control how NGINX handles system resources and connections
  • HTTP block: contains all web server configurations
  • Server blocks: define individual websites or applications (similar to virtual hosts in Apache)
  • Location blocks: specify how to handle different URL paths

Each block uses curly braces and contains directives (instructions) that control specific behaviors. Directives within a block inherit and can override settings from parent blocks.

Setting Up Worker Processes and Events

Let's start building our configuration from the top. The first two sections define how NGINX manages system resources:

The worker_processes directive tells NGINX how many worker processes to spawn. Each worker can handle multiple connections simultaneously. We're starting with 1 for simplicity; in production, you might set this to auto to match your CPU cores.

The events block configures the event-driven model. The worker_connections directive sets the maximum number of simultaneous connections each worker can handle. With one worker and 1,024 connections, our server can handle up to 1,024 concurrent connections. However, note that this doesn't mean 1,024 concurrent clients—modern browsers typically open multiple parallel connections (often 6-8) to the same server to download resources simultaneously. So the actual number of concurrent clients would be lower, perhaps 128-170 if each opens 6-8 connections.

The HTTP Block and MIME Types

Next, we open the http context, where all our web server configurations live:

These directives control how NGINX handles HTTP traffic:

  • include mime.types loads a file that maps file extensions to content types (like .html → text/html, .jpg → image/jpeg)
  • default_type specifies what content type to use when NGINX can't determine one from the file extension
  • sendfile on enables an optimized method for transferring static files directly from disk to network, bypassing user space for better performance
Defining Your Server Block

Inside the http block, we define our first server. The server block represents a single website or application:

The listen directive tells NGINX which port to accept connections on. We're using port 3000 instead of the standard HTTP port 80 because it doesn't require administrator privileges and won't conflict with other services.

The server_name directive specifies which domain names this server block should respond to. By setting it to localhost, our server will respond to requests made to http://localhost:3000/.

Setting the Document Root and Default Index

Now we specify where NGINX should look for files to serve:

The root directive sets the document root, the base directory where NGINX looks for files. The path html is relative to NGINX's installation directory. When a request comes in for /about.html, NGINX will look for html/about.html.

The index directive defines which file to serve when a request is made to a directory. If someone visits http://localhost:3000/, NGINX will automatically try to serve html/index.html.

Handling the Root Path with Inline Fallback

Let's look at how we handle requests to the root path:

The first location block uses the = modifier for an exact match on /. The try_files directive attempts to serve /index.html first. If that file doesn't exist, it falls back to the named location @inline.

The @inline location is a named fallback that generates an HTML response directly. It sets the content type to text/html and returns a 200 status code with inline HTML content. This ensures visitors always see something, even if no index.html file exists.

Serving Static Files

Finally, we add a general location block to handle all other paths:

This location block uses the / prefix, meaning it matches all URIs (unless a more specific location matches first). The try_files directive works through options in order:

  • $uri: try to serve the exact file requested
  • $uri/: if it's a directory, look for an index file
  • =404: if neither works, return a 404 Not Found error

This simple but effective pattern ensures NGINX serves static files when they exist and returns proper error codes when they don't.

Validating Your Configuration

Before starting NGINX, we should always validate our configuration file for syntax errors. NGINX provides a built-in testing command:

This command checks your configuration without actually starting the server. If everything is correct, you'll see:

If there are errors, NGINX will point you to the specific line and describe what's wrong. Always run this test before reloading or restarting NGINX to avoid downtime from configuration mistakes.

Starting NGINX and Viewing Your Site

With a valid configuration, we can start NGINX and see our work in action. Start the server using:

Now open your web browser and navigate to http://localhost:3000/. You should see either your index.html file (if you created one in the html directory) or the inline fallback page displaying "It works!" with the message "Inline fallback page."

If you need to stop NGINX later, use nginx -s stop for a quick shutdown or nginx -s quit for a graceful shutdown that completes active connections first.

Conclusion and Next Steps

Congratulations! You've successfully installed NGINX, created a complete configuration from scratch, and served your first website. You've learned about the hierarchical structure of NGINX configurations, from worker processes down to location blocks, and you understand how directives like root, index, listen, and try_files work together to serve content.

This basic setup forms the foundation for everything else you'll do with NGINX. You now have a working server that can serve static files and handle missing files gracefully. In the upcoming practice exercises, you'll get hands-on experience applying these concepts and customizing your server configuration to meet specific requirements. Get ready to build on this foundation and take your NGINX skills to the next level!

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal