Nginx 反向代理
本文详细记录如何通过 Nginx 反向代理将 Halo 博客服务部署到自定义域名,并成功配置 HTTPS 访问的完整过程。文中包含实际操作中遇到的问题及其解决方案,希望对有类似需求的用户有所帮助。
系统架构概述
本项目采用的部署架构为:
1.
Halo 服务:运行在 Docker 容器中,监听 8090 端口
2.
Nginx:作为反向代理服务器,接收外部请求并转发给 Halo
3.
HTTPS:通过 SSL 证书提供加密访问
4.
域名:使用自定义域名提供专业访问体验
访问流程:用户 → 域名 → Nginx (HTTPS) → Halo (8090端口)
Nginx 反向代理配置步骤
1. 安装 Nginx
sudo apt update
sudo apt install -y nginx
2. 创建 Nginx 配置文件
创建 /etc/nginx/conf.d/halo.conf
文件,内容如下:
# HTTP 服务器块,强制重定向到 HTTPS
server {
listen 80;
server_name mrdio.top www.mrdio.top;
# 将所有 HTTP 请求重定向到 HTTPS
return 301 https://$server_name$request_uri;
}
# HTTPS 服务器块
server {
listen 443 ssl http2;
server_name mrdio.top www.mrdio.top;
client_max_body_size 50m;
# SSL 证书配置
ssl_certificate /etc/nginx/cert/mrdio.top.pem;
ssl_certificate_key /etc/nginx/cert/mrdio.top.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_prefer_server_ciphers on;
# 静态资源缓存
location ~* \.(gif|jpg|jpeg|png|bmp|ico|css|js|svg|ttf|woff|woff2|eot)$ {
proxy_pass http://127.0.0.1:8090;
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;
expires 30d;
add_header Cache-Control "public, immutable";
}
# 代理所有核心请求到 Halo
location / {
proxy_pass http://127.0.0.1:8090;
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;
# 支持 WebSocket 连接
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
3. 测试并应用配置
# 测试配置文件语法
sudo nginx -t
# 重新加载Nginx配置
sudo systemctl reload nginx
遇到的问题及解决方案
问题一:Halo 服务无法通过域名访问
症状表现:
通过域名无法访问,但使用服务器IP+端口可以正常访问。
输入参考:
root@server:~# nslookup mrdio.top
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
*** Can't find mrdio.top: No answer
原因分析:
域名解析失败,DNS服务器无法解析自定义域名 mrdio.top。
解决方案:
我使用的是阿里云的轻量服务器:
需要先将域名添加到服务器的dns解析中。这时候使用http可以访问域名了。然后去申请ssl,部署到该服务器中,如下图(SSL控制台进入到该界面):
填写路径:
阿里云SSL证书“部署配置”填写指南
根据您的服务器环境(Linux + Nginx),请这样填写:
证书路径:
/etc/nginx/cert/mrdio.top.pem
私钥路径:
/etc/nginx/cert/mrdio.top.key
证书链路径
/etc/nginx/cert/mrdio.top.pem
重启命令:
sudo systemctl reload nginx
(对于大多数情况,包括Let's Encrypt证书,证书链通常已经包含在.pem文件中,这里可以填写与“证书路径”相同的值,或者直接留空)
问题二:Halo 返回404状态码但服务正常运行
症状表现:
Nginx能够连接到Halo服务,但返回404状态码。
输入参考:
root@server:~# curl -I http://127.0.0.1:8090
HTTP/1.1 404 Not Found
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/problem+json
原因分析:
Halo服务已启动但尚未完成初始化,或健康检查通过但主要服务未完全就绪。
解决方案:
等待Halo完成初始化过程,首次启动可能需要几分钟时间加载所有插件和组件。
问题三:HTTPS部署后无法正常访问
症状表现:
阿里云控制台显示证书部署成功,但网站无法通过HTTPS访问。
输入参考:
root@server:~# sudo cat /etc/nginx/conf.d/halo.conf
# 配置文件中只有HTTP服务器块,缺少HTTPS配置
原因分析:
阿里云的证书部署功能可能只上传了证书文件,但没有自动修改Nginx配置添加上HTTPS服务器块。
解决方案:
手动添加HTTPS服务器配置块,并确保包含以下关键元素:
1.
监听443端口并启用SSL
2.
正确配置证书和私钥路径
3.
配置SSL协议和加密套件
问题四:HTTPS访问后样式错乱或功能异常
症状表现:
HTTPS访问后页面样式丢失或部分功能无法使用。
原因分析:
Halo容器内的应用程序仍然认为它通过HTTP访问,因此生成的所有资源链接都是HTTP协议,导致浏览器阻止混合内容。
解决方案:
更新Halo的环境变量,告知它正在通过HTTPS访问:
# 修改docker-compose.yaml文件
environment:
- HALO_EXTERNAL_URL=https://mrdio.top/ # 确保使用https://
# 重启Halo容器
docker-compose down
docker-compose up -d
关键要点总结
1.
域名解析是基础:确保域名正确解析到服务器IP是成功访问的前提
2.
Nginx配置需完整:必须同时配置HTTP(重定向)和HTTPS服务器块
3.
证书路径要正确:SSL证书和私钥文件需要放在Nginx可访问的路径
4.
Halo配置需更新:部署HTTPS后必须更新HALO_EXTERNAL_URL环境变量
5.
防火墙需开放端口:确保云服务器安全组开放80和443端口
验证成功的标准
1.
访问
http://yourdomain.com
自动跳转到https://yourdomain.com
2.
浏览器地址栏显示锁图标,表示SSL证书有效
3.
所有页面资源(CSS、JS、图片)均通过HTTPS加载
4.
后台管理功能正常工作
5.
无混合内容警告或安全错误
通过以上步骤和问题解决方案,您可以成功将Halo博客服务通过Nginx反向代理部署到自定义域名,并实现安全的HTTPS访问。