主题
02 · 安装与第一次启动
生活类比:装 Nginx 就像买一台咖啡机。
- 用 Docker → 网购自动化版(开箱即用,按一下就出咖啡)
- 用 apt / yum → 楼下电器店(包邮包售后,但版本可能旧)
- 编译安装 → 自己组装手摇磨豆机(最灵活,也最折腾)
1. 三种主流安装方式 · 怎么选
| 方式 | 适合谁 | 优点 | 缺点 |
|---|---|---|---|
| 🐳 Docker | 学习、本地、容器化部署 | 干净、版本可控、不污染系统 | 需要先学 Docker 基础 |
| 📦 apt / yum | 服务器运维、已熟悉 Linux | 一行命令搞定,开机自启 | 版本可能落后半年 |
| 🔧 源码编译 | 想加第三方模块(如 OpenResty) | 高度可定制 | 步骤多、依赖一堆 |
新手建议:先用 Docker 跑通,理解配置,再考虑别的。下面三种都讲。
2. 方式一 · Docker(推荐 ⭐⭐⭐⭐⭐)
2.1 一行命令把 Nginx 跑起来
bash
docker run -d \
--name nginx-learn \
-p 8080:80 \
nginx:1.25-alpine参数解释:
| 参数 | 作用 |
|---|---|
-d | 后台运行(detach) |
--name | 给容器起个名(方便后续 stop / rm) |
-p 8080:80 | 把宿主机 8080 映射到容器内 80 端口 |
nginx:1.25-alpine | 镜像 + 标签(alpine = 极简 Linux,5MB) |
打开浏览器访问 http://localhost:8080 → 看到 "Welcome to nginx!" = 成功 ✅
2.2 看看默认配置是啥样
bash
docker exec -it nginx-learn cat /etc/nginx/nginx.confbash
docker exec -it nginx-learn ls /etc/nginx/conf.d/会看到一个 default.conf,里面就是开箱即用的"欢迎页"配置。
2.3 用自己的配置覆盖默认
新建一个目录:
bash
mkdir -p ~/nginx-learn/{html,conf}
echo "<h1>Hello Nginx 👋</h1>" > ~/nginx-learn/html/index.html写一份最小 conf:
nginx
# ~/nginx-learn/conf/default.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
}启动:
bash
docker run -d --name my-nginx \
-p 8080:80 \
-v ~/nginx-learn/html:/usr/share/nginx/html:ro \
-v ~/nginx-learn/conf/default.conf:/etc/nginx/conf.d/default.conf:ro \
nginx:1.25-alpine
:ro= 只读挂载,更安全。
2.4 改了配置怎么生效
bash
# 方法 1:reload(推荐,不断连)
docker exec my-nginx nginx -s reload
# 方法 2:重启容器(会断 1 秒连接)
docker restart my-nginx2.5 关掉 / 删掉
bash
docker stop my-nginx # 停止
docker rm my-nginx # 删除容器
docker rmi nginx:1.25-alpine # 删除镜像(一般不需要)3. 方式二 · apt / yum
3.1 Ubuntu / Debian(apt)
bash
sudo apt update
sudo apt install -y nginx
sudo systemctl enable --now nginx # 开机自启 + 立即启动3.2 CentOS / RHEL / 阿里云 Linux(yum / dnf)
bash
sudo yum install -y epel-release
sudo yum install -y nginx
sudo systemctl enable --now nginx3.3 装完之后的关键路径
| 路径 | 是啥 |
|---|---|
/etc/nginx/nginx.conf | 主配置文件 |
/etc/nginx/conf.d/*.conf | 一般虚拟主机配置(按文件拆分) |
/etc/nginx/sites-available/ | Debian 系特有:可用站点配置池 |
/etc/nginx/sites-enabled/ | Debian 系特有:实际启用的软链 |
/var/log/nginx/access.log | 访问日志 |
/var/log/nginx/error.log | 错误日志 |
/var/www/html/ | 默认网站根目录 |
/usr/sbin/nginx | 二进制可执行文件 |
不同发行版略有差异,记住"主配置在
/etc/nginx/nginx.conf、日志在/var/log/nginx/"就够 80% 场景。
4. 方式三 · 源码编译(进阶)
bash
# 1. 装编译依赖
sudo apt install -y build-essential libpcre3-dev libssl-dev zlib1g-dev
# 2. 下载源码
wget https://nginx.org/download/nginx-1.25.3.tar.gz
tar zxvf nginx-1.25.3.tar.gz && cd nginx-1.25.3
# 3. 配置(这里加了 SSL、HTTP/2、gzip)
./configure \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_gzip_static_module \
--with-http_stub_status_module
# 4. 编译 + 安装
make && sudo make install
# 5. 启动
/usr/local/nginx/sbin/nginx什么时候要源码编译?想加官方没集成的模块(比如
nginx-rtmp-module、nginx-upload-module)。日常开发不需要。
5. nginx 命令行 5 大动作(记牢)
bash
nginx # 启动
nginx -s stop # 立刻停(粗暴)
nginx -s quit # 优雅停(处理完当前请求再退)
nginx -s reload # 重载配置 ✨ 90% 用这个
nginx -t # 仅测试配置文件语法 ⭐ 改配置后必跑最常见工作流:
bash
# 改完 nginx.conf 之后
sudo nginx -t # ① 先测试语法
sudo nginx -s reload # ② 没问题就 reload💡
-t是救命稻草。直接 reload 配置错了 = nginx 起不来 = 网站 502。养成"reload 前必 -t"的肌肉记忆。
6. 第一次跑通的小作业 ✏️
学会这一章的 4 个动作,下一章才能继续。
任务
- 启动一个 Nginx 容器(或装好 Nginx 服务),监听本地 8080 端口
- 把
<h1>我的第一个 Nginx 页面 - {你的名字}</h1>放到默认 root 下 - 用
curl http://localhost:8080看到自己的内容 - 停掉 Nginx,再启动它
验收脚本(在 Linux/Mac 上)
bash
# 启动
docker run -d --name first-nginx -p 8080:80 nginx:1.25-alpine
# 把自定义 HTML 拷进去
echo "<h1>我的第一个 Nginx 页面 - LiLei</h1>" | \
docker exec -i first-nginx tee /usr/share/nginx/html/index.html
# 验证
curl http://localhost:8080
# 期望输出:<h1>我的第一个 Nginx 页面 - LiLei</h1>
# 干掉
docker rm -f first-nginx跑通了,恭喜你 — Nginx 已经"被你养起来了"。
7. ⚠️ 新手常踩的坑
- 80 端口被占 →
bind() to 0.0.0.0:80 failed (98: Address already in use)→sudo lsof -i:80看占用,杀掉对应进程或换端口。 - 改了 conf 没生效 → 忘了
nginx -s reload,或者改的是 conf 但 nginx 加载的是另一个 conf →nginx -t输出里的the configuration file ... syntax is ok那一行就是它真正读的文件路径。 - Docker 里改宿主机 html 文件没刷出来 → 浏览器缓存。
Ctrl+Shift+R强刷或加查询参数?v=1。 - systemctl status nginx 显示 active 但访问不通 → 防火墙!
- Ubuntu:
sudo ufw allow 80/tcp - CentOS:
sudo firewall-cmd --add-port=80/tcp --permanent && sudo firewall-cmd --reload - 云服务器:还要去安全组里开 80/443
- Ubuntu:
- 权限不够 → 直接执行
nginx报Permission denied:用sudo,或者把 worker 改成自己的用户(学习阶段可以)。
8. 章末面试题速览
详见
qa.md第 4-5 题。
nginx -s reload和restart区别? → reload 不断连接、平滑切换;restart 会断开所有连接重启进程。- 改了 conf 没 reload 会咋样? → 不会生效。Nginx 进程还在用旧配置。
- 如何让 Nginx 开机自启? →
systemctl enable nginx(systemd 的标准动作)。
9. 一句话总结
学习用 Docker 一行命令,生产用 apt 加 systemd——记牢
nginx -t和nginx -s reload,你就拿到了 Nginx 的"启动按钮"。
下一章 → 03 · 配置文件结构:把配置文件这只洋葱一层层剥开。
💻 示例代码
下方提供了 docker-compose.yml、最小 nginx.conf、和一个完整的 commands.sh 脚本,跟着运行就能起一个本地 Nginx。
💻 示例代码
bash
#!/usr/bin/env bash
# Nginx · 第 02 章 · 一键体验脚本
# 用法:bash commands.sh up 启动
# bash commands.sh down 停止
# bash commands.sh logs 跟踪日志
# bash commands.sh test nginx -t 测试配置语法
# bash commands.sh reload reload 配置(不断连)
set -euo pipefail
CONTAINER=nginx-learn
IMAGE=nginx:1.25-alpine
PORT=${PORT:-8080}
ROOT=$(cd "$(dirname "$0")" && pwd)
cmd_up() {
mkdir -p "$ROOT/html" "$ROOT/conf" "$ROOT/logs"
if [ ! -f "$ROOT/html/index.html" ]; then
cat > "$ROOT/html/index.html" <<'EOF'
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="utf-8"><title>Hello Nginx</title></head>
<body style="font-family:sans-serif;text-align:center;padding:40px;">
<h1>👋 Hello Nginx</h1>
<p>第一份属于你的网页 · 来自 Nginx 学习笔记</p>
</body>
</html>
EOF
fi
if [ ! -f "$ROOT/conf/default.conf" ]; then
cp "$ROOT/default.conf" "$ROOT/conf/default.conf"
fi
docker rm -f "$CONTAINER" >/dev/null 2>&1 || true
docker run -d \
--name "$CONTAINER" \
-p "${PORT}:80" \
-v "$ROOT/html:/usr/share/nginx/html:ro" \
-v "$ROOT/conf/default.conf:/etc/nginx/conf.d/default.conf:ro" \
-v "$ROOT/logs:/var/log/nginx" \
"$IMAGE" >/dev/null
echo "✅ Nginx 已启动 → http://localhost:${PORT}"
echo " 健康检查 → http://localhost:${PORT}/healthz"
}
cmd_down() {
docker rm -f "$CONTAINER" >/dev/null 2>&1 || true
echo "🛑 已停止并移除容器 $CONTAINER"
}
cmd_logs() { docker logs -f "$CONTAINER"; }
cmd_test() { docker exec "$CONTAINER" nginx -t; }
cmd_reload() { docker exec "$CONTAINER" nginx -s reload && echo "🔁 Reload 完成"; }
cmd_shell() { docker exec -it "$CONTAINER" sh; }
case "${1:-}" in
up) cmd_up ;;
down) cmd_down ;;
logs) cmd_logs ;;
test) cmd_test ;;
reload) cmd_reload ;;
shell) cmd_shell ;;
*)
echo "Usage: $0 {up|down|logs|test|reload|shell}" ;;
esactxt
server {
listen 80;
server_name localhost;
access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location = /healthz {
access_log off;
return 200 "ok\n";
add_header Content-Type text/plain;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}yaml
version: "3.8"
services:
nginx:
image: nginx:1.25-alpine
container_name: nginx-learn
restart: unless-stopped
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
- ./conf/default.conf:/etc/nginx/conf.d/default.conf:ro
- ./logs:/var/log/nginx
healthcheck:
test: ["CMD", "wget", "-q", "-O", "-", "http://localhost/"]
interval: 30s
timeout: 5s
retries: 3