Most people install Nginx via package managers, but compiling from source truly reveals its module mechanism. This post uses FastDFS module integration as an example to analyze Nginx’s build system and modular architecture.
1. Why Compile from Source?
1.1 Package Manager Limitations
1
2
3
4
5
6
| # Package manager install
apt install nginx
# Check compile parameters
nginx -V
# Fixed module list, can't modify
|
Problems:
- Can’t add third-party modules (FastDFS, OpenResty)
- Can’t remove unneeded modules (reduce size)
- Can’t tune compilation optimization flags
1.2 Scenarios Requiring Source Compilation
| Scenario | Requirement |
|---|
| Distributed file storage | Integrate fastdfs-nginx-module |
| WAF protection | Integrate ModSecurity |
| High-performance cache | Integrate ngx_cache_purge |
| Lua scripting | Integrate OpenResty |
| Minimal footprint | Remove unneeded modules |
2. Nginx Modular Architecture
2.1 Module Categories
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| ┌─────────────────────────────────────────────────────────┐
│ Nginx Core │
├─────────────────────────────────────────────────────────┤
│ Core Modules │
│ ├── ngx_core_module Process management, config parse │
│ ├── ngx_errlog_module Error logging │
│ └── ngx_events_module Event-driven │
├─────────────────────────────────────────────────────────┤
│ HTTP Modules │
│ ├── ngx_http_core_module HTTP core │
│ ├── ngx_http_proxy_module Reverse proxy │
│ ├── ngx_http_fastcgi_module FastCGI support │
│ ├── ngx_http_gzip_module Gzip compression │
│ └── ngx_http_ssl_module HTTPS support │
├─────────────────────────────────────────────────────────┤
│ Third-party Modules │
│ ├── fastdfs-nginx-module FastDFS integration │
│ ├── ngx_cache_purge Cache purging │
│ └── lua-nginx-module Lua scripting │
└─────────────────────────────────────────────────────────┘
|
2.2 Module Loading Mechanism
Nginx modules can be statically compiled or dynamically loaded:
1
2
3
4
5
6
7
8
| # Static compilation: linked into binary at compile time
./configure --add-module=/path/to/module
# Dynamic loading (1.9.11+): loaded at runtime
./configure --add-dynamic-module=/path/to/module
# Load dynamic module in nginx.conf
load_module modules/ngx_http_image_filter_module.so;
|
3. Build Environment Preparation
3.1 Install Dependencies
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| # Ubuntu/Debian
sudo apt update
sudo apt install -y \
build-essential \
libpcre3-dev \
zlib1g-dev \
libssl-dev \
libgd-dev \
libgeoip-dev
# CentOS/RHEL
sudo yum groupinstall -y "Development Tools"
sudo yum install -y \
pcre-devel \
zlib-devel \
openssl-devel \
gd-devel \
GeoIP-devel
|
3.2 Dependency Explanation
| Dependency | Purpose | Corresponding Module |
|---|
| PCRE | Regular expressions | rewrite module |
| zlib | Gzip compression | gzip module |
| OpenSSL | HTTPS | ssl module |
| libgd | Image processing | image_filter module |
| GeoIP | IP geolocation | geoip module |
4.1 Common Parameters
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| ./configure \
# Install paths
--prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--conf-path=/etc/nginx/nginx.conf \
--pid-path=/var/run/nginx.pid \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
# User and group
--user=nginx \
--group=nginx \
# Enable modules
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
# Disable unneeded modules (reduce size)
--without-http_autoindex_module \
--without-http_ssi_module \
# Third-party modules
--add-module=/path/to/fastdfs-nginx-module/src \
# Compilation optimization
--with-cc-opt='-O2 -fstack-protector-strong' \
--with-ld-opt='-Wl,-z,relro -Wl,-z,now'
|
1
2
3
| # View configure output
ls objs/
# autoconf.err Makefile ngx_auto_config.h ngx_modules.c src/
|
Key files:
| File | Purpose |
|---|
objs/Makefile | Build rules |
objs/ngx_auto_config.h | Auto-detected system config |
objs/ngx_modules.c | Module registration list |
4.3 Module Registration Internals
1
2
3
4
5
6
7
8
9
10
11
12
| // objs/ngx_modules.c (auto-generated)
ngx_module_t *ngx_modules[] = {
&ngx_core_module,
&ngx_errlog_module,
&ngx_conf_module,
&ngx_events_module,
&ngx_http_module,
&ngx_http_core_module,
// ... more modules
&ngx_http_fastdfs_module, // Third-party module
NULL
};
|
This is why adding modules requires recompilation — the module list is determined at compile time.
5. FastDFS Module Integration
5.1 Preparation
1
2
3
4
5
6
7
| # Download source
wget https://nginx.org/download/nginx-1.24.0.tar.gz
git clone https://github.com/happyfish100/fastdfs-nginx-module.git
# Extract
tar -xzf nginx-1.24.0.tar.gz
cd nginx-1.24.0
|
1
2
3
4
5
6
7
| ./configure \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_realip_module \
--with-http_stub_status_module \
--add-module=../fastdfs-nginx-module/src
|
5.3 Compile and Install
1
2
3
4
5
6
7
8
9
| # Compile (use all CPU cores)
make -j$(nproc)
# Install
sudo make install
# Verify
/usr/local/nginx/sbin/nginx -V
# Output should include --add-module=.../fastdfs-nginx-module
|
1
2
3
4
5
6
7
8
9
10
11
| # /etc/nginx/nginx.conf
http {
server {
listen 80;
# FastDFS file access
location /group1/M00 {
ngx_fastdfs_module;
}
}
}
|
6. Compilation Optimization Strategies
1
2
3
4
5
6
| ./configure \
# Compiler optimization
--with-cc-opt='-O3 -march=native -mtune=native' \
# Linker optimization
--with-ld-opt='-Wl,-O1 -Wl,--as-needed'
|
Optimization level explanation:
| Flag | Effect | Use Case |
|---|
-O0 | No optimization | Debugging |
-O2 | Balanced optimization | Production (recommended) |
-O3 | Aggressive optimization | Maximum performance |
-march=native | Target current CPU | Non-container environments |
6.2 Security Hardening
1
2
3
4
5
6
7
8
9
10
| ./configure \
# Stack protection
--with-cc-opt='-fstack-protector-strong -D_FORTIFY_SOURCE=2' \
# RELRO (lazy binding protection)
--with-ld-opt='-Wl,-z,relro -Wl,-z,now' \
# PIE (address space randomization)
--with-cc-opt='-fPIE' \
--with-ld-opt='-pie'
|
6.3 Slim Binary
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # Remove unneeded modules
./configure \
--without-http_autoindex_module \
--without-http_browser_module \
--without-http_empty_gif_module \
--without-http_geo_module \
--without-http_map_module \
--without-http_split_clients_module \
--without-http_userid_module
# Strip symbol table after compile
strip /usr/local/nginx/sbin/nginx
# Compare size
ls -lh /usr/local/nginx/sbin/nginx
# From ~5MB to ~1.5MB
|
7. Production Deployment
7.1 Systemd Service File
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| # /etc/systemd/system/nginx.service
[Unit]
Description=Nginx HTTP Server
After=network.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
|
7.2 Zero-Downtime Upgrade
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 1. Compile new version (don't install)
./configure ... && make
# 2. Backup old binary
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
# 3. Replace binary
cp objs/nginx /usr/local/nginx/sbin/nginx
# 4. Send USR2 to old process, start new process
kill -USR2 $(cat /var/run/nginx.pid)
# 5. Gracefully shut down old workers
kill -WINCH $(cat /var/run/nginx.pid.oldbin)
# 6. After confirming success, stop old master
kill -QUIT $(cat /var/run/nginx.pid.oldbin)
|
8. Troubleshooting
8.1 Compilation Error Debugging
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # View detailed errors
cat objs/autoconf.err
# Common issues
# 1. Missing PCRE
./configure: error: the HTTP rewrite module requires the PCRE library
# Solution: apt install libpcre3-dev
# 2. Missing OpenSSL
./configure: error: SSL modules require the OpenSSL library
# Solution: apt install libssl-dev
# 3. Third-party module path wrong
./configure: error: no /path/to/module/config was found
# Solution: Check if config file exists in module directory
|
8.2 Runtime Debugging
1
2
3
4
5
6
7
8
| # Test configuration
nginx -t
# View loaded modules
nginx -V 2>&1 | tr ' ' '\n' | grep module
# Start in debug mode
nginx -g "daemon off; error_log /dev/stderr debug;"
|
9. Summary
| Topic | Takeaway |
|---|
| Module mechanism | Static compile vs dynamic load |
| Configure | Auto-detect + generate Makefile |
| Compile optimization | -O2 + security hardening flags |
| Zero-downtime upgrade | USR2 + WINCH signals |
Core insight: Understanding Nginx’s build system not only enables flexible customization, but also deepens understanding of C project build processes — applicable to other system software like Redis and Linux Kernel.