Linux服务器部署Nginx与Let‘s Encrypt HTTPS网站全流程指南

发布时间:2026/8/7 1:56:27
Linux服务器部署Nginx与Let‘s Encrypt HTTPS网站全流程指南
1. 项目概述从零到一在Linux上构建安全的Web服务最近几年无论是个人开发者想展示自己的作品集还是小团队需要部署一个内部管理系统在Linux服务器上搭建一个网站都成了刚需。但很多朋友一上来就被各种概念搞晕了Apache还是NginxHTTP怎么变成HTTPS证书去哪弄配置文件的参数看得人眼花缭乱。我自己从最早用LAMP套件到后来折腾Docker容器化部署踩过的坑不计其数。今天我就以一个过来人的身份带你手把手、无死角地在Linux上搭建一个同时支持HTTP和HTTPS访问的网站。我们不止要“搭起来”更要理解每一步背后的“为什么”让你以后遇到502 Bad Gateway、SSL证书过期这类问题时能从容应对而不是只会重启大法。这个教程的目标是让你获得一个完全受控的、可通过http://你的服务器IP和https://你的服务器IP或域名访问的网站。我们会选用最经典、最稳定的组合Nginx作为Web服务器因为它性能高、配置清晰配合Let‘s Encrypt提供的免费SSL证书来实现HTTPS。整个过程会涵盖从系统准备、软件安装、配置详解到安全加固的全链路。无论你是刚接触Linux的新手还是想系统梳理一遍Web服务部署的老兵都能从中找到实用的干货。2. 核心组件选型与原理浅析在动手之前我们得先搞清楚要用的几个核心组件是干什么的以及为什么选它们。这就像盖房子前得了解砖瓦水泥的特性而不是直接照葫芦画瓢。2.1 为什么是Nginx而不是Apache在Linux世界搭建网站Web服务器主要有两大巨头Apache和Nginx。早期LAMPLinux, Apache, MySQL, PHP栈名震江湖Apache是绝对主力。但如今Nginx发音为“engine-x”的市场份额和口碑后来居上尤其在并发处理和高性能场景下。我选择Nginx作为本次搭建的核心主要基于以下几点实战考量高并发与低内存占用Apache采用多进程或多线程模型每个连接需要一个进程/线程处理当并发连接数上万时内存和CPU开销会急剧上升。Nginx则采用了事件驱动的异步非阻塞架构一个工作进程就能处理成千上万个连接非常适合现代高并发的Web应用。我实测过在同一台1核2G的云服务器上Nginx静态资源服务的QPS每秒查询率能比Apache高出30%以上内存占用却只有一半。配置简洁直观Apache的配置文件httpd.conf和.htaccess文件虽然功能强大但语法相对繁杂模块加载机制也稍显笨重。Nginx的配置文件结构清晰采用类似编程语言的块block结构比如用server块定义一个网站用location块处理特定URL逻辑一目了然。对于新手来说学习曲线更平缓。反向代理与负载均衡的“原生”优势Nginx从设计之初就强化了作为反向代理和负载均衡器的能力。即使你现在只是搭一个单点网站未来业务增长需要在前端Nginx后面挂接多个应用服务器比如Tomcat、Node.js、Python Django时Nginx可以无缝升级为流量入口和调度中心而Apache在这方面的配置相对复杂。当然Apache在动态内容处理如通过mod_php模块直接解析PHP和.htaccess目录级配置灵活性上仍有优势。但对于绝大多数从零开始的网站特别是静态站点、博客或前后端分离的应用前端HTML/JS/CSS后端通过API通信Nginx是更优、更面向未来的选择。2.2 HTTP与HTTPS不止是“S”的区别很多搜索热词都提到了“http和https的区别”这确实是安全上网的基石。简单说HTTP超文本传输协议是明文传输的数据在客户端和服务器之间“裸奔”容易被窃听、篡改。HTTPS就是在HTTP之下加入了一层SSL/TLS加密协议相当于给数据通道加了一个保险箱。这个“S”Secure带来的核心价值是加密防止通信内容被第三方窃听。认证通过SSL证书确保你访问的“www.yourdomain.com”真的是你的服务器而不是钓鱼网站。完整性防止数据在传输过程中被恶意篡改。如今主流浏览器对纯HTTP网站都会标记为“不安全”搜索引擎如Google也会对HTTPS网站给予排名权重。因此为网站启用HTTPS不再是可选项而是必选项。2.3 SSL证书Let‘s Encrypt为何是首选实现HTTPS的关键是SSL证书。证书由证书颁发机构CA签发用来证明服务器身份和提供加密公钥。商业证书价格不菲而Let‘s Encrypt的出现彻底改变了游戏规则。它提供完全免费、自动化的域名验证型DV证书。虽然有效期只有90天商业证书通常1-2年但它配套的自动化工具Certbot可以让你轻松实现证书的自动申请和续期完全解决了手动管理的麻烦。选择Let‘s Encrypt Certbot这个组合意味着你可以以零成本为你的网站部署业界标准的安全加密这对于个人项目、测试环境和小型企业网站来说是绝佳选择。我们后续的实操也将围绕这个组合展开。3. 环境准备与Nginx安装理论清晰了我们开始动手。请准备一台安装有Linux系统的服务器Ubuntu 20.04/22.04 LTS或CentOS 7/8 Stream是常见且推荐的选择并确保你拥有root权限或可以通过sudo执行特权命令。3.1 系统更新与基础检查首先无论用什么系统第一步永远是更新软件包列表确保我们从一个最新的基础环境开始。对于Ubuntu/Debian系统sudo apt update sudo apt upgrade -y对于CentOS/RHEL系统sudo yum update -y # 如果是CentOS 8 Stream可能需要使用dnf # sudo dnf update -y更新完成后检查一下服务器的网络和防火墙状态。我们需要确保80HTTP和443HTTPS端口是开放的。检查防火墙如果使用了ufw或firewalld# Ubuntu 查看ufw状态 sudo ufw status # 如果状态是inactive则防火墙未启用。如果active需要放行端口 sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw reload # CentOS 查看firewalld状态 sudo firewall-cmd --state # 如果运行中放行端口 sudo firewall-cmd --permanent --add-servicehttp sudo firewall-cmd --permanent --add-servicehttps sudo firewall-cmd --reload检查云服务商安全组如果你使用的是阿里云、腾讯云、AWS等云服务器务必在控制台的安全组规则中添加入方向规则允许来自0.0.0.0/0或你的IP段对80和443端口的TCP访问。这是很多新手搭建后外网无法访问的最常见原因3.2 安装Nginx不同Linux发行版的安装命令不同但过程都很简单。在Ubuntu/Debian上安装sudo apt install nginx -y安装完成后Nginx会自动启动。你可以通过以下命令验证sudo systemctl status nginx如果看到active (running)的字样说明服务已成功运行。此时在浏览器中输入你的服务器公网IP地址例如http://123.123.123.123你应该能看到Nginx的默认欢迎页面。如果看不到请返回上一步检查防火墙和安全组设置。在CentOS/RHEL上安装默认的CentOS仓库可能不包含最新版Nginx。建议先添加EPELExtra Packages for Enterprise Linux仓库或者直接添加Nginx官方仓库以获得最新稳定版。# 安装EPEL仓库 sudo yum install epel-release -y # 安装Nginx sudo yum install nginx -y # 启动并设置开机自启 sudo systemctl start nginx sudo systemctl enable nginx sudo systemctl status nginx同样用浏览器访问服务器IP检查默认页面。注意有些VPS提供商如部分海外厂商的镜像可能预装了Apache。如果安装Nginx时发生端口冲突80端口已被占用你需要先停止并禁用Apachesudo systemctl stop apache2(Ubuntu) 或sudo systemctl stop httpd(CentOS)然后sudo systemctl disable apache2/httpd。或者你也可以修改Nginx的默认监听端口但这会增加不必要的复杂度建议直接使用Nginx。4. 配置你的第一个HTTP网站看到默认页面只是第一步那属于Nginx自己。现在我们要配置一个属于我们自己的网站。4.1 准备网站文件首先为你的网站创建一个根目录。通常网站文件放在/var/www/目录下。我们创建一个以你域名或项目名命名的目录例如my_site。sudo mkdir -p /var/www/my_site-p参数确保如果父目录不存在则一并创建。接下来创建一个最简单的HTML文件作为测试页面。使用vim或nano编辑器sudo vim /var/www/my_site/index.html在文件中输入以下内容!DOCTYPE html html head title我的Linux网站/title /head body h1恭喜/h1 p你的基于Nginx的网站已经成功运行在HTTP协议下。/p p服务器时间span iddatetime/span/p script var dt new Date(); document.getElementById(datetime).innerHTML dt.toLocaleString(); /script /body /html保存并退出。然后将这个目录的所有权更改为Nginx运行的用户通常是www-data在Ubuntunginx在CentOS以便Nginx有权限读取文件。Ubuntu:sudo chown -R www-data:www-data /var/www/my_site sudo chmod -R 755 /var/www/my_siteCentOS:sudo chown -R nginx:nginx /var/www/my_site sudo chmod -R 755 /var/www/my_site4.2 创建Nginx服务器块Server Block配置Nginx使用“服务器块”类似Apache的虚拟主机来托管多个网站。默认的配置文件在/etc/nginx/sites-available/default。最佳实践是为每个网站创建一个独立的配置文件。创建配置文件sudo vim /etc/nginx/sites-available/my_site写入配置内容将以下配置粘贴进去。这里我们假设你的服务器IP是123.123.123.123如果你有域名请将server_name后的IP替换为你的域名例如www.yourdomain.com。server { # 监听80端口即HTTP listen 80; # 监听IPv6的80端口如果服务器支持IPv6 listen [::]:80; # 设置网站根目录 root /var/www/my_site; # 设置默认索引文件 index index.html index.htm; # 服务器名称可以是IP或域名 server_name 123.123.123.123; location / { # 尝试以URI访问文件如果找不到则尝试目录最后返回404 try_files $uri $uri/ 404; } # 可选的记录访问日志和错误日志 access_log /var/log/nginx/my_site_access.log; error_log /var/log/nginx/my_site_error.log; }这个配置块定义了一个监听80端口的虚拟主机将请求指向我们刚才创建的/var/www/my_site目录。启用配置在/etc/nginx/sites-available/下的配置文件不会自动生效需要创建一个符号链接到/etc/nginx/sites-enabled/目录。sudo ln -s /etc/nginx/sites-available/my_site /etc/nginx/sites-enabled/测试配置并重载Nginx在重启Nginx前务必测试配置文件语法是否正确这是一个非常重要的好习惯可以避免因配置错误导致服务崩溃。sudo nginx -t如果输出nginx: configuration file /etc/nginx/nginx.conf test is successful说明语法正确。 然后重新加载Nginx配置平滑重载不会中断现有连接sudo systemctl reload nginx # 或者使用 sudo nginx -s reload现在再次在浏览器中访问你的服务器IPhttp://123.123.123.123你应该能看到刚才创建的个性化HTML页面而不是Nginx的默认页面了。恭喜你的HTTP网站已经上线5. 为网站部署HTTPSSSL/TLS加密HTTP网站建好了但还不够安全。接下来我们使用Let‘s Encrypt和Certbot来免费获取SSL证书并配置HTTPS。5.1 安装Certbot工具Certbot是Let‘s Encrypt官方推荐的自动化证书管理工具。安装方法因系统而异。在Ubuntu 20.04上sudo apt install certbot python3-certbot-nginx -ypython3-certbot-nginx是Certbot的Nginx插件它能自动读取Nginx配置并修改极大简化流程。在CentOS 7/8上需要先启用EPEL仓库然后安装。# CentOS 7 sudo yum install certbot python2-certbot-nginx -y # CentOS 8 sudo dnf install certbot python3-certbot-nginx -y5.2 申请并自动配置SSL证书这是最关键的一步。运行以下命令Certbot会自动完成几件事连接Let‘s Encrypt服务器。验证你对域名的所有权通过在你网站的.well-known目录下创建临时文件Let‘s Encrypt服务器会尝试访问该文件。验证通过后下载证书和密钥文件到/etc/letsencrypt/live/你的域名/目录下。自动修改你的Nginx配置文件添加HTTPS监听和证书路径。执行命令sudo certbot --nginx -d 你的域名或IP例如如果你的域名是www.example.com则命令为sudo certbot --nginx -d www.example.com如果你暂时没有域名只有IP地址Let‘s Encrypt不支持为纯IP地址签发证书。你必须拥有一个域名。对于测试和学习你可以使用本地Hosts文件将任意域名指向你的服务器IP但Let‘s Encrypt的验证需要该域名在公网可解析。因此拥有一个域名是启用HTTPS的前提。执行命令后Certbot会交互式地询问你一些信息邮箱地址用于接收证书到期提醒和紧急通知。务必填写有效邮箱。服务条款输入A表示同意。是否分享邮箱可选根据个人意愿选择。是否将HTTP流量重定向到HTTPS强烈建议选择2重定向。这样当用户访问http://你的网站时会自动跳转到https://确保始终使用安全连接。整个过程如果顺利你会看到“Congratulations!”的提示。Certbot已经自动帮你修改了Nginx配置。5.3 理解Certbot修改后的配置让我们看看Certbot对/etc/nginx/sites-available/my_site文件做了什么。现在它应该看起来像这样注释已简化server { listen 80; listen [::]:80; server_name www.example.com; # 你的域名 # 这是Certbot添加的重定向规则将HTTP重定向到HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; # 监听443端口启用SSL和HTTP/2 listen [::]:443 ssl http2; server_name www.example.com; root /var/www/my_site; index index.html index.htm; # SSL证书和密钥的路径由Certbot管理 ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem; # 引入推荐的SSL安全配置 include /etc/letsencrypt/options-ssl-nginx.conf; # Certbot用于证书自动续期的验证路径 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { try_files $uri $uri/ 404; } access_log /var/log/nginx/my_site_access.log; error_log /var/log/nginx/my_site_error.log; }可以看到Certbot创建了两个server块第一个块监听80端口只有一个return 301指令将所有HTTP请求永久重定向到HTTPS版本。第二个块是主配置监听443端口并配置了ssl_certificate和ssl_certificate_key指向Let‘s Encrypt颁发的证书文件。再次测试配置并重载Nginxsudo nginx -t sudo systemctl reload nginx现在访问http://你的域名浏览器会自动跳转到https://你的域名并且地址栏会显示一把锁安全连接标识。你的HTTPS网站已成功部署5.4 配置证书自动续期Let‘s Encrypt证书只有90天有效期但Certbot提供了非常方便的自动续期功能。它通过一个系统定时任务cron job来实现。你可以手动测试续期流程--dry-run表示模拟运行不会真的申请新证书sudo certbot renew --dry-run如果模拟运行成功说明自动续期配置正常。Certbot安装时通常已经创建了定时任务位于/etc/cron.d/certbot。你可以查看一下cat /etc/cron.d/certbot内容大致是每天运行两次certbot renew命令。只有当证书距离过期不足30天时renew命令才会真正执行续期。续期成功后它会自动重新加载Nginx配置因此你的网站服务不会中断。实操心得尽管有自动续期我仍然建议在证书过期前一个月手动检查一下续期日志sudo certbot renew并确保你的邮箱能收到Let‘s Encrypt的提醒邮件。我曾遇到过因为服务器时间不同步导致续期失败的情况定期检查可以防患于未然。6. 高级配置与性能安全调优基础功能跑通了但要让网站更健壮、更安全、性能更好还需要一些额外的配置。这部分是区分“能用”和“好用”的关键。6.1 性能优化启用Gzip压缩与HTTP/2Gzip压缩可以显著减少文本类资源HTML, CSS, JS的传输大小。HTTP/2则提供了多路复用、头部压缩等特性能提升页面加载速度。这些优化通常可以在Nginx的主配置文件/etc/nginx/nginx.conf中的http块内进行全局设置也可以在每个server块中单独设置。建议在http块中配置对所有站点生效。编辑主配置文件sudo vim /etc/nginx/nginx.conf在http {块内找到或添加以下配置http { # ... 其他现有配置 ... # 启用Gzip压缩 gzip on; gzip_vary on; gzip_proxied any; # 压缩级别1-96是性价比比较高的选择 gzip_comp_level 6; # 最小压缩文件大小小于此值不压缩 gzip_min_length 1024; # 压缩类型 gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xmlrss application/atomxml image/svgxml; # ... 其他配置 ... }关于HTTP/2如果你仔细看Certbot在配置443端口时已经自动添加了http2参数listen 443 ssl http2;。这表示HTTPS站点已经启用了HTTP/2。你无需额外配置。修改后测试并重载配置。6.2 安全加固隐藏Nginx版本号与限制访问默认情况下Nginx会在错误页面如404、500和响应头中显示版本号。这会给攻击者提供信息。我们可以隐藏它。在主配置文件nginx.conf的http块内或在你站点的server块内添加server_tokens off;这会将错误页面的“Nginx/1.18.0”变成简单的“nginx”同时移除响应头中的Server版本信息。另外可以限制一些敏感文件的访问比如防止.git目录、配置文件等被直接访问。在你的站点配置文件my_site的server块内添加location ~ /\.(git|ht|env) { deny all; return 404; } location ~* \.(log|ini|conf|sql|bak)$ { deny all; return 403; }6.3 静态资源缓存优化对于图片、CSS、JS等静态资源设置浏览器缓存可以极大提升回头客的访问速度。在你的站点配置文件的server块内针对特定资源类型添加location规则location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2)$ { expires 30d; # 缓存30天 add_header Cache-Control public, immutable; # 可选记录日志时排除这些静态资源减少日志体积 access_log off; }immutable属性告诉浏览器在缓存有效期内该资源永远不会改变适合带哈希版本号的前端资源。7. 常见问题排查与调试实录搭建过程很少一帆风顺这里汇总了我遇到过的典型问题及其解决方法。7.1 访问网站出现“502 Bad Gateway”这是非常常见的错误通常意味着Nginx作为反向代理无法从上游服务如PHP-FPM、Node.js、Tomcat获得有效响应。但在我们当前纯静态网站的上下文中出现502的可能性较小。如果未来你扩展为动态网站例如用PHP502错误可能由以下原因导致上游服务未运行检查你的PHP-FPM、uWSGI等服务是否启动。sudo systemctl status php7.4-fpm以实际版本为准。Nginx配置中fastcgi_pass指向错误检查Nginx配置文件中location ~ \.php$块内的fastcgi_pass指令是否指向了正确的Socket或端口例如unix:/run/php/php7.4-fpm.sock或127.0.0.1:9000。权限问题确保Nginx工作进程用户www-data或nginx有权限读取网站文件和执行上游服务的Socket。排查命令# 查看Nginx错误日志通常会有更具体的错误信息 sudo tail -f /var/log/nginx/error.log # 查看上游服务日志 sudo journalctl -u php7.4-fpm --no-pager -f7.2 访问网站出现“403 Forbidden”这通常是权限问题。Nginx进程用户没有权限访问你网站根目录下的文件。检查目录和文件所有权确保网站根目录如/var/www/my_site的所有者和组是Nginx用户。ls -la /var/www/检查目录和文件权限确保目录至少有755权限文件至少有644权限。对于静态文件755目录和644文件通常是安全的。sudo chmod -R 755 /var/www/my_site/ sudo find /var/www/my_site/ -type f -exec chmod 644 {} \;检查SELinux仅CentOS/RHELSELinux可能会阻止Nginx访问。你可以临时禁用SELinux来测试sudo setenforce 0但生产环境建议配置正确的SELinux上下文sudo chcon -R -t httpd_sys_content_t /var/www/my_site/7.3 SSL证书续期失败自动续期失败可能由于域名解析问题确保你的域名在公网DNS解析正确指向服务器IP。续期时Let‘s Encrypt会再次验证域名所有权。防火墙/安全组阻挡确保服务器的80和443端口对Let‘s Encrypt的验证服务器开放。Nginx配置被手动修改如果你手动修改了Nginx站点配置特别是移除了Certbot添加的用于验证的location /.well-known/acme-challenge块会导致验证失败。修复后可以手动强制续期sudo certbot renew --force-renewal证书存储路径权限问题极少数情况下/etc/letsencrypt/目录权限异常。可以尝试修复sudo chown -R root:root /etc/letsencrypt sudo chmod -R 0755 /etc/letsencrypt7.4 如何为多个网站配置HTTPS如果你有多个域名例如site1.com和site2.com指向同一台服务器你需要为每个域名单独申请证书并配置Nginx。方法一为每个域名单独运行Certbotsudo certbot --nginx -d site1.com -d www.site1.com sudo certbot --nginx -d site2.com -d www.site2.comCertbot会自动为每个命令创建或修改独立的Nginx配置文件。方法二单个证书包含多个域名SAN证书如果你希望site1.com和site2.com使用同一张证书可以在一条命令中指定多个-d参数sudo certbot --nginx -d site1.com -d www.site1.com -d site2.com -d www.site2.com这会产生一张包含所有域名的证书。在Nginx配置中每个server块的ssl_certificate和ssl_certificate_key都指向同一个证书文件即可。7.5 我想用IP地址访问但无法申请HTTPS证书怎么办正如前文所述Let‘s Encrypt不支持为IP签发证书。如果你只有IP又需要加密有以下几种折中方案使用自签名证书你可以自己生成证书和密钥。浏览器访问时会显示“不安全”警告需要手动信任。适用于内部系统或测试环境。sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt然后在Nginx配置中指向这两个文件。注意自签名证书不被公众信任不适合生产环境对外服务。使用免费域名申请一个免费的二级域名例如Freenom、eu.org等将其解析到你的服务器IP然后为这个域名申请Let‘s Encrypt证书。使用支持IP证书的CA少数商业CA提供IP地址证书但通常价格昂贵。对于绝大多数公开网站购买一个属于自己的域名是必要且划算的投资。整个搭建过程从裸机Linux到提供安全加密服务的网站核心在于理解每个组件的角色和配置的逻辑。Nginx作为高效的门卫SSL/TLS是可靠的加密信使而Certbot则是自动化管理的得力助手。我个人的体会是Linux上搭建Web服务初期可能会被各种配置文件和命令参数困扰但一旦你理解了其工作模型监听端口、处理请求、读取文件、返回响应很多问题都能迎刃而解。遇到报错别慌多查日志/var/log/nginx/error.log和access.log善用sudo nginx -t测试配置社区的解决方案通常都很丰富。最后保持系统和服务软件的更新定期检查证书状态你的网站就能稳定、安全地运行下去。