当前位置:首页>Linux>Linux、Nginx学习第三周从零搭一个 Nginx:安装、目录结构、第一个站点,10 分钟跑起来

Linux、Nginx学习第三周从零搭一个 Nginx:安装、目录结构、第一个站点,10 分钟跑起来

  • 2026-10-11 06:15:02
Linux、Nginx学习第三周从零搭一个 Nginx:安装、目录结构、第一个站点,10 分钟跑起来

前两篇把 Linux 命令和权限打底打完,从这一篇起进入 Nginx 主战场。

第一次接触 Nginx 的人,最容易卡在「装好了不知道改哪个文件」「改完不知道怎么生效」「配错了不知道哪里看错误」。这一篇按真实部署流程走一遍:装上去 → 看目录结构 → 写第一个站点配置 → 验证生效 → 看日志。10 分钟跑起来一个能访问的静态站点,对 Nginx 的整体结构也就有了感觉。


一、Nginx 三种安装姿势对比

方式
拿到的版本
适用场景
卸载干净度
发行版仓库
偏老(如 Ubuntu 22.04 默认 1.18)
学习、内部工具
apt purge 干净
官方仓库
最新稳定(1.24+)
生产推荐
apt purge 干净
源码编译
任意 + 自定义模块
需 Lua / Brotli / 第三方模块
make uninstall 不彻底
Docker
镜像选定
容器化部署
删容器即清

新人推荐路径:本地学习用发行版仓库(最简单);生产用官方仓库(最新稳定版);需要 Lua / brotli 时上 OpenResty 或 nginx + 模块编译。

Ubuntu / Debian 安装(发行版仓库)

bash
sudo apt updatesudo apt install nginx -y# 验证nginx -v# nginx version: nginx/1.18.0 (Ubuntu)sudo systemctl status nginx

Ubuntu 装官方最新版

bash
# 1. 装必要工具sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring -y# 2. 加 Nginx 官方签名 keycurl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \  | sudotee /usr/share/keyrings/nginx-archive-keyring.gpg > /dev/null# 3. 加仓库(mainline 是最新主线、stable 是稳定)echo"deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" \  | sudotee /etc/apt/sources.list.d/nginx.list# 4. 安装sudo apt updatesudo apt install nginx -ynginx -v# nginx version: nginx/1.27.x

CentOS / Rocky / RHEL 安装

bash
# 系统自带 dnf 仓库版本一般稳定但偏老sudo dnf install nginx -y# 装官方最新(推荐)sudotee /etc/yum.repos.d/nginx.repo <<'EOF'[nginx-stable]name=nginx stable repobaseurl=http://nginx.org/packages/centos/$releasever/$basearch/gpgcheck=1enabled=1gpgkey=https://nginx.org/keys/nginx_signing.keyEOFsudo dnf install nginx -y

Docker 起一个(最快验证)

bash
docker run -d --name nginx-demo \  -p 8080:80 \  -v $(pwd)/html:/usr/share/nginx/html:ro \  nginx:1.27-alpinecurl http://localhost:8080

容器化最大的好处:测完 docker rm -f nginx-demo 一键清,本机零污染。


二、安装后的目录结构地图

装完后第一件事是搞清楚配置、日志、文档都在哪儿。Ubuntu/Debian 系和 CentOS/RHEL 系结构不完全一样:

Ubuntu / Debian(apt 装的)

/etc/nginx/├── nginx.conf                # 主配置入口├── conf.d/                   # 通用配置片段(推荐自己加文件在这)├── sites-available/          # **Debian 特有**:所有站点配置原始文件├── sites-enabled/            # **Debian 特有**:通过软链启用的站点├── snippets/                 # 复用片段(fastcgi-php.conf 等)├── mime.types                # MIME 类型映射├── modules-available/├── modules-enabled/└── proxy_params              # 反代常用 header 片段/var/log/nginx/├── access.log                # 访问日志└── error.log                 # 错误日志(**最先看的文件**)/var/www/html/                # 默认站点根目录/usr/sbin/nginx               # 二进制/usr/share/doc/nginx/         # 文档

sites-available + sites-enabled 的逻辑:站点配置写在 sites-available/ 下,要启用就 ln -s 软链到 sites-enabled/。这是 Apache 时代留下的习惯,新人很容易在 sites-available 里改了配但忘了软链,发现配置不生效。

CentOS / RHEL / Rocky(dnf 装的)

/etc/nginx/├── nginx.conf├── conf.d/                   # **CentOS 没有 sites-* 目录,统一放 conf.d**├── default.d/├── mime.types└── fastcgi.conf/var/log/nginx//usr/share/nginx/html/        # 默认站点根(**注意路径不同**)

Nginx 官方仓库装的(不论发行版)

/etc/nginx/├── nginx.conf├── conf.d/                   # 只有 conf.d,没有 sites-*└── default.d//var/log/nginx//usr/share/nginx/html/

这是 Nginx 圈最高频的迷惑点:你查到的教程说 sites-enabled,你在 CentOS 上找不到——因为根本没有。新人记一条:

官方仓库 + CentOS 系 = 走 conf.d/,Debian 系 = 走 sites-enabled/。


三、nginx.conf 五大块结构

打开 /etc/nginx/nginx.conf,看到的不是一坨平铺配置,是有嵌套层级的:

nginx
# === main 上下文(全局)===user www-data;worker_processes auto;pid /run/nginx.pid;error_log /var/log/nginx/error.log warn;# === events 上下文(连接处理)===events {worker_connections1024;useepoll;}# === http 上下文(HTTP 协议层)===http {include /etc/nginx/mime.types;default_type application/octet-stream;sendfileon;keepalive_timeout65;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;# === include 进来的所有站点配置 ===include /etc/nginx/conf.d/*.conf;include /etc/nginx/sites-enabled/*;# === server 上下文(虚拟主机)===server {listen80 default_server;server_name _;root /var/www/html;# === location 上下文(URL 路径)===location / {try_files$uri$uri/ =404;        }    }}

五层嵌套关系:

main ├── events └── http      └── server           └── location

核心心智模型:

  • main / events:全局基础设置,一般不动
  • http:全站默认行为(日志格式、压缩、超时、SSL 默认),改这里影响所有站点
  • server:一个虚拟主机(一个域名 / 一组域名)
  • location:某个 URL 路径下的行为

写自己站点 99% 的时间是在 server + location 里改,main / events / http 几乎只在调优时碰。


四、写第一个站点:3 分钟可用

新人第一次自己写一个 Nginx 站点,先在 conf.d/ 下加文件,不要直接改 nginx.conf(升级时会被覆盖)。

bash
# 1. 准备静态文件sudomkdir -p /var/www/my-sitesudotee /var/www/my-site/index.html <<'EOF'<!doctype html><html><body>  <h1>Hello from Nginx</h1>  <p>First site is live.</p></body></html>EOF# 2. 改属主,让 nginx 用户能读sudochown -R www-data:www-data /var/www/my-site   # Ubuntu/Debian# sudo chown -R nginx:nginx /var/www/my-site       # CentOS# 3. 写一份最小可用 site 配置sudotee /etc/nginx/conf.d/my-site.conf <<'EOF'server {    listen 80;    server_name my-site.local;    root /var/www/my-site;    index index.html;    access_log /var/log/nginx/my-site.access.log;    error_log  /var/log/nginx/my-site.error.log warn;    location / {        try_files $uri$uri/ =404;    }}EOF

Debian 系用 sites-enabled 的话:

bash
sudocp /etc/nginx/conf.d/my-site.conf /etc/nginx/sites-available/my-sitesudoln -s /etc/nginx/sites-available/my-site /etc/nginx/sites-enabled/sudorm /etc/nginx/conf.d/my-site.conf       # 避免重复 include

五、验证三件套:test → reload → curl

永远按这个顺序,缺一不可:

bash
# 1. 语法检查sudo nginx -t# nginx: the configuration file /etc/nginx/nginx.conf syntax is ok# nginx: configuration file /etc/nginx/nginx.conf test is successful# 2. 平滑重载(不断连)sudo nginx -s reload# 或者sudo systemctl reload nginx# 3. 访问验证curl -H "Host: my-site.local" http://127.0.0.1/# <!doctype html># <html><body>#   <h1>Hello from Nginx</h1># ...curl -I -H "Host: my-site.local" http://127.0.0.1/# HTTP/1.1 200 OK# Server: nginx/1.27.x# ...

铁律:永远先 nginx -t 再 nginx -s reload。Nginx master 收到 SIGHUP 后会先解析新配置:

  • 语法错误
    :master 会在 error.log 里报错并回滚到旧配置,老 worker 继续工作——这一类不会断
  • 语法对但语义错
    (监听端口被占、SSL 证书路径不存在、upstream DNS 解析失败等):新 worker 起不来,老 worker 还在跑,但部分场景(如 listen 改了端口、证书过期被拒)会导致新连接无人接、老连接慢慢断

nginx -t 能拦下语法错误,但拦不下「语法对、语义错」的问题。真正稳的姿势是:测试环境 reload 一遍、prod 改完再 nginx -t、配上 reload 后的探活脚本(curl /healthz 校验回 200)。

nginx 信号速查表

bash
sudo nginx -s reload     # SIGHUP:平滑重载配置(**不断连**)sudo nginx -s reopen     # SIGUSR1:重新打开日志文件(logrotate 用)sudo nginx -s stop       # SIGTERM:快速停止(**会断连**)sudo nginx -s quit       # SIGQUIT:优雅关闭(**等存量请求处理完**)
操作
信号
是否断连
适用场景
nginx -s reload
SIGHUP
不断
改配置后让生效
nginx -s reopen
SIGUSR1
不断
日志切割后重开日志句柄
nginx -s quit
SIGQUIT
不断(等完)
维护下线
nginx -s stop
SIGTERM
断
紧急停
systemctl restart nginx
KILL + START
断
升级二进制后必须

核心区别:reload 不断连,restart 会断连。日常改配置 reload 就够,只有升级 nginx 二进制本身才需要 restart。


六、Master + Worker 进程模型

启动后看一眼进程:

bash
ps auxf | grep nginx# root      1234  ... nginx: master process /usr/sbin/nginx# www-data  1235  ... \_ nginx: worker process# www-data  1236  ... \_ nginx: worker process
  • Master 进程
    :root 跑(读 80/443 端口需要 root 权限),不处理请求,只管 worker 的启停 / 信号转发 / 配置 reload
  • Worker 进程
    :普通用户(www-data / nginx)跑,实际处理请求的就是它,默认 worker_processes auto 会启动等于 CPU 核数的 worker

reload 时具体发生了什么:

1. master 收到 SIGHUP2. master 解析新配置,校验失败 → 不做任何事,原 worker 继续干活3. master 启动一批新 worker(用新配置)4. master 向老 worker 发 SIGQUIT5. 老 worker 处理完手头请求后自己退出

整个过程没有任何请求被中断——这就是为什么 nginx 改配置生产可以随便 reload。


七、日志怎么看

Nginx 日志分两类,新人遇到任何问题先看 error.log,再看 access.log。

access.log(每个请求一条)

默认的 combined 格式:

127.0.0.1 - - [25/Jun/2026:14:23:45 +0800] "GET /index.html HTTP/1.1" 200 89 "-" "curl/8.0.1"   │       │ │              │              │                            │    │  │      │   │       │ │              │              │                            │    │  │      └─ User-Agent   │       │ │              │              │                            │    │  └─ Referer   │       │ │              │              │                            │    └─ 响应体字节数   │       │ │              │              │                            └─ 状态码   │       │ │              │              └─ 请求行(方法 + URI + 协议)   │       │ │              └─ 时间   │       │ └─ 远程用户(HTTP 基本认证才有)   │       └─ identd(基本永远是 -)   └─ 客户端 IP

定位问题的实战 awk:

bash
# Top 10 访问 IPawk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10# 所有 5xx 错误请求awk '$9 >= 500 {print $0}' /var/log/nginx/access.log# 各状态码分布awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn

error.log(五级日志)

debug  → info  → notice  → warn  → error  → crit  → alert  → emerg

默认是 warn 级别(从 warn 起记录)。调试时改 error_log /var/log/nginx/error.log debug; 能看到非常详细的处理路径,但生产环境千万别开 debug——量大到爆磁盘。

最常见的几条 error 长这样:

# 后端连不通*123 connect() failed (111: Connection refused) while connecting to upstream# 权限不够(Nginx 用户读不到文件)*456 open() "/var/www/my-site/index.html" failed (13: Permission denied)# 路径不存在*789 "/var/www/my-site/" is not found (2: No such file or directory)

八、第一次踩坑清单

新人搭完发现「装好了访问不到」,按这个清单顺序排:

1. nginx 进程没启动

bash
sudo systemctl status nginx# 看 Active 状态、Main PID

2. 80 端口被别人占了

bash
sudo ss -lntp | grep ':80'# 如果是 Apache / 其他东西占了,要么停掉,要么 nginx 改听别的端口

3. 防火墙拦截

bash
# Ubuntu ufwsudo ufw statussudo ufw allow 80/tcp# CentOS firewalldsudo firewall-cmd --list-allsudo firewall-cmd --permanent --add-service=httpsudo firewall-cmd --reload# 云上别忘了「安全组」也要放行(云防火墙在 OS 防火墙之前生效)

4. SELinux 拦截(CentOS 高频)

bash
# 看一眼是不是 enforcinggetenforce# Enforcing# 临时关(仅排查用)sudo setenforce 0# 如果确认是 SELinux 拦截了 nginx 读 /var/www/my-site,正确做法是改上下文:sudochcon -Rt httpd_sys_content_t /var/www/my-sitesudo restorecon -Rv /var/www/my-site

Ubuntu 默认没装 SELinux,CentOS 默认 enforcing,这条是 CentOS 新人栽得最深的坑之一。

5. 文件权限不对

bash
# nginx worker 用什么用户跑?ps aux | grep "nginx: worker"# www-data ... nginx: worker process# 这个用户能不能读到你的文件?sudo -u www-data ls /var/www/my-site/index.html# 如果 Permission denied,就是权限或属主问题

常见解法:

bash
sudochown -R www-data:www-data /var/www/my-sitesudochmod -R 755 /var/www/my-site

6. server_name 没匹配上

bash
# 你的 server_name my-site.local,但 curl 直接打 http://127.0.0.1/# 没设 Host 头,Nginx 会用 default_server 处理(不是你的 my-site)# 测试时要么改 hosts 让域名指向 127.0.0.1,要么 curl 带 -H "Host: my-site.local"

写在最后

  • 装 Nginx 生产用官方仓库,开发用发行版仓库 / Docker 都行
  • Debian 系走 sites-enabled、CentOS / 官方包统一走 conf.d
    ,别复制错路径
  • nginx.conf 五大块嵌套:main / events / http / server / location,自己改 99% 在最后两层
  • 改完永远 nginx -t 再 nginx -s reload
    ,裸 reload 是事故温床
  • reload 不断连、restart 才断连
    ,日常改配置只 reload
  • 访问不到先按「进程 → 端口 → 防火墙 → SELinux → 权限 → server_name」六步排查,比瞎试快十倍
  • error.log 是诊断金矿,permission denied / connect refused / not found 三大常客

最新文章

随机文章