适用:Ubuntu 22.04/24.04、Debian 12、麒麟、openEuler 耗时:约 30 分钟 前置:E2(懂服务)、T1(会编辑文件)
先做出一个能访问的页面,再谈别的。 这一篇从零到"浏览器能看到东西",只用 nginx,不碰数据库、不碰后端。
一、nginx 是什么
一个 Web 服务器。 它做的事很简单:别人来请求,它把文件给他。
浏览器请求 https://example.com/index.html
↓
nginx 在 /var/www/html/ 找 index.html
↓
把文件内容发回去
它也能做更多(反向代理、负载均衡、HTTPS),但第一篇只讲"发文件"这一件事。
为什么用 nginx 而不是 Apache
| nginx | Apache | |
|---|---|---|
| 高并发 | 更好(事件驱动) | 中等(进程/线程模型) |
| 内存占用 | 低 | 较高 |
| 配置 | 简洁 | 灵活但啰嗦 |
| 生态 | 主流 | 老牌 |
现在新部署基本都是 nginx。 跟这个走没错。
二、安装
# Debian 系(Ubuntu / Debian / 麒麟桌面)
sudo apt update
sudo apt install nginx
# RPM 系(openEuler / CentOS / 麒麟服务器)
sudo dnf install nginx
装完自动启动(Debian 系)。检查:
systemctl status nginx
应该看到 active (running)。
如果没启动:
sudo systemctl enable --now nginx
三、立刻验证
装完就有一个默认页面。
# 本机测
curl -I http://127.0.0.1
期望输出:
HTTP/1.1 200 OK
Server: nginx/1.24.0 (Ubuntu)
...
浏览器访问 http://服务器IP,应该看到 “Welcome to nginx!"。
如果访问不了:
- 先
curl 127.0.0.1—— 本机能通吗?- 本机通、外部不通 → 防火墙或云安全组
- 见第九节排障
四、目录结构:先搞清楚文件在哪
| 路径 | 作用 |
|---|---|
/etc/nginx/nginx.conf | 主配置(一般不用改) |
/etc/nginx/sites-available/ | 站点配置(可用的) |
/etc/nginx/sites-enabled/ | 站点配置(启用的,是上面的软链接) |
/etc/nginx/conf.d/ | 另一种放站点配置的地方 |
/var/www/html/ | 默认网站根目录 |
/var/log/nginx/access.log | 访问日志 |
/var/log/nginx/error.log | 错误日志(排障看这个) |
sites-available和sites-enabled的关系: 写配置放 available,启用靠软链接到 enabled。 这样"停用"就是删链接,不用删配置。 RPM 系的 nginx 一般没有这两个目录,只有conf.d/。两种方式都行,任选。
五、搭一个自己的站点
第 1 步:准备网站文件
sudo mkdir -p /var/www/mysite
sudo nano /var/www/mysite/index.html
内容:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的站点</title>
<style>
body { font-family: system-ui, sans-serif; max-width: 40rem;
margin: 4rem auto; padding: 0 1.2rem; line-height: 1.8; }
h1 { border-bottom: 2px solid #eee; padding-bottom: .5rem; }
</style>
</head>
<body>
<h1>站点跑起来了</h1>
<p>这台机器上的 nginx 正在工作。</p>
<p><small id="t"></small></p>
<script>document.getElementById('t').textContent = new Date().toString();</script>
</body>
</html>
权限设对:
sudo chown -R www-data:www-data /var/www/mysite
sudo chmod -R 755 /var/www/mysite
www-data是 Debian 系 nginx 的运行用户。RPM 系通常是nginx。 检查:ps aux | grep nginx看 worker 进程的属主。
第 2 步:写站点配置
Debian 系:
sudo nano /etc/nginx/sites-available/mysite
RPM 系(或统一用这个位置):
sudo nano /etc/nginx/conf.d/mysite.conf
内容:
server {
listen 80;
listen [::]:80;
server_name _; # 暂时接受所有域名/IP
root /var/www/mysite;
index index.html;
charset utf-8;
# 访问日志单独放(多站点时便于区分)
access_log /var/log/nginx/mysite.access.log;
error_log /var/log/nginx/mysite.error.log;
location / {
try_files $uri $uri/ =404;
}
}
逐行解释:
| 行 | 作用 |
|---|---|
listen 80 | 监听 IPv4 的 80 端口 |
listen [::]:80 | 监听 IPv6 |
server_name _ | 匹配任何域名(占位符) |
root | 网站根目录 |
index | 默认首页文件 |
charset utf-8 | 中文不乱码的关键 |
try_files $uri $uri/ =404 | 先找文件,再找目录,都没有返回 404 |
第 3 步:启用(Debian 系)
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
RPM 系跳过这步(放 conf.d/ 就自动启用)。
第 4 步:检查语法 —— 这一步不能省
sudo nginx -t
期望:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
⚠️
nginx -t不通过就别 reload。 配置语法错会导致 nginx 起不来——如果这时重启了,网站直接挂掉。
第 5 步:生效
sudo systemctl reload nginx
用 reload 不用 restart:
| 命令 | 行为 |
|---|---|
reload | 平滑重载:新配置生效,已有连接不断 |
restart | 停掉再启动:所有连接中断,配置错了站点直接挂 |
改配置一律 reload。只有 nginx 本身升级才需要 restart。
第 6 步:验证
curl -I http://127.0.0.1
curl http://127.0.0.1 | head -5
浏览器打开 http://服务器IP,应该看到"站点跑起来了”。
六、关掉默认站点(可选)
装完 nginx 有个默认配置,会抢 80 端口的默认响应。
Debian 系:
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
这样你的站点就成了唯一的响应者。
不删也行,但如果发现访问 IP 显示的是 “Welcome to nginx”,说明默认站点在抢——删掉它。
七、几个马上会用到的配置
1. 加缓存(静态资源)
location ~* \.(jpg|jpeg|png|gif|webp|svg|ico|css|js|woff2?)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000, immutable";
}
图片和 CSS/JS 缓存 30 天,第二次访问就不重新下载了。
2. 禁止访问隐藏文件
location ~ /\.(?!well-known) {
deny all;
}
挡住 .git、.env 这类文件(well-known 例外,ACME 验证要用)。
3. 禁止列目录
autoindex off;
默认就是 off,但显式写一遍更保险——列目录会把你的文件结构暴露出去。
4. 自定义 404
error_page 404 /404.html;
location = /404.html {
internal;
}
5. 隐藏 nginx 版本号
在主配置 nginx.conf 的 http {} 块里加:
server_tokens off;
默认会返回 Server: nginx/1.24.0——这等于告诉攻击者"我有哪个版本的漏洞"。关掉后只返回 Server: nginx。
6. 加安全响应头
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
⚠️ 坑:server 块里只要出现任何
add_header,就会覆盖掉http层继承的所有add_header。 所以要么全写在 server 里,要么全写在 http 里——不能一半一半,否则会静默丢失。
八、一个稍完整的配置(可以直接用)
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/mysite;
index index.html;
charset utf-8;
server_tokens off;
autoindex off;
access_log /var/log/nginx/mysite.access.log;
error_log /var/log/nginx/mysite.error.log;
# 安全头(全量写,避免继承被覆盖)
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 隐藏文件和源文件
location ~ /\.(?!well-known) { deny all; }
location ~* \.(md|toml|yaml|yml|log|bak)$ { deny all; }
# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|webp|svg|ico|css|js|woff2?)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000, immutable" always;
add_header X-Content-Type-Options "nosniff" always;
}
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404.html;
location = /404.html { internal; }
}
九、排障:访问不了怎么办
按顺序查,不要乱试。
第 1 步:nginx 在跑吗
systemctl status nginx
不是 active (running):
sudo journalctl -u nginx -n 50 --no-pager
看最后几行的错误。
第 2 步:本机能访问吗
curl -I http://127.0.0.1
| 结果 | 说明 |
|---|---|
| 200 | nginx 正常,问题在外面 |
| 403 | 权限问题:/var/www/mysite 的文件 nginx 读不到 |
| 404 | 路径不对:root 指错,或者文件不在那 |
| 502 | 后端有问题(静态站不会出现) |
| 连接失败 | nginx 没监听 80 |
第 3 步:在监听 80 吗
sudo ss -ltnp | grep :80
应该看到 nginx 在 0.0.0.0:80 和 [::]:80 监听。
看不到 → 配置里 listen 写错了,或者被别的程序占了。
第 4 步:外网能到吗
# 从另一台机器
curl -I http://服务器IP
nc -zv 服务器IP 80
本机通、外面不通 → 防火墙。
# 看防火墙
sudo ufw status # Ubuntu
sudo firewall-cmd --list-all # RPM 系
sudo iptables -L -n | head -20 # 裸 iptables
开放 80 端口:
sudo ufw allow 80/tcp # ufw
sudo firewall-cmd --add-service=http --permanent # firewalld
sudo firewall-cmd --reload
⚠️ 云服务器还有一层"安全组",在云控制台网页上配。本机防火墙全开、安全组没放行,一样访问不了。 这是云上最常见的"为什么访问不了"。
第 5 步:看错误日志
sudo tail -30 /var/log/nginx/error.log
403 / 404 的具体原因都在这。
常见:
*1 open() "/var/www/mysite/index.html" failed (13: Permission denied)
→ 权限问题,chmod 755 + chown
*2 open() "/var/www/mysite/index.html" failed (2: No such file or directory)
→ 路径不对,检查 root 和文件名
十、动手:五个练习
练习 1:装 nginx 并访问默认页
sudo apt install nginx
systemctl status nginx
curl -I http://127.0.0.1
练习 2:搭自己的站点
按第五节做一遍,浏览器看到"站点跑起来了"。
练习 3:故意写错配置,看 nginx -t 报什么
sudo nano /etc/nginx/sites-available/mysite
# 把 try_files 那行的分号删掉
sudo nginx -t
会报 unexpected end of file, expecting ";"——这就是为什么必须先 -t。
改回来,再 -t,通过后 reload。
练习 4:制造一个 404 并看日志
curl -I http://127.0.0.1/不存在的页面
sudo tail -5 /var/log/nginx/mysite.error.log
练习 5:看访问日志
sudo tail -10 /var/log/nginx/mysite.access.log
能看到你的每次请求——IP、时间、路径、状态码、User-Agent。
十一、验证:你过关了吗
- 会装 nginx 并确认它在跑
- 知道站点配置放哪(
sites-available+sites-enabled,或conf.d) - 会写一个最小的
server块 - 每次改配置都先
nginx -t - 用
reload不用restart - 会看
error.log定位 403/404 - 知道本机通、外网不通要查防火墙和安全组
- 会关掉
server_tokens
十二、不行怎么办
Q1:nginx: command not found
没装,或者装失败了。重装:
sudo apt install --reinstall nginx
Q2:Job for nginx.service failed
配置有语法错。看详情:
sudo nginx -t
sudo journalctl -u nginx -n 30 --no-pager
Q3:403 Forbidden 最可能是权限,或者缺 index 文件:
ls -ld /var/www/mysite
ls -l /var/www/mysite/index.html
# 修
sudo chown -R www-data:www-data /var/www/mysite
sudo chmod -R 755 /var/www/mysite
别用 777——那给了所有人写权限。
Q4:403 但权限看着没问题
上级目录的 x 权限不够。用:
namei -l /var/www/mysite/index.html
逐层看,哪一层缺 x(见 E1)。
Q5:改了配置不生效
- 忘了
reload - 改的是
sites-available但没链接到sites-enabled - 有多个
server块抢同一个域名/端口,先匹配的赢
sudo nginx -T | grep -A5 "server_name"
-T 会输出最终生效的完整配置——这是排查"改了没生效"的利器。
Q6:显示的是 “Welcome to nginx” 而不是我的页面 默认站点在抢:
ls -l /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
Q7:中文显示乱码 缺 charset:
charset utf-8;
同时确认 HTML 里有 <meta charset="UTF-8">。
Q8:nginx -t 通过,但 reload 后站点挂了
看 error.log 和 journalctl -u nginx。
可能是:
- 端口被占(
Address already in use) - 证书文件不存在(HTTPS 配置引用了还没签的证书)
- 日志目录没权限
Q9:重启机器后网站没了 没设开机自启:
sudo systemctl enable nginx
十三、一句话总结
/var/www/放文件,server块说怎么发,nginx -t验语法,reload生效。本机
curl 127.0.0.1通、外面不通 → 防火墙或云安全组。改配置永远:
-t→reload,不用restart。
← 返回 第四周:架起来 下一篇 → S2|数据库入门:SQLite 和 MySQL