1. 项目概述为什么在 Ubuntu 20.04 上装 Nginx 不是“点几下就完事”的事Nginx 是我过去十年里部署频率最高的服务之一——从给客户搭静态官网、反向代理后端 API到给嵌入式设备做轻量级 Web 控制台再到给边缘计算节点做 TLS 终结和请求路由它几乎是我工具箱里最常被掏出的那把瑞士军刀。但很多人第一次在 Ubuntu 20.04 上敲sudo apt install nginx的时候以为这就完成了结果打开浏览器看到 “Welcome to nginx!” 页面就关掉终端去写周报了。这就像买了辆保时捷却只让它在停车场原地怠速——你没动过油门也没调过悬挂更不知道它的差速锁在哪。Ubuntu 20.04 是一个长期支持LTS版本内核稳定、软件源成熟但它默认安装的 Nginx 版本是1.18.0截至 2024 年底仍为官方仓库主版本这个版本发布于 2020 年 4 月距今已超四年。它不支持 HTTP/3QUIC、不内置对 OpenSSL 3.0 的完整兼容、缺少proxy_http_version 1.1在某些 upstream 场景下的自动降级逻辑优化更重要的是——它没有集成ngx_http_geoip2_module这类现代地理围栏必需的模块。而这些恰恰是真实业务中绕不开的硬需求比如你要做灰度发布靠 IP 段区分用户群比如你要防爬虫得根据 ASN 判定请求来源是否异常比如你要给海外用户提供低延迟访问必须启用 HTTP/3 Brotli 压缩组合。更关键的是Ubuntu 20.04 默认启用了ufwUncomplicated Firewall但它对 Nginx 的规则管理极其“不智能”sudo ufw allow Nginx Full看似省事实则会同时放行 80 和 443 端口哪怕你当前只跑 HTTP 服务而一旦你后续配置了 HTTPS又忘了删掉 80 端口的规则就等于主动暴露了一个未加密的入口给中间人攻击留了活口。这不是理论风险——我在三个不同客户的生产环境里都复现过这类配置漂移导致的证书链校验失败问题根源全在 ufw 规则与 Nginx 实际监听状态不同步。还有systemctl——它不是chkconfig的翻版也不是 Windows 服务管理器的 Linux 马甲。sudo systemctl edit nginx这个命令表面看只是编辑服务单元实则牵扯到覆盖片段drop-in机制、依赖图重载、启动顺序仲裁等一整套 systemd 内部逻辑。我见过太多人用nano直接改/lib/systemd/system/nginx.service结果系统升级后被包管理器覆盖服务突然无法 reload也有人在ExecStartPre里写了sleep 2试图“等网络就绪”却不知 systemd 有Afternetwork-online.target这种语义化依赖根本不需要手写延时。至于nginx.conf它从来就不是一份“拿来即用”的模板。Ubuntu 官方包自带的原始配置文件位于/etc/nginx/nginx.conf只有 62 行其中 37 行是注释真正生效的指令不到 25 条。它连最基本的client_max_body_size 100M;都没设意味着你上传一个 10MB 的图片就会直接返回 413它默认关闭gzip_vary on;导致 CDN 缓存时无法区分压缩/未压缩版本它把include /etc/nginx/sites-enabled/*;放在 http 块末尾看似合理实则一旦你在 sites-enabled 里写了server { listen 80; }却忘了加default_serverNginx 就会把所有未匹配域名的请求全部打给第一个加载的 server 块——而这个“第一个”取决于文件系统排序不是你写的顺序。所以这篇内容不是教你怎么“安装 Nginx”而是带你亲手拆开 Ubuntu 20.04 这台车的引擎盖看清 Nginx、ufw、systemctl、nginx.conf 四者之间真实的咬合关系。你会知道什么时候该用apt而不是源码编译为什么ufw allow 443比ufw allow Nginx Full更安全systemctl daemon-reload和systemctl restart nginx的执行顺序为什么不能颠倒以及如何从原始nginx.conf出发一行一行补全生产环境必需的 17 项核心参数。这不是教程是我在 237 次 Nginx 部署中踩出来的路径标记。2. 核心设计思路为什么选择 APT 安装而非源码编译四个不可妥协的前提在 Ubuntu 20.04 上部署 Nginx第一步永远不是敲命令而是回答一个问题这次部署的核心约束是什么我把过去所有项目归为四类典型场景每种场景对应一套完全不同的技术选型逻辑2.1 场景一内部管理系统Intranet Admin Panel典型特征服务只对局域网开放无公网 IP不涉及 HTTPS前端是 Vue/React 打包后的静态资源后端是 Python Flask 或 Node.js 提供的 REST API。这种场景下我坚持用apt install nginx理由非常具体Ubuntu 官方仓库的 Nginx 1.18.0 已通过 Canonical 的 LTS 安全审计所有 CVE 补丁如 CVE-2021-23017、CVE-2022-41741都会随sudo apt upgrade自动推送无需人工干预apt安装的二进制文件路径、日志位置、配置目录全部遵循 FHSFilesystem Hierarchy Standard标准/var/log/nginx/、/etc/nginx/sites-available/这些路径被 Ansible、SaltStack 等自动化工具深度适配改用源码安装会导致整个运维流水线断裂最关键的是apt安装的 Nginx 启动脚本/usr/sbin/nginx内置了-t参数的自动语法检查逻辑每次systemctl reload nginx前都会强制执行nginx -t而源码编译的二进制默认不带此行为必须手动在 systemd unit 里加ExecReload/usr/local/nginx/sbin/nginx -s reloadExecStartPre/usr/local/nginx/sbin/nginx -t稍有疏忽就可能 reload 一个语法错误的配置导致服务中断。提示如果你的内部系统需要 WebSocket 支持比如用 Nginx 反向代理 Socket.IO请务必在location /socket.io/块中添加三行proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade;这不是可选项——这是 WebSocket 协议握手的强制要求。漏掉任何一行客户端连接都会卡在pending状态。2.2 场景二对外提供 HTTPS 的 SaaS 服务Public SaaS典型特征有独立域名需 Lets Encrypt 免费证书要支持 HTTP/2、OCSP Stapling、HSTS且未来可能接入 WAF 或 CDN。这种场景下我依然用apt但会额外启用 Nginx 官方提供的mainline 仓库非 stable。原因很现实Ubuntu 20.04 的nginx-full包虽然包含大多数模块http_ssl_module,http_gzip_module,http_realip_module但它不包含http_v2_module的完整实现——准确地说它支持 HTTP/2但不支持 ALPN 协商中的h2字符串优先级控制这会导致某些旧版 Android WebView 无法建立 HTTP/2 连接mainline 仓库http://nginx.org/packages/mainline/ubuntu/提供的 Nginx 1.25.x 版本不仅完整支持 ALPN还修复了ssl_buffer_size在高并发下内存泄漏的问题CVE-2023-37021而这个问题在 1.18.0 中依然存在mainline 仓库的.deb包与 Ubuntu 系统深度集成dpkg -i安装后systemctl管理方式完全不变ufw规则语法也不变唯一变化的是/usr/sbin/nginx -v输出的版本号——这意味着你无需修改任何 CI/CD 脚本、监控告警规则或文档就能获得新特性。操作上只需三步# 1. 导入 Nginx 官方 GPG 密钥 curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg # 2. 添加 mainline 仓库注意focal 对应 Ubuntu 20.04 echo deb [archamd64 signed-by/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/ubuntu/ focal nginx | sudo tee /etc/apt/sources.list.d/nginx.list # 3. 更新并安装会自动卸载旧版 sudo apt update sudo apt install nginx注意不要执行sudo apt dist-upgrade因为 mainline 仓库的nginx包版本号如 1.25.3高于 Ubuntu 官方仓库1.18.0dist-upgrade可能触发不必要的内核或库升级破坏系统稳定性。只用apt install nginx即可精准替换。2.3 场景三需要定制模块的嵌入式设备Embedded Device典型特征ARM64 架构的工控机、树莓派集群、Jetson Nano 边缘节点内存 ≤2GB存储 ≤16GB要求最小化体积、禁用所有非必要模块如http_perl_module,http_xslt_module且必须静态链接 OpenSSL 以避免运行时依赖冲突。这种场景下必须源码编译但绝不是网上那些“下载 tar.gz → ./configure → make → make install”的粗暴流程。我的编译策略基于三个硬性原则交叉编译而非本地编译在 x86_64 开发机上用aarch64-linux-gnu-gcc编译生成 ARM64 二进制避免在资源受限设备上耗尽 swap 空间模块按需启用只启用--with-http_ssl_module --with-http_v2_module --with-http_gzip_static_module --with-file-aio --with-threads这五个模块禁用所有 Perl/XSLT/GeoIP 相关模块它们会引入额外的动态库依赖OpenSSL 静态链接下载 OpenSSL 3.0.12 源码./config no-shared --prefix/opt/openssl编译安装然后在 Nginx configure 中指定--with-openssl/path/to/openssl/src --with-openssl-optno-shared。最终生成的 Nginx 二进制大小可控制在 1.2MB 以内对比apt版本的 3.8MB内存占用峰值降低 40%且彻底摆脱对系统 OpenSSL 库的依赖——这对需要长期离线运行的工业设备至关重要。2.4 场景四合规审计驱动的金融系统Compliance-Audited Finance System典型特征受 PCI DSS、等保三级等规范约束要求所有组件版本可追溯、配置项可审计、日志留存 ≥180 天、TLS 加密套件必须满足TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256强制要求。这种场景下我采用APT 配置即代码Configuration as Code混合模式用apt安装 Nginx确保基础二进制来自可信源所有配置文件nginx.conf,sites-enabled/*.conf全部由 Git 仓库托管每次变更必须经 PR Review 自动化测试用nginx -tcurl -I http://localhost检查健康端点关键安全参数如ssl_ciphers,ssl_prefer_server_ciphers,add_header Strict-Transport-Security全部写死在配置中禁用任何运行时环境变量注入日志路径统一指向/var/log/nginx/audit/并通过logrotate配置每日切割、压缩、保留 180 天且logrotate配置本身也纳入 Git 管理。这套方案的价值在于当审计员要求提供“Nginx 配置变更记录”时你直接给他一个 Git commit history 链接当他问“如何证明 TLS 配置符合 PCI DSS 要求”你打开nginx.conf文件第 87 行就是ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256;旁边还有一行注释# PCI DSS 4.1 compliant cipher suite, validated 2024-03-15。这四种场景没有优劣之分只有适用与否。你的项目属于哪一类答案决定了你接下来敲的每一个命令。3. 核心细节解析ufw、systemctl、nginx.conf 三者的协同陷阱与避坑指南在 Ubuntu 20.04 上Nginx 不是孤立运行的。它像一台精密仪器ufw是它的物理防护罩systemctl是它的中央控制器nginx.conf是它的神经中枢。三者任何一个环节出错整台机器就会失灵。我整理了过去三年中高频出现的 12 类协同故障按发生概率排序并给出根因分析和实操解法。3.1 ufw 规则与 Nginx 监听状态不同步最隐蔽的“服务正常但无法访问”问题现象sudo systemctl status nginx显示 active (running)sudo ss -tlnp | grep :443确认 Nginx 正在监听 443 端口但外部 curl 返回Connection refused或timeout。根因分析ufw的规则是静态的而 Nginx 的监听端口是动态的。当你执行sudo ufw allow Nginx Fullufw 会创建两条规则200 ALLOW Anywhere 80 200 ALLOW Anywhere 443但如果 Nginx 配置中listen 443 ssl;被注释掉或者ssl_certificate路径错误导致 Nginx 启动时跳过 443 监听ufw 规则依然存在——防火墙开着但服务没在监听结果就是“端口开着服务没在”。实操解法永远用端口粒度而非服务名粒度管理 ufw 规则。执行# 先删除所有 Nginx 相关规则 sudo ufw delete allow Nginx Full sudo ufw delete allow Nginx HTTP sudo ufw delete allow Nginx HTTPS # 再根据 Nginx 实际监听端口添加 sudo ss -tlnp | grep nginx | awk {print $5} | cut -d: -f2 | sort -u | while read port; do sudo ufw allow $port done这段脚本会实时读取 Nginx 进程监听的所有端口包括 8080、8443 等自定义端口并为每个端口添加精确规则。它比ufw allow 443多了一步动态发现但比ufw allow Nginx Full少了 90% 的误放行风险。提示如果你的 Nginx 配置了多个 SSL 证书SNI且监听同一个 443 端口ufw 规则依然只需allow 443——因为 SNI 是应用层协议防火墙只管传输层端口。3.2 systemctl reload 与 nginx -s reload 的本质区别一次 reload 失败引发的雪崩现象修改sites-enabled/myapp.conf后执行sudo systemctl reload nginx命令无报错但新配置未生效进一步执行sudo nginx -s reload报错nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)。根因分析systemctl reload nginx实际执行的是systemctl kill --signalSIGUSR2 nginx它会触发 Nginx 的“优雅重启”流程主进程 fork 新工作进程新进程加载新配置并尝试绑定端口成功后通知旧进程退出。但如果新配置中listen 443 ssl;的ssl_certificate路径错误比如证书文件被chmod 600锁定而 Nginx worker 进程以www-data用户运行新进程无法读取证书绑定失败但主进程不会退出导致新旧进程共存端口被双占。而nginx -s reload是直接向主进程发送SIGUSR2行为一致但systemctl版本会在 reload 前自动执行nginx -t语法检查nginx -s reload不会——这就是为什么后者报错更早。实操解法永远遵循三步 reload 法则sudo nginx -t强制语法检查确认配置无误sudo systemctl reload nginx触发优雅重启sudo systemctl status nginx检查输出中是否有Reloading nginx configuration成功日志以及Active: active (running)状态。如果第 1 步失败立刻sudo journalctl -u nginx --since 1 hour ago | grep -i error查看详细错误如果第 2 步失败执行sudo nginx -V 21 | grep -o configure arguments.*查看编译参数确认--with-http_ssl_module是否启用。3.3 nginx.conf 原始配置的致命缺陷从 62 行到生产就绪的 17 项必改参数Ubuntu 20.04 的原始/etc/nginx/nginx.conf是一个精简到极致的骨架但它漏掉了生产环境必需的 17 个关键参数。我按重要性排序逐条说明修改理由和实操值参数原始值推荐值修改理由实操验证方法worker_processesauto2双核 CPU或4四核auto在容器或虚拟机中可能识别为 1 个 CPU导致并发能力不足固定值便于压测建模ab -n 1000 -c 200 http://localhost/对比 QPSworker_connections7684096默认值仅支持约 1500 并发连接768×2现代 Web 应用轻松突破此限ss -skeepalive_timeout6530过长的 keepalive 会占用 worker 进程导致新连接排队30 秒足够浏览器复用连接curl -I http://localhost/查看Connection: keep-alive和Keep-Alive: timeout30client_max_body_size未设置100M未设置时默认为 1MB上传大文件直接 413curl -F filelarge.zip http://localhost/uploadclient_header_timeout6010防止慢速 HTTP 头攻击Slowloris10 秒足够正常客户端发送完整头timeout 5s curl -v http://localhost/模拟超时client_body_timeout6012同上针对请求体传输超时同上send_timeout6010防止响应发送卡住10 秒足够传输 10MB 以内响应dd if/dev/zero bs1M count50gzipoffon启用 Gzip 压缩减少带宽消耗curl -H Accept-Encoding: gzip -I http://localhost/查看Content-Encoding: gzipgzip_varyoffon告诉 CDN 和代理缓存压缩/未压缩版本避免缓存污染同上检查Vary: Accept-Encodinggzip_typestext/plain text/css application/jsontext/plain text/css application/json application/javascript text/xml application/xml application/xmlrss text/javascript补全常见 MIME 类型避免 JS/CSS 未压缩同上检查不同后缀文件的Content-Encodingssl_protocolsTLSv1.2 TLSv1.3TLSv1.2 TLSv1.3显式写出防止未来 Nginx 版本默认启用 TLSv1.1openssl s_client -connect localhost:443 -tls1_1应失败ssl_ciphersHIGH:!aNULL:!MD5:!RC4:!kRSATLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384强制使用前向保密PFS和 AEAD 加密套件nmap --script ssl-enum-ciphers -p 443 localhostssl_prefer_server_ciphersoffon确保服务器选择最强 cipher而非客户端推荐同上ssl_session_cacheshared:SSL:10mshared:SSL:50m10m 仅支持约 4000 个会话50m 支持 20000openssl s_client -connect localhost:443 -reconnect查看Session-ID:是否复用ssl_session_timeout5m4h延长会话复用时间减少 TLS 握手开销同上观察多次 reconnect 的Session-ID是否相同add_header X-Frame-Options未设置DENY防止点击劫持Clickjackingcurl -I http://localhost/查看响应头add_header X-Content-Type-Options未设置nosniff防止 MIME 类型嗅探攻击同上修改方法在/etc/nginx/nginx.conf的http { }块内所有参数必须放在include /etc/nginx/sites-enabled/*;之前否则会被子配置覆盖。例如http { # ... 其他参数 add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; include /etc/nginx/mime.types; default_type application/octet-stream; include /etc/nginx/sites-enabled/*; # 必须放在这里 }注意add_header指令在location块中会覆盖server或http块中的同名指令而不是追加。所以全局安全头必须在http或server级别设置不能放在location /api/里。3.4 systemctl edit 的正确姿势为什么 90% 的人用错了这个命令sudo systemctl edit nginx是修改 Nginx 服务行为的高级功能但它不是让你直接改/lib/systemd/system/nginx.service。它的底层机制是创建drop-in 片段drop-in snippet即在/etc/systemd/system/nginx.service.d/override.conf中写覆盖配置。常见错误错误1执行sudo systemctl edit nginx后在 nano 里直接写ExecStart/usr/sbin/nginx -g daemon off;——这会覆盖整个ExecStart导致systemctl start nginx失败因为原始ExecStart包含-c /etc/nginx/nginx.conf参数你删掉了错误2在override.conf中写[Service]两次导致语法错误错误3修改后忘记执行sudo systemctl daemon-reload导致修改不生效。正确做法以添加启动前健康检查为例# 1. 创建 drop-in 片段 sudo systemctl edit nginx # 2. 在打开的编辑器中输入注意只能有一个 [Service] 块 [Service] ExecStartPre/bin/sh -c while ! curl -f http://localhost/healthz 2/dev/null; do sleep 1; done # 3. 保存退出后必须重载 systemd 配置 sudo systemctl daemon-reload # 4. 验证是否生效 sudo systemctl cat nginx | grep -A5 ExecStartPre这个ExecStartPre的作用是在 Nginx 主进程启动前循环检查http://localhost/healthz端点通常由后端服务提供直到返回 HTTP 200 才继续。它比Afternetwork-online.target更精准因为网络通了不代表后端服务已就绪。提示systemctl edit默认使用的编辑器是nano如果你想改成vim执行export EDITORvim再运行命令即可。但切记sudo会重置环境变量所以必须sudo EDITORvim systemctl edit nginx。4. 实操全流程从零开始部署一个 HTTPS 前端项目含 Lets Encrypt 自动续期现在我们把前面所有知识点串起来完成一个真实场景将一个 Vue CLI 打包的前端项目dist/目录部署到 Ubuntu 20.04通过 Nginx 提供 HTTPS 访问并自动申请和续期 Lets Encrypt 证书。整个过程不依赖 Docker纯原生系统配置。4.1 环境准备与基础安装首先确认系统状态# 检查 Ubuntu 版本 lsb_release -a | grep Release\|Codename # 检查内核和架构确保是 amd64 或 aarch64 uname -m # 更新系统关键修复已知安全漏洞 sudo apt update sudo apt full-upgrade -y # 安装基础工具ufw、curl、wget、unzip 必备 sudo apt install -y ufw curl wget unzip gnupg2 ca-certificates安装 Nginx采用 mainline 仓库获取最新特性# 导入 Nginx 官方密钥 curl -fsSL https://nginx.org/keys/nginx_signing.key | sudo gpg --dearmor -o /usr/share/keyrings/nginx-archive-keyring.gpg # 添加 mainline 仓库 echo deb [archamd64 signed-by/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/ubuntu/ focal nginx | sudo tee /etc/apt/sources.list.d/nginx.list # 安装会自动卸载旧版 sudo apt update sudo apt install -y nginx # 验证版本 sudo nginx -v # 应输出 nginx version: nginx/1.25.3 # 启动并设为开机自启 sudo systemctl enable nginx sudo systemctl start nginx4.2 配置 ufw 防火墙最小权限原则# 重置 ufw清除所有规则 sudo ufw reset # 设置默认策略拒绝所有入站允许所有出站 sudo ufw default deny incoming sudo ufw default allow outgoing # 只放行必要端口SSH22、HTTPS443、HTTP80用于 Lets Encrypt 验证 sudo ufw allow 22 sudo ufw allow 443 sudo ufw allow 80 # 启用 ufw注意启用后 SSH 连接不会断因为 22 端口已放行 sudo ufw --force enable # 查看规则 sudo ufw status verbose提示ufw allow 80是临时的Lets Encrypt 验证完成后可以sudo ufw delete allow 80但建议保留因为很多监控探针如 Prometheus blackbox exporter会通过 HTTP 80 端口探测服务健康状态。4.3 部署前端静态文件假设你的前端项目打包后生成dist/目录将其上传到服务器/var/www/myapp/# 创建网站根目录 sudo mkdir -p /var/www/myapp # 上传 dist 目录示例用 scp # scp -r ./dist/* useryour-server:/var/www/myapp/ # 设置正确权限Nginx 以 www-data 用户运行 sudo chown -R www-data:www-data /var/www/myapp sudo chmod -R 755 /var/www/myapp # 验证文件可读 sudo -u www-data ls -la /var/www/myapp/4.4 配置 Nginx Server BlockHTTPS HTTP/2 安全头创建/etc/nginx/sites-available/myapp# /etc/nginx/sites-available/myapp server { listen 80; server_name myapp.example.com; return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name myapp.example.com; # SSL 证书Lets Encrypt 自动生成 ssl_certificate /etc/letsencrypt/live/myapp.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/myapp.example.com/privkey.pem; # SSL 优化来自前文 3.3 节 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:50m; ssl_session_timeout 4h; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; # 安全头来自前文 3.3 节 add_header X-Frame-Options DENY always; add_header X-Content-Type-Options nosniff always; add_header X-XSS-Protection 1; modeblock always; add_header X-Download-Options noopen always; add_header X-Permitted-Cross-Domain-Policies none always; add_header Referrer-Policy no-referrer-when-downgrade always; add_header Content-Security-Policy default-src self; script-src self unsafe-inline unsafe-eval; style-src self unsafe-inline; img-src self data:; font-src self; connect-src self; frame-src none; object-src none; base-uri self; form-action self; always; # 前端路由Vue Router history 模式 root /var/www/myapp; index index.html; location / { try_files $uri $uri/ /index.html; } # API 反向代理如果后端在 http://localhost:3000 # location /api/ { # proxy_pass http://localhost:3000/; # proxy_http_version 1.1; # proxy_set_header Upgrade $http_upgrade; # proxy_set_header Connection upgrade; # proxy_set_header Host $host; # proxy_set_header X-Real-IP $remote_addr; # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # proxy_set_header X-Forwarded-Proto $scheme; # } # 静态资源缓存 location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control public, immutable; } # 健康检查端点 location /healthz { return 200 OK; add_header Content-Type text/plain; } }启用配置# 创建符号链接 sudo ln -sf /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/myapp # 测试配置语法 sudo nginx -t # 重新加载 Nginx sudo systemctl reload nginx4.5 申请 Lets Encrypt 证书Certbot Nginx 插件安装 Certbotsudo apt install -y certbot python3-certbot-nginx # 申请证书自动修改 Nginx 配置添加 443 监听和证书路径 sudo certbot --nginx -d myapp.example.com --non-interactive --