
Nginx(发音为"engine-x")是全球部署最广泛的网络服务器之一,Netflix、Airbnb、GitHub 等高流量网站都在使用它。其事件驱动、非阻塞架构使单个工作进程无需大量资源即可处理数万个并发连接。本教程将带你从零开始在 Ubuntu 22.04 VPS 上安装 Nginx,涵盖静态文件服务、虚拟主机、Node.js 反向代理、Let's Encrypt SSL、Gzip 压缩以及基础安全响应头等内容。
Nginx 是什么?与 Apache 有何不同?
Apache 和 Nginx 都是主流的网络服务器,但它们处理连接的方式从根本上有所不同。
Apache:基于进程 / 线程的模型
Apache 采用基于进程(或线程)的并发模型。每收到一个请求,就会新建一个进程或线程。当并发量较高时(例如 1,000 个同时连接),Apache 会创建 1,000 个进程或线程,消耗大量内存与 CPU。这种模型对动态内容和 .htaccess 灵活性支持较好,但在高负载下扩展效率较低。
Nginx:事件驱动、非阻塞
Nginx 采用事件驱动、非阻塞 I/O 模型。单个工作进程可通过事件队列同时管理数千个连接,而无需逐一阻塞等待。在相同流量负载下,Nginx 的内存占用通常远低于 Apache。
- Apache:适合依赖 .htaccess 或需要大量模块(mod_rewrite、mod_php)的网站。
- Nginx:适合静态文件服务、作为 Node.js/Python/PHP-FPM 的反向代理,以及需要最高性能的高流量网站。
- 内存占用:在高并发情况下,Nginx 的内存消耗通常比 Apache 低 2–5 倍。
- 静态文件:Nginx 开箱即用时,提供静态资源(HTML、CSS、JS、图片)的速度明显快于 Apache。
如何选择?如果你在 VPS 上运行 Node.js、Python(Django/Flask)或 PHP-FPM,并需要一个轻量级反向代理,Nginx 是更合适的选择。如果你依赖 DirectAdmin 面板或需要每目录 .htaccess 覆盖,Apache 可能更方便。
在 Ubuntu 22.04 上安装 Nginx
通过 SSH 连接到你的 VPS,然后运行以下命令安装并启动 Nginx。
第一步:更新软件包索引并安装
apt update && apt install nginx -y
第二步:启用并启动服务
systemctl enable nginx systemctl start nginx
enable 命令确保 Nginx 在服务器重启后自动运行,start 命令则立即启动服务。
第三步:检查状态与 80 端口
# Check that Nginx is running systemctl status nginx # Confirm Port 80 is listening ss -tlnp | grep :80 # If using UFW, open HTTP and HTTPS ufw allow 'Nginx Full' ufw status
打开浏览器,访问你的 VPS IP 地址,例如 http://123.456.789.0。如果看到"Welcome to nginx!"页面,说明安装成功。
Nginx 文件结构概览
在修改配置之前,了解文件布局能为你节省大量排查问题的时间。
/etc/nginx/ ├── nginx.conf # Main config file (global settings) ├── conf.d/ # Auto-included configs (custom global settings) ├── sites-available/ # All virtual host definitions (stored but not yet active) │ └── default # Default virtual host ├── sites-enabled/ # Symlinks to active virtual hosts │ └── default -> ../sites-available/default ├── modules-available/ # Available modules ├── modules-enabled/ # Loaded modules └── snippets/ # Reusable config fragments (e.g. SSL params)
- nginx.conf:设置 worker_processes、events 块和 include 路径,通常无需大量修改。
- sites-available/:存放所有虚拟主机配置文件,未创建软链接前不会生效。
- sites-enabled/:Nginx 只加载此目录中的配置,这里的文件均为指向 sites-available 的软链接。
为静态网站配置虚拟主机
在 Nginx 术语中,"虚拟主机"称为 server block(服务器块)。它告知 Nginx 响应哪个域名、文件存放在哪里,以及如何处理请求。
创建网站根目录
# Create the document root mkdir -p /var/www/mysite.com/html # Set ownership to www-data (the user Nginx runs as) chown -R www-data:www-data /var/www/mysite.com # Set appropriate permissions chmod -R 755 /var/www/mysite.com
创建服务器块配置文件
nano /etc/nginx/sites-available/mysite.conf
添加以下内容,将 mysite.com 替换为你的域名。
server {
listen 80;
listen [::]:80;
server_name mysite.com www.mysite.com;
root /var/www/mysite.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# Block access to hidden files (e.g. .env, .git)
location ~ /\. {
deny all;
}
# Log files
access_log /var/log/nginx/mysite.com.access.log;
error_log /var/log/nginx/mysite.com.error.log;
}启用虚拟主机并重新加载
# Create a symlink from sites-available to sites-enabled ln -s /etc/nginx/sites-available/mysite.conf /etc/nginx/sites-enabled/ # Test the config for syntax errors (very important!) nginx -t # If the test passes, reload gracefully (no downtime) systemctl reload nginx
重要提示:每次执行 systemctl reload nginx 之前,务必先运行 nginx -t。若配置文件存在语法错误而直接重载,Nginx 可能无法启动,导致网站宕机。
静态文件服务:root、index、try_files 与 location 块
以下几个关键指令控制 Nginx 如何提供静态内容。这里是一个扩展示例,为静态资源添加了缓存响应头。
server {
listen 80;
server_name mysite.com www.mysite.com;
root /var/www/mysite.com/html;
# Files to serve when the request path is a directory
index index.html index.htm;
# Primary location: try exact file, then directory, then 404
location / {
try_files $uri $uri/ =404;
}
# Cache images and static assets for 30 days
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|svg)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
# Block hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}- root:设置 Nginx 查找文件的网站根目录。
- index:当请求路径解析为目录时,返回的默认文件。
- try_files $uri $uri/ =404:依次尝试将 URI 作为文件、目录提供,若均不存在则返回 404。
- location ~* ...:对特定文件类型进行不区分大小写的正则匹配。
Nginx 作为 Node.js / PHP-FPM 的反向代理
Nginx 最常见的用途之一是充当反向代理——位于应用服务器(Node.js、Python、PHP-FPM)前端,转发请求并处理 TLS 终止、缓存和压缩。
Node.js 反向代理
server {
listen 80;
server_name myapp.com www.myapp.com;
location / {
proxy_pass http://localhost:3000;
# Forward original headers to the application
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeout settings
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}负载均衡的 Upstream 块
若你运行多个应用实例(例如 Node.js 集群或多台应用服务器),可使用 upstream 块在它们之间分发流量。
# Define the upstream group before the server block
upstream myapp_backend {
# Round-robin by default
server localhost:3000;
server localhost:3001;
server localhost:3002;
# Reuse connections with keepalive
keepalive 16;
}
server {
listen 80;
server_name myapp.com www.myapp.com;
location / {
proxy_pass http://myapp_backend;
proxy_http_version 1.1;
proxy_set_header Connection ""; # Required for keepalive upstream
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}PHP-FPM 反向代理
server {
listen 80;
server_name myphp.com www.myphp.com;
root /var/www/myphp.com/html;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Pass PHP files to PHP-FPM
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}使用 Let's Encrypt 和 Certbot 配置 SSL
Let's Encrypt 是一家免费的证书颁发机构,可自动签发 SSL 证书。Certbot 是官方客户端,能够与 Nginx 直接集成,通过一条命令完成证书的申请与安装。
第一步:安装 Certbot
apt install certbot python3-certbot-nginx -y
第二步:申请证书并自动配置 Nginx
# Replace example.com with your domain # Certbot will update nginx config automatically and redirect HTTP to HTTPS certbot --nginx -d example.com -d www.example.com
Certbot 会提示输入邮箱地址(用于证书到期通知),并询问是否将所有 HTTP 流量重定向至 HTTPS。强烈建议选择重定向。
第三步:验证自动续签
Certbot 会安装一个 systemd 定时器(或 cron 任务),在证书到期前自动续签。通过模拟续签(dry run)验证其正常运行。
# Test renewal without actually renewing certbot renew --dry-run # Check the systemd timer status systemctl status certbot.timer # Or check the cron entry (depending on your system) cat /etc/cron.d/certbot
Let's Encrypt 证书有效期为 90 天。当剩余有效期不足 30 天时,Certbot 会自动续签。
前提条件:运行 Certbot 之前,域名的 DNS A 记录必须已指向你的 VPS IP 地址。若域名未解析到该服务器,Certbot 的域名所有权验证(ACME challenge)将会失败。
Nginx 的 Gzip 压缩
启用 Gzip 压缩可将传输文件大小缩减 60–80%,显著提升 HTML、CSS、JS 和 JSON 响应的页面加载速度。
将以下内容添加到 /etc/nginx/nginx.conf 的 http 块中,或在 /etc/nginx/conf.d/gzip.conf 创建专用配置文件。
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/x-javascript
application/xml
application/xml+rss
application/xhtml+xml
image/svg+xml
font/woff
font/woff2;- gzip_comp_level 6:压缩级别从 1(最快/压缩率最低)到 9(最慢/压缩率最高),级别 6 是性能与压缩率的良好平衡点。
- gzip_min_length 256:跳过小于 256 字节的文件——对小文件压缩得不偿失。
- gzip_vary on:添加
Vary: Accept-Encoding响应头,确保缓存服务器能正确区分处理压缩与未压缩的响应。
Nginx 的安全响应头
添加安全相关的响应头可防御常见攻击向量,如点击劫持、MIME 类型嗅探和信息泄露。将以下内容添加到 server 块内。
server {
# ... other config ...
# Prevent clickjacking (disallow embedding in iframes from other origins)
add_header X-Frame-Options "SAMEORIGIN" always;
# Prevent MIME type sniffing
add_header X-Content-Type-Options "nosniff" always;
# Control the referrer sent to third-party sites
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Legacy XSS protection for older browsers
add_header X-XSS-Protection "1; mode=block" always;
# Force HTTPS for the duration of max-age (requires SSL to be working first)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Hide the Nginx version number from response headers
server_tokens off;
}注意:仅在确认 HTTPS 配置正常运行后,再添加 Strict-Transport-Security(HSTS)。一旦设置,浏览器将在整个 max-age 期间拒绝 HTTP 连接——若 SSL 出现问题,用户将无法访问网站。
测试配置与安全重载
Nginx 内置配置测试功能,在每次重载或重启前务必运行,以防止因配置错误导致服务中断。
# Test config syntax without touching the running server nginx -t # Expected output on success: # nginx: the configuration file /etc/nginx/nginx.conf syntax is ok # nginx: configuration file /etc/nginx/nginx.conf test is successful # Graceful reload (zero downtime — serves in-flight requests until complete) systemctl reload nginx # Full restart (brief downtime — use only when necessary) systemctl restart nginx # Tail the error log in real time tail -f /var/log/nginx/error.log # Tail the access log in real time tail -f /var/log/nginx/access.log
重载 vs 重启:systemctl reload nginx 执行优雅重载——Nginx 以更新后的配置 fork 出新的工作进程,同时旧进程继续处理进行中的请求,实现零停机。而 restart 会完全停止并重新启动 Nginx,可能中断活跃连接。
常见问题与解决方法
502 Bad Gateway
此错误表示 Nginx 无法连接到后端(Node.js 或 PHP-FPM 已停止,或端口配置错误)。
# Check that the backend service is running systemctl status php8.2-fpm # Or for Node.js ps aux | grep node # Confirm the backend is listening on the expected port ss -tlnp | grep 3000 # Review Nginx error logs tail -100 /var/log/nginx/error.log # Restart the backend systemctl restart php8.2-fpm
权限被拒绝(403 Forbidden)
通常由文件或目录权限不正确引起,也可能是 AppArmor/SELinux 阻止了访问。
# Check ownership of files in the document root
ls -la /var/www/mysite.com/
# Fix ownership for www-data
chown -R www-data:www-data /var/www/mysite.com/
# Set correct permissions: directories 755, files 644
find /var/www/mysite.com/ -type d -exec chmod 755 {} \;
find /var/www/mysite.com/ -type f -exec chmod 644 {} \;配置语法错误
编辑出错后会发生此问题。nginx -t 将失败,Nginx 会拒绝重载。
# Run to see the exact error and line number nginx -t # Common error messages: # nginx: [emerg] unexpected "}" — missing semicolon on a previous line # nginx: [emerg] "server" directive is not allowed here — block is in the wrong place # nginx: [emerg] host not found in upstream — upstream name or port is wrong # If Nginx stopped entirely, restore the last known-good config # then fix the error and start again
Nginx 显示默认页面而非你的网站
# Check that the symlink exists in sites-enabled ls -la /etc/nginx/sites-enabled/ # Verify the server_name matches your domain grep server_name /etc/nginx/sites-available/mysite.conf # Remove the default site if it is interfering rm /etc/nginx/sites-enabled/default nginx -t && systemctl reload nginx
准备好在自己的 VPS 上运行 Nginx 了吗?
AsiaGB VPS 提供完整的 root 权限,几分钟内即可安装 Nginx、Node.js 或 PHP-FPM。Linux VPS 套餐起价 750 泰铢/月,数据中心位于泰国和新加坡。
查看 AsiaGB VPS 套餐