一、Nginx 是什么

Nginx(engine-x)是一个高性能的 HTTP 和反向代理服务器。核心特点:高并发、低内存、热部署。

它的三大核心用途:

用途 说明 场景
静态文件服务 直接把 HTML/CSS/JS/图片传给客户端 托管博客、官网
反向代理 接收请求后转发给后端服务 转发到 Docker 容器、API 服务
负载均衡 把请求分发到多台机器 高并发场景

二、安装

Linux(Ubuntu/Debian)

1
sudo apt update && sudo apt install nginx -y

常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 启动
sudo systemctl start nginx

# 设置开机自启
sudo systemctl enable nginx

# 重载配置(不中断服务)
sudo nginx -s reload

# 检查配置语法
sudo nginx -t

# 查看状态
sudo systemctl status nginx

安装后在浏览器访问服务器 IP,看到 Nginx 欢迎页面即为成功。

三、核心概念

1. 配置文件结构

一切配置都在 /etc/nginx/ 下:

1
2
3
4
5
/etc/nginx/
├── nginx.conf # 主配置文件
├── conf.d/ # 子配置目录(推荐放这里)
│ └── default.conf
└── sites-enabled/ # 站点配置(Ubuntu 特有)

nginx.conf 默认包含 include /etc/nginx/conf.d/*.conf;,所以通常只需要在 conf.d/ 下新建 .conf 文件即可。

2. 基本语法

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
# 全局块
worker_processes auto; # 工作进程数,设为 CPU 核心数

# events 块
events {
worker_connections 1024; # 每个进程最大连接数
}

# http 块
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

# server 块 = 一个虚拟主机(站点)
server {
listen 80;
server_name example.com;

# location 块 = 匹配 URL 路径
location / {
root /var/www/html;
index index.html;
}
}
}

层级关系:http > server > location

四、静态文件托管

最简单的场景 — 托管纯静态网站:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
listen 80;
server_name your-domain.com;

root /var/www/my-site;
index index.html index.htm;

location / {
try_files $uri $uri/ /index.html;
}

# 静态资源加缓存
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}

关键点:

  • try_files 把找不到的路径回退到 index.html,解决 SPA/Hexo 的路由刷新 404
  • expires 设置浏览器缓存时间,减轻服务器压力

开启 gzip

http 块或 server 块中加入:

1
2
3
4
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript image/svg+xml;
gzip_min_length 1000;
gzip_vary on;

五、反向代理

这才是 Nginx 最核心的场景 — 把请求转发给后端服务。

基本原理

1
2
浏览器 ──HTTPS──▶ Nginx:443 ──HTTP──▶ 后端:8080
(公网) (内网)

Nginx 作为统一入口,80/443 端口只归它,所有后端服务各自监听不同内部端口。

基本配置

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name api.your-domain.com;

location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}

多个站点同时配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 博客站点 -> 转发到 Docker 容器
server {
listen 80;
server_name blog.your-domain.com;

location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

# API 服务 -> 转发到 Node.js
server {
listen 80;
server_name api.your-domain.com;

location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

一个 nginx,N 个后端。域名不同,转发的端口不同。

容器端口绑定注意

1
2
3
4
5
# 推荐:只绑 127.0.0.1,外部只能通过 nginx 访问
docker run -d --name blog -p 127.0.0.1:8080:80 website-hexo

# 不推荐:绑 0.0.0.0,外部可以绕过 nginx 直接访问容器
docker run -d --name blog -p 8080:80 website-hexo

WebSocket 反向代理

1
2
3
4
5
6
location /ws {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

六、HTTPS 配置

Let’s Encrypt 免费获取 SSL 证书。

使用 Certbot 自动配置

1
2
3
4
5
6
7
8
# 安装 Certbot
sudo apt install certbot python3-certbot-nginx -y

# 自动申请 + 配置(certbot 会自己改 nginx 配置)
sudo certbot --nginx -d your-domain.com

# 设定自动续期
sudo systemctl enable certbot.timer

手动配置 SSL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
listen 443 ssl http2;
server_name your-domain.com;

ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
}
}

# HTTP 自动跳转 HTTPS
server {
listen 80;
server_name your-domain.com;
return 301 https://$host$request_uri;
}

七、常用配置片段

自定义 404 页面

1
2
3
4
error_page 404 /404.html;
location = /404.html {
root /var/www/error-pages;
}

访问控制

1
2
3
4
5
6
# 只允许特定 IP 访问
location /admin {
allow 192.168.1.0/24;
deny all;
proxy_pass http://127.0.0.1:9090;
}

限流

1
2
3
4
5
6
7
8
# http 块中定义
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

# location 中使用
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://127.0.0.1:3000;
}

日志格式

1
2
3
4
5
6
7
8
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';

access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
}

八、排错技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. 检查配置语法(最常用)
sudo nginx -t

# 2. 查看错误日志
sudo tail -f /var/log/nginx/error.log

# 3. 查看访问日志
sudo tail -f /var/log/nginx/access.log

# 4. 测试反向代理是否可达
curl http://127.0.0.1:8080

# 5. 查看端口占用
sudo lsof -i :80

九、总结

一个典型的单服务器部署架构:

1
2
3
4
5
6
7
8
9
10
11
                ┌─────────────────┐
│ Nginx :80/443 │
│ (反向代理) │
└───┬──────┬──────┘
│ │
┌───────────┘ └───────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ blog :8080 │ │ api :3000 │
│ (Hexo/Docker)│ │ (Node.js) │
└──────────────┘ └──────────────┘

记住核心原则:一个端口只给 Nginx,其余服务全部走内网转发