Modular Nginx Configuration: How to Elegantly Manage Multiple Projects with Subdomains
Content
## The Problem
When managing a server that hosts multiple web projects, cramming all configurations into a single `nginx.conf` file quickly becomes messy, difficult to maintain, and hard to troubleshoot. A more elegant and professional approach is to adopt a modular configuration structure, creating separate configuration files for each project.
This article, based on a specific set of requirements, will provide a detailed guide on how to build a clean, scalable multi-project configuration for Nginx (using version 1.27.2 as an example). This strategy is widely used in practice by the **DP@lib00** team.
**Core Requirements:**
1. All project code is stored in the `/web_root/lib00_projects/` directory, with each project in its own subdirectory (e.g., `projectA`).
2. Each project is accessed via a unique subdomain (e.g., `projectA.wiki.lib00.com`).
3. Nginx listens on a non-standard HTTP port, `55101`.
4. A modular configuration is used, where each project's `server` block is stored in a separate `.conf` file within the `/etc/nginx/project_config/` directory.
5. Provide a configuration solution for testing in a development environment using an IP address (e.g., `192.168.1.2`).
---
## Step 1: Configure the Main `nginx.conf` File
The role of the main `nginx.conf` file is to define global settings and act as a "router" that loads all individual project configurations using the `include` directive. This keeps the main file clean and concise.
Open or create `/etc/nginx/nginx.conf` and add the following basic content:
```nginx
# It's recommended to run Nginx with a non-root user, e.g., www-data
user www-data;
# Automatically adjust the number of worker processes based on CPU cores
worker_processes auto;
pid /run/nginx.pid;
# Include configurations for dynamic modules if needed
# include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# Enabling Gzip compression can improve performance
# gzip on;
# This is the key to modularity!
# Nginx will load all files ending with .conf from the specified directory.
# We'll place our project configs in a folder named wiki.lib00_project_config
include /etc/nginx/wiki.lib00_project_config/*.conf;
}
```
**Key Insight:**
* **`include /etc/nginx/wiki.lib00_project_config/*.conf;`**: This is the core of the entire modular setup. It tells Nginx to load all `.conf` files from the `wiki.lib00_project_config` directory. This way, whenever you need to add, modify, or delete a project, you only need to work with its corresponding file without touching the main configuration.
---
## Step 2: Create Individual Configuration Files for Projects
Now, let's create a separate configuration file for `projectA`.
Create the file `/etc/nginx/wiki.lib00_project_config/projectA.conf`:
```nginx
server {
# Listen on the port we specified in the requirements: 55101
listen 55101;
# Bind the project's subdomain
server_name projectA.wiki.lib00.com;
# Set the website's root directory
root /web_root/lib00_projects/projectA;
# Set the default index files
index index.html index.htm;
location / {
# Try to find a file in order: $uri (file) -> $uri/ (directory) -> return 404
# This is crucial for handling routing in Single Page Applications (SPAs)
try_files $uri $uri/ =404;
}
# You can add extra configurations for specific projects, like logs, access control, etc.
access_log /var/log/nginx/projectA-access.log;
error_log /var/log/nginx/projectA-error.log;
}
```
If you have another project, `projectB`, simply copy this file to create `projectB.conf` and change the `projectA`-related names and paths to `projectB`. This approach dramatically improves the maintainability of your configuration.
---
## Step 3: Configure IP-Based Access for Development
During the development phase, subdomains might not be resolved yet. We often need to access projects using the server's IP address for testing. We can create a dedicated `server` block for this purpose.
In the same `/etc/nginx/wiki.lib00_project_config/` directory, create a test configuration file, for example, `dev-test.conf`:
```nginx
server {
# Listen on the same 55101 port
listen 55101;
# Key point: Use the server's IP address as the server_name
# When a request comes to http://192.168.1.2:55101, Nginx will match this server block
server_name 192.168.1.2;
# Point the request to projectA's root directory
root /web_root/lib00_projects/projectA;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# It's a good practice to use separate log files for the test environment
access_log /var/log/nginx/dev-test-access.log;
error_log /var/log/nginx/dev-test-error.log;
}
```
**How It Works:**
When a user accesses `http://192.168.1.2:55101`, Nginx checks the `Host` request header. Even if the browser doesn't send a `Host` header or sends the IP address, by explicitly listing the IP in `server_name`, Nginx can accurately route these requests to the `projectA` codebase.
---
## Conclusion
By adopting a modular approach using the `include` directive to separate configuration files, we have successfully built a clean, scalable, and easy-to-maintain Nginx configuration structure for a multi-project environment. This practical experience from **wiki.lib00.com** not only makes daily management more efficient but also simplifies troubleshooting. Whether for production or development testing, this structure offers significant convenience.
Related Contents
How Can a Docker Container Access the Mac Host? The Ultimate Guide to Connecting to Nginx
Duration: 00:00 | DP | 2025-12-08 23:57:30Nginx vs. Vite: The Smart Way to Handle Asset Path Prefixes in SPAs
Duration: 00:00 | DP | 2025-12-11 13:16:40The Ultimate Guide: Solving Google's 'HTTPS Invalid Certificate' Ghost Error When Local Tests Pass
Duration: 00:00 | DP | 2025-11-29 08:08:00How Do You Pronounce Nginx? The Official Guide to Saying It Right: 'engine x'
Duration: 00:00 | DP | 2025-11-30 08:08:00The Ultimate Nginx Guide: How to Elegantly Redirect Multi-Domain HTTP/HTTPS Traffic to a Single Subdomain
Duration: 00:00 | DP | 2025-11-24 20:38:27Composer Script Not Running? Unveiling the `post-install-cmd` Trap and the Ultimate Solution
Duration: 00:00 | DP | 2025-12-23 07:20:50Recommended
Unlock Your IDE's Full Potential: A Deep Dive into PHPDoc for Flawless PHP Autocompletion
00:00 | 14This article provides a deep dive into the core ro...
Shell Magic: How to Gracefully Write Output from Multiple Commands to a Single Log File
00:00 | 5In shell scripting or daily system administration,...
The Ultimate Guide to PHP's nl2br() Function: Effortlessly Solve Web Page Line Break Issues
00:00 | 8Struggling with newline characters from textareas ...
The Ultimate Guide to MySQL Partitioning: From Creation and Automation to Avoiding Pitfalls
00:00 | 9Is database performance becoming a bottleneck with...