Linux Nginx安装实战:从包管理器到源码编译与排错
发布时间:2026/9/11 12:49:42 锦皓数字建站

1. 安装前先确定三件事发行版、软件来源与 CPU 架构1.1 为什么“2026 年装 nginx”第一件事不是敲命令很多朋友找我排查 nginx 问题第一句话都是“我按教程装了但起不来”。细问之下十有八九是教程里的命令和当前系统对不上有人用 Ubuntu 的教程跑到 CentOS 上敲 apt有人照着编译教程装到一半发现缺依赖还有人装完发现nginx命令根本不在 PATH 里。到 2026 年Linux 安装 nginx 的手段比前几年更分化了。系统包管理器、官方仓库、源码编译、容器镜像四条路都有人在用而且各自维护的版本、目录结构、服务管理方式都有差别。这不是教程写得不好而是“安装”本身已经没有唯一标准答案。所以在动手之前我建议先花三分钟回答三个问题你手上是什么发行版Debian/Ubuntu 系、RHEL 系还是基于它们改造的国产 Linux 发行版你想用哪个来源装系统自带源、nginx 官方源还是源码编译机器是什么 CPU 架构x86_64、aarch64 还是其他这三件事没有确定下来后面每一步都可能白做。保姆级教程的真正意义不是把命令罗列出来让你复制而是让你知道为什么在这个环境下要敲这些命令。1.2 用三分钟把系统、镜像源和 CPU 架构搞清楚拿到一台新服务器我习惯先执行下面这几条命令把这些信息记录下来之后再查日志、找包、配仓库的时候会省很多事。cat /etc/os-release uname -m getconf LONG_BIT nproccat /etc/os-release会输出系统的 ID、版本号、版本代号。比如 Ubuntu 24.04 会看到IDubuntu、VERSION_CODENAMEnobleRocky Linux 9 会看到IDrocky、VERSION_ID9。后面配 nginx 官方源的时候这个版本代号要原样填进去填错了 apt 会直接提示找不到对应目录。uname -m输出 CPU 架构。绝大多数云服务器和虚拟机是x86_64但也有不少 ARM 架构的实例会显示aarch64。如果你要在 ARM 机器上编译安装有些依赖包的名字会不一样这一点后面讲编译安装时还会展开。关于镜像源我多说一句。国内服务器访问国外官方源有时候速度不稳定apt 和 dnf 都支持配置国内镜像源。Debian/Ubuntu 系统改/etc/apt/sources.list或者/etc/apt/sources.list.d/下的文件RHEL 系改 repo 文件里的baseurl。各大云厂商都维护了自己的镜像站速度基本都能跑满带宽。等我装完系统包之后要apt update或dnf makecache这一步如果特别慢大概率就是源的问题。另外很多国产 Linux 发行版看起来像 CentOS 或者 Ubuntu但包管理器、软件源目录结构会有调整。遇到这种情况不要硬套通用命令先cat /etc/os-release看清它基于哪个生态再选择对应的安装方式。2. 快速通路用系统包管理器把 nginx 跑起来2.1 Ubuntu/Debian 系apt 安装与官方源取舍如果你的系统是 Debian 或 Ubuntu 系的最省事的方案就是直接走 apt。命令只有两条sudo apt update sudo apt install -y nginx装完之后服务通常会被自动启动。你可以立刻用systemctl status nginx看一眼状态再用curl -I http://127.0.0.1验证页面能不能打开。这里有一个关键选择用系统自带的源还是用 nginx 官方源。系统自带源里的 nginx 版本通常偏保守可能比官方主线版落后一两个大版本。好处是和系统库配合得好安全补丁也会随系统更新一起推送。如果你只是要跑一个常规站点完全够用。但如果你需要用 nginx 官方源里更新的功能或者希望更及时地拿到新版本那就要手动添加官方仓库。添加官方仓库的完整步骤是这样的以 Ubuntu 24.04 为例sudo apt install -y curl gnupg2 ca-certificates lsb-release echo deb [signed-by/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu noble nginx | sudo tee /etc/apt/sources.list.d/nginx.list curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg sudo apt update sudo apt install -y nginx注意几个细节。第一noble是 Ubuntu 24.04 的版本代号不同版本要换掉比如 22.04 对应jammy。第二这种源只提供 nginx 官方编译的版本不会和系统自带的 nginx 包同时存在如果之前用 apt 装过建议先卸载干净再切换。第三在 “nginx.org/packages/ubuntu” 这一行中架构是自动识别的x86_64 和 aarch64 都会拿到对应包。2.2 RHEL 系yum/dnf 与 EPEL 的坑RHEL 系的系统包括 Rocky Linux、AlmaLinux、CentOS Stream 这些包管理命令现在是dnf。直接执行sudo dnf install -y nginx这里有个很大的坑如果系统没有启用 EPELExtra Packages for Enterprise Linux这个命令很可能会提示找不到 nginx 包。所以更稳妥的顺序是先装 EPELsudo dnf install -y epel-release sudo dnf makecache sudo dnf install -y nginxRHEL 系装完 nginx 之后服务默认不会启动要手动执行sudo systemctl enable --now nginx另外RHEL 系机器如果开着 SELinuxnginx 启动后访问页面可能遇到403 Forbidden。这不是 nginx 本身的问题而是 SELinux 阻止了进程访问某些目录。排查时先用getenforce看当前状态如果显示Enforcing可以先临时切换成Permissive试一下确认是 SELinux 的锅再决定要不要调整布尔值或者文件上下文。生产环境不要直接关掉 SELinux正确做法是找到具体违规项放行对应权限。2.3 装完先别高兴来一套快速体检不管是 apt 还是 dnf 安装装完后我都会按固定顺序做一套“快速体检”确保真的能用了而不是只看到nginx命令存在。# 1. 查看版本 nginx -v # 2. 检查配置是否有语法错误 sudo nginx -t # 3. 确认服务是启动状态并且已设置开机自启 systemctl status nginx --no-pager -l systemctl is-enabled nginx # 4. 本机请求一次看返回码 curl -I http://127.0.0.1curl -I如果返回HTTP/1.1 200 OK说明 nginx 已经在工作。如果看到的是一堆 HTML 文本那可能是 80 端口被其他服务占用后面我会专门讲端口冲突的排查。3. 需要自定义模块时的源码编译安装全流程3.1 哪些场景必须编译安装系统包管理器方便但有个限制能装的模块是固定的。你可能会遇到这些场景包管理器满足不了需要第三方模块比如nginx-rtmp-module、headers-more-nginx-module、lua-nginx-module需要自己选择编译参数比如启用--with-stream四层负载均衡、--with-http_v2_moduleHTTP/2需要把 nginx 安装到自定义目录方便多版本共存或者做二进制分发需要基于特定分支或者打了补丁的源码来做定制。在 2026 年HTTP/3 相关的编译需求比前几年明显多了。如果你要体验 HTTP/3nginx 官方有对应的 QUIC 分支需要通过源码编译的方式启用--with-http_v3_module。这种事情用 apt 是做不到的。3.2 依赖准备的通用套路源码编译最烦的不是make而是缺依赖。很多教程直接就给./configure make make install结果一执行第一步就报错。以 Ubuntu/Debian 系为例我通常先装这一组sudo apt install -y build-essential libpcre3-dev zlib1g-dev libssl-devbuild-essential提供 gcc、g 和 makelibpcre3-dev提供正则表达式库nginx 的 rewrite 模块依赖它zlib1g-dev提供压缩库gzip 模块依赖它libssl-dev提供 SSL/TLS 库--with-http_ssl_module依赖它。RHEL 系对应的安装命令是sudo dnf groupinstall Development Tools sudo dnf install -y pcre-devel zlib-devel openssl-devel最近两三年新发行版里 PCRE 逐渐被 PCRE2 替代Ubuntu 24.04 上就会同时存在libpcre3-dev和libpcre2-dev。nginx 较新版本在 configure 时会自动识别系统里的 PCRE 库。如果你发现 configure 报错说找不到 PCRE不用慌先把libpcre3-dev装上基本上都能解决。3.3 configure、编译与安装参数要一次性看清假设我要把 nginx 安装到/usr/local/nginx并且启用几个常用模块完整的编译安装命令如下cd /usr/local/src sudo wget https://nginx.org/download/nginx-1.26.2.tar.gz sudo tar -zxvf nginx-1.26.2.tar.gz cd nginx-1.26.2 ./configure \ --prefix/usr/local/nginx \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_stub_status_module \ --with-http_realip_module \ --with-http_gzip_static_module \ --with-stream \ --with-stream_ssl_module \ --with-pcre make -j$(nproc) sudo make install重点解释几个参数别看着多就慌。--prefix指定安装目录nginx 的配置、日志、二进制都会放在这个目录下面。--with-http_ssl_module启用 HTTPS 支持这是必选项不做 HTTPS 的现代网站几乎没有。--with-stream启用四层 TCP/UDP 代理做端口转发、数据库代理会用到。--with-http_v2_module启用 HTTP/2如果你的站点面向用户这个建议开。--with-http_stub_status_module会提供/nginx_status监控页看连接数很方便虽然现在是 Prometheus 生态更流行了但自己排查问题时这个页仍然很实用。make -j$(nproc)的-j参数是并行编译nproc会返回 CPU 核心数量。如果服务器配置低比如只有 2 核那make -j5反而可能更慢可以把-j去掉。编译完成后nginx 被安装到/usr/local/nginx。目录结构和包管理器安装的完全不同这在后面配置的时候要特别留意。4. 给编译版 nginx 补一个 systemd 服务4.1 systemd 之前自己管理进程的方式源码编译安装后的 nginx最大的痛点是它没有被接入 systemd。你直接敲systemctl start nginx多半会得到一行提示服务不存在。很多老教程会让你写一个/etc/init.d/nginx启动脚本或者直接在/etc/rc.local里加启动命令。这些办法在今天的新系统上已经不够体面了。Systemd 管理进程的好处是有统一的日志、有崩溃自动拉起能力、可以用systemctl status查看健康状态。所以我强烈建议编译装完后的第一件事就是补一个 systemd 服务文件。4.2 一行行写一份 nginx.service在我的服务器上这份服务文件长这样[Unit] Descriptionnginx - high performance web server Documentationhttps://nginx.org/en/docs/ Afternetwork-online.target Wantsnetwork-online.target [Service] Typeforking PIDFile/usr/local/nginx/logs/nginx.pid ExecStart/usr/local/nginx/sbin/nginx ExecReload/usr/local/nginx/sbin/nginx -s reload ExecStop/usr/local/nginx/sbin/nginx -s quit PrivateTmptrue [Install] WantedBymulti-user.target把它保存到/etc/systemd/system/nginx.service。几个字段值得讲明白Typeforking告诉 systemd这个服务启动后会 fork 出子进程父进程退出子进程在后台继续跑。nginx 默认就是这种工作方式所以必须声明否则 systemd 会误判服务启动失败。PIDFile指向 nginx 写入自己主进程 PID 的文件。systemd 靠它来跟踪 nginx 是否还在运行。路径要和你编译时指定的--prefix/usr/local/nginx对得上不然 systemd 会找不到 PID 文件状态就会显示异常。ExecReload和ExecStop用的是 nginx 的信号机制。nginx -s reload会平滑重载配置不中断现有连接nginx -s quit会优雅退出处理完当前请求后再关闭。不要用ExecStop/bin/kill那样是强杀。保存后执行sudo systemctl daemon-reload sudo systemctl enable --now nginx sudo systemctl status nginx --no-pager -l看到active (running)编译版的 nginx 才算真正融入了系统。之后你就能像管理其他服务一样管理它了。5. 验证安装是否真正成功端口、进程、访问页与防火墙5.1 四个核心检查有些时候服务状态显示是running但页面就是打不开。我不会只信systemctl status还要做以下四项检查每一项实际上都在回答不同层面的问题# 进程层面nginx 是否在跑主进程和 worker 进程是否都在 ps -ef | grep nginx # 端口层面80 端口是否被监听监听进程是不是 nginx ss -lntp | grep :80 # 本地请求层面本机访问能否返回正常头信息 curl -I http://127.0.0.1 # 日志层面有没有报错正在刷屏 sudo tail -f /var/log/nginx/error.logps通常能看到一个 master 进程和多个 worker 进程如果只有 master 没有 worker说明配置里的 worker 数量设置有问题通常是worker_processes写成了固定数字实际起不来。ss -lntp里看到的监听进程必须是nginx。如果看到的是httpd或者java那说明 80 端口被别的服务占了。这题下面第七部分会专门讲。5.2 防火墙和云安全组最容易漏掉的一步本地curl通了你高高兴兴地用浏览器访问服务器公网 IP结果一直转圈。这种情况九成是防火墙问题。检查分三层。第一层是本机防火墙。Debian/Ubuntu 常见的是 ufwsudo ufw status sudo ufw allow 80/tcp sudo ufw allow 443/tcpRHEL 系常见的是 firewalldsudo firewall-cmd --permanent --add-servicehttp sudo firewall-cmd --permanent --add-servicehttps sudo firewall-cmd --reload第二层是云平台的安全组规则。阿里云、腾讯云、AWS 这些平台都需要在控制台里把入方向的 80 和 443 端口放行。这里通过命令行是查不到的很多新手在这卡一整天。安全组规则改完之后通常几秒钟内生效可以用telnet或者本机以外的机器访问测试。第三层是 SELinux。前面提过RHEL 系要特别关注。如果 SELinux 在Enforcing状态nginx 对非标准目录的读写权限会被限制。遇到 403 或者连接异常就查一下/var/log/audit/audit.log里面会有denied的关键字。6. 安装后必做的配置摸底三个目录与一套默认配置6.1 apt 安装与编译安装的目录差异很多新手栽在“conf 文件到底在哪”这个问题上。其实这就是安装方式决定目录结构先摸清底后面才不会晕。如果是 apt 安装目录结构是这样的配置文件/etc/nginx/主配置/etc/nginx/nginx.conf可用的站点配置/etc/nginx/sites-available/启用的站点配置/etc/nginx/sites-enabled/通用配置片段/etc/nginx/conf.d/日志/var/log/nginx/二进制/usr/sbin/nginx如果是源码编译安装目录是安装根目录/usr/local/nginx/配置/usr/local/nginx/conf/nginx.conf日志/usr/local/nginx/logs/默认站点页面/usr/local/nginx/html/二进制/usr/local/nginx/sbin/nginx两个结构的最大区别在于apt 版把sites-available和sites-enabled分开了通过符号链接决定哪些站点生效编译版只有conf.d的概念。很多照着网上教程配置sites-available的朋友发现没效果就是因为自己安装的是编译版根本没有这个目录。所以拿到一台服务器我第一件事就是which nginx和nginx -V搞清楚它是谁装的、装在哪。我见过最混乱的情况是系统里同时存在 apt 版和编译版两个 nginx 抢 80 端口排错排到怀疑人生。避免这个问题的办法很简单安装前确定好一种方式不要混着来。6.2 从默认 nginx.conf 看懂 server、location 和 include打开/etc/nginx/nginx.conf或者编译版的/usr/local/nginx/conf/nginx.conf默认配置看起来挺长但拆开看就三层结构。第一层是全局块。比如worker_processes auto; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; include /etc/nginx/conf.d/*.conf; }worker_processes auto让 nginx 根据 CPU 核数自动决定 worker 进程数量。worker_connections表示每个 worker 进程能同时处理的最大连接数。这两个参数决定了 nginx 的并发能力上限。第二层是http块里的 server 块。每个server块代表一个虚拟主机。拿默认站点来看server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } }listen 80表示监听 80 端口server_name是这个虚拟主机的域名location /匹配所有以/开头的请求root指定文件根目录index指定默认首页文件名。第三层是location块的匹配规则。location /是前缀匹配location /是精确匹配location ~ \.php$是正则匹配。做反向代理、静态文件缓存、访问控制实际上都是在写 location 规则。重点说下include这个指令。nginx 主配置里一般都有include /etc/nginx/conf.d/*.conf;意思是加载这个目录下所有.conf文件。所以你完全可以把每个站点的配置单独放到conf.d/下面不用把所有内容堆到一个大文件里。改配置、查问题都方便很多。等到你配置的站点多了你会感激这一点。7. 高频安装报错排查手册按错误信息对号入座7.1 依赖缺失相关configure 阶段最扎心源码编译时看到一个红色的error很多人就慌了其实错误信息已经把答案告诉你了。我这里列三个最高频的。第一个是./configure: error: the HTTP rewrite module requires the PCRE library.这是系统缺 PCRE 开发库。Ubuntu/Debian 装libpcre3-devRHEL 系装pcre-devel。装完重新 configure 即可。第二个是./configure: error: the HTTP gzip module requires the zlib library.缺 zlib。Ubuntu/Debian 装zlib1g-devRHEL 系装zlib-devel。第三个是checking for C compiler ... not found ./configure: error: C compiler cc is not found这会出现在全新系统上连编译工具链都没有。装build-essential或者gcc、make这个问题就消失了。这些报错不是 nginx 的问题是基础环境的问题。所以编译之前先确认基础依赖而不是等报错了再去搜。7.2 端口占用bind() failed 的完整排查链路启动 nginx 时看到这样的日志[emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)说明 80 端口被别的进程占了。不要慌着杀进程按这个链路来排查# 第一步看谁占了 80 端口 sudo ss -lntp | grep :80 # 第二步如果查不到用 lsof 补一下 sudo lsof -i :80 # 第三步确认占用进程是什么 ps -ef | grep 进程PID常见的原因包括系统里已经装过另一个 nginxApache/httpd 在跑还有像我前面说的apt 版和编译版 nginx 并存两个都试图监听 80。确认占用者之后再根据情况处理。如果占用者是旧的 nginx可以选择用新的替换或者把新版的listen 80改成其他端口两个共存。如果占用者是其他业务进程那你要想清楚哪个服务该占 80。阻塞宁可只保留一个正确的服务也不要强行杀掉别的进程尤其是生产环境。7.3 配置语法错误unknown directive 与文件缺失系统包管理器装完默认配置一般没问题但你自己改过配置之后常见的报错有三类。第一类是nginx: [emerg] unknown directive sever in /etc/nginx/conf.d/test.conf:2这种九成是单词拼错了。sever_name写成server_nmae、listen后面少了端口号、分号漏写都会导致 unknown directive。排查方法很原始但很有效一行一行看有问题的文件检查关键字和结尾的分号。第二类是nginx: [emerg] open() /etc/nginx/sites-enabled/default failed (2: No such file or directory)这是符号链接指向的文件不存在典型场景是sites-enabled里有一个指向sites-available的软链接但sites-available里对应的文件被误删了。检查ls -l /etc/nginx/sites-enabled/把失效的链接删掉就行。第三类是逻辑问题不会在nginx -t时报错但访问时表现异常。比如 403 Forbidden。这种要分两头查一头是文件系统权限看 nginx 有没有权限访问配置里root指定的目录另一头是 SELinux用ausearch -m avc -ts recent查 denial 记录。不管改了什么配置遵循一个铁律sudo nginx -t通过后再systemctl reload nginx。一次都不要跳过。reload是平滑重载不会中断现有请求但如果你连语法检查都没过就直接 reload结果就是 nginx 拒绝加载新配置服务保持旧配置运行这种“改了等于没改”的情况特别迷惑人。8. 装完先别急着部署用反向代理和负载均衡实测 nginx8.1 反向代理一次就懂很多教程装完 nginx 就结束了但 nginx 真正常用的场景是反向代理。安装验证完我建议你花三分钟配一个最简单的反向代理这一步能让后续所有配置都有底气。现在假设你有一个后端服务跑在127.0.0.1:8080你想让用户访问 nginx 的 80 端口由 nginx 把请求转发给 8080 端口。先在conf.d/下新建一个配置文件比如reverse.confserver { listen 80; server_name demo.example.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; } }然后验证并重载sudo nginx -t sudo systemctl reload nginx为什么proxy_set_header这几行重要因为后面那个后端服务看到的请求来源会变成 nginx 的地址而不是用户真实 IP。X-Real-IP和X-Forwarded-For就是把真实客户端 IP 传给后端的方式。如果你后面要基于 IP 做限流或者审计日志这一步漏掉数据全是假的。你可以用 Python 起一个极简后端来测试python3 -m http.server 8080然后访问 nginx 的 80 端口浏览器应该能看到这个目录列表页面。看到这个页面就说明反向代理链路已经通了。8.2 upstream 与负载均衡的快速验证反向代理通了之后负载均衡几乎不需要额外学习成本。upstream就是定义一组后端服务器proxy_pass直接指向这组服务器的名字。配置长这样upstream backend { server 127.0.0.1:8081; server 127.0.0.1:8082; } server { listen 80; server_name demo.example.com; location / { proxy_pass http://backend; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }默认策略是轮询也就是每个请求依次打给 8081、8082再回到 8081。你可以开两个终端分别跑python3 -m http.server 8081 python3 -m http.server 8082然后连续刷新浏览器会发现内容在两个端口之间来回切换。如果 8081 停掉nginx 会自动把请求都转发给 8082这大概就是 nginx 负载均衡最直观的体现。upstream里还能加weight参数调整权重加max_fails和fail_timeout来控制失败重试策略。这些在安装阶段不用研究太深但知道有这个能力至少能让你在部署架构时心里有数。9. 收尾安装自检清单与我的习惯9.1 一张表完成安装验收教程看到这里你已经不只是安装 nginx而是把安装、配置、验证、排错串成了一条链路。最后我用一张表帮你做最终验收每条都过一遍这个 nginx 才算真正交工。检查项命令期望结果版本信息nginx -v显示 nginx 版本号模块信息nginx -V21显示 configure arguments能确认所需模块是否开启配置语法sudo nginx -t输出 syntax is ok 和 test is successful服务状态systemctl status nginx --no-pager -lactive (running)开机自启systemctl is-enabled nginxenabled端口监听ss -lntp | grep :80能看到 nginx 监听 80 端口本地访问curl -I http://127.0.0.1HTTP/1.1 200 OK防火墙sudo ufw status或sudo firewall-cmd --list-all80/443 端口已放行日志检查tail -n 20 /var/log/nginx/error.log无新的 error 或 critical 记录前端时间我给朋友排查问题他搞了一整天没搞定我远程过去发现就是systemctl is-enabled nginx返回了 disabled。服务能手动启动但机器一重启就消失这种属于“装了一半”不算装完。9.2 我长期维护 Linux nginx 的一些习惯最后分享几个我实际维护中的习惯这些踩坑多了之后慢慢形成的。第一每次安装或者升级之后我会把nginx -V输出的完整 configure 参数保存到一个文件里。这样做有实际好处以后要升级到新版本直接拿这份参数去配置新源码不会漏启用模块。很多人在升级时重新编译结果忘了带某个参数上线之后才发现功能不见了要回滚就非常被动。第二每次改配置前先备份改完一定nginx -t。这个习惯看起来简单但我真的遇到过因为多打了一个空格导致配置加载失败的生产事故。备份命令也不复杂cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date %Y%m%d%H%M%S)第三同一台机器上不要混用多种安装方式。这一点我在前面反复提醒过因为这是最容易踩的隐形坑。要么全用包管理器要么全用编译安装。容器环境就用镜像不要在主机的/usr/local里再塞一份 nginx否则迟早会出端口或者资源竞争问题。到 2026 年容器化部署已经非常普遍很多人可能会问还有必要掌握裸机安装 nginx 吗我的回答是有必要。容器里的 nginx 也是 nginx它的配置语法、目录结构、排错思路和裸机完全一样。而且你在生产环境里总会遇到一些不能用容器的情况比如特殊网络环境、性能压测、要直接管理主机资源的时候懂安装、懂配置、懂排错这一整套链路才能真正兜住底。这些东西往往就是日常看起来最普通的“装个 nginx”里积累出来的。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。