适用: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

nginxApache
高并发更好(事件驱动)中等(进程/线程模型)
内存占用低较高
配置简洁灵活但啰嗦
生态主流老牌

现在新部署基本都是 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!"。

如果访问不了:

  1. 先 curl 127.0.0.1 —— 本机能通吗?
  2. 本机通、外部不通 → 防火墙或云安全组
  3. 见第九节排障

四、目录结构:先搞清楚文件在哪

路径作用
/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
结果说明
200nginx 正常,问题在外面
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