从零部署个人网站:域名·备案·Hugo·HTTPS
完整记录一个静态网站从购买域名到 HTTPS 上线的全流程,涵盖域名、ICP 备案、Hugo 构建、Nginx 部署、SSL 证书配置等环节。
一、域名与 DNS
1.1 购买域名
在任意域名注册商(阿里云、腾讯云、Namecheap 等)购买域名。常见后缀 .com / .me / .top 等。
1.2 实名认证
购买后域名需完成实名认证。实名认证不完成,DNS 解析不会生效。认证通常几分钟到几小时生效。
1.3 DNS 解析
在域名控制台添加 A 记录,将域名指向服务器公网 IP。
your-domain.com A your-server-ip
www.your-domain.com A your-server-ip
解析生效后,ping your-domain.com 应返回你的服务器 IP。
二、ICP 备案
2.1 什么是 ICP 备案
根据中国法规,服务器在中国境内的网站必须完成 ICP 备案。无论网站内容多少,只要面向公众开放就需要备案。
2.2 备案流程
- 提交网站信息、个人资料至管局审核
- 审核周期:10~20 个工作日
- 备案完成前,域名不得指向国内 IP 的 80/443 端口
2.3 备案期间的临时方案
备案期间域名不可用,可以用服务器公网 IP + 非标端口临时上线:
http://<服务器公网IP>:8080
其他临时托管方案:
| 平台 | 特点 | 国内访问 |
|---|---|---|
| CODING Pages | 腾讯云旗下,免费,国内 CDN | 快 |
| 阿里云 OSS / 腾讯云 COS | 按量付费,静态网站托管 | 快 |
| 海外服务器(香港) | 免备案,延迟低 | 较快 |
注意:80/443 端口未备案被扫到,运营商会直接封端口。备案是一次性的,之后永久有效。
三、Hugo 构建与部署
3.1 本地构建
hugo
输出到 public/ 目录。Hugo 是静态站点生成器,将 Markdown 内容编译为纯 HTML/CSS/JS。
3.2 部署三步走
graph LR
A[hugo build] --> B[scp push]
B --> C[chown fix permissions]
C --> D[上线 ✅]
3.3 scp 推送
scp -i <your-key> -r public/* <user>@<server-ip>:/var/www/html/
Windows 用户注意:PowerShell 里直接敲 scp 会找不到命令,需要用完整路径:
C:\Windows\System32\OpenSSH\scp.exe -i <key-path> -r public\* <user>@<server-ip>:/var/www/html/
改用 Git Bash 也不会有这个问题。
3.4 修复文件权限
scp 用 root 上传后,文件 owner/group 都是 root,但 nginx worker 通常以 www-data 用户运行——读不了 root 的文件,浏览器直接 403/403。
ssh -i <key> <user>@<server-ip> "chown -R www-data:www-data /var/www/html/"
这一步容易忘,建议写进部署脚本。不需要 reload nginx,也不需要重启任何服务。
四、SSL 证书与 HTTPS
4.1 什么是 SSL 证书
SSL 证书(X.509 标准数字文档)包含:
| 内容 | 说明 |
|---|---|
| 域名信息 | Subject: CN = your-domain.com |
| 公钥 | 用于 TLS 握手加密临时密钥 |
| CA 签名 | 证明该证书由可信任的 CA 签发 |
| 有效期 | notBefore / notAfter |
为什么需要?没有 HTTPS,所有通信都是明文传输,中间人可以截取或篡改内容。
4.2 DNS 验证原理
申请证书时,CA 需要证明你拥有域名控制权:
sequenceDiagram
participant CA
participant You as 你(域名控制台)
participant DNS as DNS 服务器
CA->>You: 请在域名下添加 TXT 记录: "abc123"
You->>DNS: 添加 _acme-challenge TXT "abc123"
CA->>DNS: 查询 _acme-challenge TXT 记录
DNS->>CA: 返回 "abc123"
CA->>You: 匹配成功,签发证书 ✅
只有域名所有者才能操作 DNS 控制台,所以这种方式可信。DNS 验证的优点是:不依赖服务器 80 端口,且支持通配符证书。
4.3 证书文件说明
申请成功后拿到三个文件:
| 文件 | 作用 | 安全要求 |
|---|---|---|
cert.pem |
证书(域名 + 公钥 + CA 签名) | 可公开 |
cert.key |
私钥(对应公钥的私密部分) | 绝不可泄露 |
cert.cer |
证书链(CA 的中级证书) | 可公开 |
私钥是你申请时本地生成的。只有持有了私钥才能完成 TLS 握手。私钥泄露 = 别人可以冒充你的网站。
证书链的作用:浏览器只信任根 CA,你的证书是由中级 CA 签发的。需要证书链补全信任链。
graph TD
subgraph 信任链验证
A[cert.pem<br/>your-domain.com] -->|CA 签名验证| B[cert.cer<br/>中级 CA]
B -->|CA 签名验证| C[根 CA<br/>浏览器内置信任]
end
4.4 Nginx 配置 SSL
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /path/to/cert.pem; # 证书
ssl_certificate_key /path/to/cert.key; # 私钥
ssl_trusted_certificate /path/to/cert.cer; # 证书链
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
ssl_certificate / ssl_certificate_key 告诉 nginx 证书和私钥在服务器上的路径。TLS 握手时 nginx 用私钥解密客户端发来的密钥。
4.5 HTTP → HTTPS 强制跳转
server {
listen 80;
server_name your-domain.com www.your-domain.com;
return 301 https://$host$request_uri;
}
原理:用户访问 http://your-domain.com 时,nginx 返回 301(永久重定向),浏览器自动跳转到 HTTPS。
$host 和 $request_uri 是 nginx 内置变量,保留原始 URL,比如 /about/ 会正确跳转到 https://your-domain.com/about/。
301 vs 302:301 是永久重定向,浏览器会缓存,下次直接走 HTTPS。302 是临时重定向,每次都会先请求 HTTP。
4.6 完整请求流程
sequenceDiagram
actor User as 用户浏览器
participant DNS
participant Server as 服务器(Nginx)
User->>DNS: 输入 your-domain.com
DNS->>User: 返回服务器 IP
User->>Server: HTTP 请求 (80)
Server->>User: 301 → https://your-domain.com
User->>Server: HTTPS 请求 (443)
Note over User,Server: TLS 握手 / 验证证书链 / 协商对称密钥
Server->>User: 🔒 加密通信开始
4.7 RSA 非对称加密:同一个私钥的两个用法
TLS 中 — 私钥用于解密:
客户端用公钥加密"临时密钥"发过来 → 服务器用私钥解密拿到密钥
→ 后续通信用这个对称密钥加密
SSH 认证中 — 私钥用于签名:
服务器发随机数 → 客户端用私钥签名 → 服务器用公钥验签 → 通过则放行
同一把私钥能做两件事,因为 RSA 的数学本质:
| 操作 | 公式 |
|---|---|
| 公钥加密 | 密文 = 明文^e mod n |
| 私钥解密 | 明文 = 密文^d mod n |
| 私钥签名 | 签名 = 消息^d mod n |
| 公钥验签 | 消息 = 签名^e mod n |
加密和签名是同一套数学公式,只是谁拿指数 d(私钥)谁拿 e(公钥)的区别。
私钥是"只有你有的秘密",用它来加密还是解密,看场景需要。
4.8 验证配置
nginx -t # 测试配置文件语法
systemctl reload nginx # 优雅重载,不中断现有连接
nginx -t 检查配置语法和文件引用。reload 发送 SIGHUP 信号给 nginx 主进程,读取新配置后优雅切换——不中断正在处理的请求。
4.9 证书续签
- 免费证书通常 90 天~1 年有效期
- 到期前需续签,否则浏览器显示"不安全"
- 推荐 Let’s Encrypt + Certbot,配置好自动续签后一劳永逸
- 私钥文件权限建议设为
600(仅 root 可读)
五、常见问题
5.1 推送后页面 403 / 404
大概率是文件权限问题。跑一遍 chown -R www-data:www-data。
5.2 更新内容后还是旧版本
浏览器缓存了静态资源,硬刷新(Ctrl+F5 / Cmd+Shift+R)或开无痕模式访问。
5.3 修改了 nginx 配置
改完需要 systemctl reload nginx。只更新文件内容不需要。
5.4 图片显示不出来
检查文件头确认实际格式。某些第三方 API 返回 PNG 文件但后缀名写 .jpg,Windows 宽容能显示,Linux + 特定浏览器可能拒绝渲染。
# Linux 下检查文件真实格式
file album_cover.jpg
教训:不要相信第三方 API 返回的文件后缀名,检查文件头确认实际格式。
5.5 备案期间域名无法访问
备案完成前不要将域名解析到国内服务器的 80/443 端口。临时方案用 IP + 非标端口。
六、流程总览
| 环节 | 耗时 | 关键点 |
|---|---|---|
| 域名实名 | 分钟~小时 | 不做 DNS 不生效 |
| ICP 备案 | 10~20 工作日 | 中国境内服务器必须做 |
| Hugo 部署 | 即时 | 三步走:build → push → chown |
| SSL 证书 | 即时~1天 | DNS 验证后自动部署 |
| 配置 nginx | 即时 | SSL + 301 跳转 |