学习目标: 从零到一搭建一个可以通过公网访问、带HTTPS的个人网站,掌握域名、服务器、Nginx、证书配置的全流程。
16.1 整体架构概览
在动手之前,先理解一个网站是如何工作的:
用户浏览器
│
▼ ① 输入 yourdomain.com
DNS服务器 ──▶ 返回服务器IP地址
│
▼ ② HTTPS请求
云服务器(ECS)
│
▼ ③ Nginx接收请求
├── 静态文件 → 直接返回HTML/CSS/JS
│ (yourdomain.com)
│
└── API请求 → 转发给后端
(yourdomain.com/api/* → Flask:5000)
本章我们分步骤实现上面这个架构。
16.2 域名注册与DNS配置
选购域名
推荐域名注册商:
| 平台 | 优点 | 价格参考 |
|---|---|---|
| Namesilo | 海外最便宜,送免费WHOIS隐私保护 | .com约$10/年 |
| Cloudflare | 成本价(不加价),自带CDN和DDoS防护 | .com约$10/年 |
| 阿里云(万网) | 国内最方便,备案流程完善 | .com约¥55/年 |
| 腾讯云(DNSPod) | 国内性价比高 | .com约¥55/年 |
选域名建议:
.com最通用,但好名字基本被抢光了.me、.dev、.io是程序员常用后缀- 短、好记、好拼写 > 其他一切
- 避免数字和连字符(口头传播不友好)
🔒 国内特殊要求: 使用国内服务器需要备案,而备案的前提是域名已经实名认证。实名认证通常需要1-3个工作日。
DNS配置
DNS(域名系统)就是电话簿——把域名翻译成IP地址。
常见DNS记录类型:
A记录 域名 → IPv4地址 yourdomain.com → 123.123.123.123
AAAA记录 域名 → IPv6地址 yourdomain.com → 2001:db8::1
CNAME 域名 → 另一个域名 www.yourdomain.com → yourdomain.com
MX 邮件服务器记录 → 用于配置邮箱
TXT 文本记录 → SPF/DKIM(邮箱验证)、域名验证
配置流程(以阿里云为例):
1. 进入域名控制台 → 解析设置
2. 添加两条记录:
`
记录类型: A
主机记录: @ (表示根域名 yourdomain.com)
记录值: 你服务器的公网IP
记录类型: A
主机记录: www
记录值: 你服务器的公网IP (或CNAME到@)
`
3. 等待DNS生效(几分钟到几小时,可通过nslookup yourdomain.com验证)
💡 DNS修改后不会立刻全球生效,因为有TTL(缓存时间)。可以用 `dig yourdomain.com` 或 [DNSChecker.org](https://dnschecker.org) 查看全球传播状态。
16.3 云服务器选购
选哪家?
| 平台 | 适合人群 | 新用户优惠 |
|---|---|---|
| 阿里云 ECS | 国内用户首选 | 经常有百元/年活动 |
| 腾讯云 CVM | 国内性价比 | 学生优惠不错 |
| AWS Lightsail | 海外用户/学AWS | $3.5/月起步 |
| Vultr / DigitalOcean | 海外便宜VPS | $6/月起 |
入门配置建议: 1核CPU + 1-2GB内存 + 40GB SSD,足够支撑个人博客/小项目(月费约¥30-70)。
服务器初始配置
SSH登录后首先做安全加固:
# 1. 更新系统
apt update && apt upgrade -y
# 2. 创建普通用户(不要一直用root)
adduser deploy
usermod -aG sudo deploy
# 3. 配置SSH密钥登录(禁用密码登录更安全)
# 在本地生成密钥:
ssh-keygen -t ed25519 -C "my-server"
# 上传公钥到服务器:
ssh-copy-id deploy@your-server-ip
# 编辑SSH配置 /etc/ssh/sshd_config:
# PasswordAuthentication no
# PermitRootLogin no
# Port 2222 (改端口减少扫描)
systemctl restart sshd
# 4. 配置防火墙
ufw allow 2222/tcp # SSH
ufw allow 80/tcp # HTTP
ufw allow 443/tcp # HTTPS
ufw enable
16.4 Nginx安装与配置
Nginx是世界上最流行的Web服务器之一,以高性能、低资源消耗著称。
安装与基本命令
sudo apt install nginx -y
# 常用命令
sudo systemctl start nginx # 启动
sudo systemctl enable nginx # 开机自启
sudo systemctl status nginx # 查看状态
sudo nginx -t # 测试配置文件语法
sudo nginx -s reload # 热重载配置(不中断服务)
安装后浏览器访问 http://your-server-ip,看到Nginx欢迎页就说明成功了。
配置静态网站
Nginx配置文件在 /etc/nginx/sites-available/,启用时创建符号链接到 sites-enabled/。
# /etc/nginx/sites-available/myblog
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/myblog; # 网站文件根目录
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 静态资源缓存(提升性能)
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}
# 启用配置
sudo ln -s /etc/nginx/sites-available/myblog /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default # 删除默认配置
sudo nginx -t && sudo nginx -s reload
# 创建网站目录并放入文件
sudo mkdir -p /var/www/myblog
echo "Hello World!
" | sudo tee /var/www/myblog/index.html
反向代理到后端API
当你有后端应用(如Flask运行在5000端口),Nginx作为反向代理:
server {
listen 80;
server_name yourdomain.com;
# 前端静态文件
root /var/www/myblog;
index index.html;
location / {
try_files $uri $uri/ /index.html; # SPA fallback
}
# API请求转发到Flask
location /api/ {
proxy_pass http://127.0.0.1:5000/;
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;
}
}
16.5 HTTPS证书配置(Let's Encrypt)
🔒 没有HTTPS的网站,浏览器会标记为"不安全"。任何人(WiFi管理员、运营商)都可以看到甚至篡改你和网站之间的通信。
为什么选Let's Encrypt?
- ✅ 完全免费
- ✅ 自动化:certbot工具自动完成验证和续期
- ✅ 被主流浏览器信任
- ✅ 90天有效期,但certbot自动续期,无需人工干预
配置步骤
# 安装certbot
sudo apt install certbot python3-certbot-nginx -y
# 一键获取并配置证书(certbot自动修改nginx配置)
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
# 按提示操作:
# 1. 输入邮箱(用于证书到期提醒)
# 2. 同意服务条款
# 3. 选择是否强制HTTP→HTTPS跳转(建议选2:自动重定向)
完成后certbot自动修改Nginx配置,listen 443 ssl和证书路径都配好了。
验证自动续期:
sudo certbot renew --dry-run # 模拟续期,确认一切正常
# certbot默认添加了cron/systemd timer,证书到期前30天自动续期
手动配置HTTPS + HTTP重定向(理解内部机制):
# HTTP → 强制跳转到HTTPS
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$host$request_uri;
}
# HTTPS实际服务
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
# 现代SSL配置(安全评分A+)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# HSTS:告诉浏览器"以后只走HTTPS"
add_header Strict-Transport-Security "max-age=63072000" always;
root /var/www/myblog;
index index.html;
location / { try_files $uri $uri/ =404; }
}
你可以用 [SSL Labs](https://www.ssllabs.com/ssltest/) 给网站评分,目标A+。
16.6 静态网站部署
方案对比
| 方案 | 适合场景 | 优点 | 缺点 |
|---|---|---|---|
| Nginx直接托管 | 简单静态站 | 简单直接 | 无自动部署 |
| GitHub Pages | 开源项目/个人主页 | 免费+自动部署 | 仅静态,国内访问慢 |
| Vercel / Netlify | 现代前端项目 | 自动HTTPS+CDN+CI | 国内访问速度一般 |
| 对象存储+CDN | 纯静态+AWS/阿里云生态 | 按量付费,流量大便宜 | 配置稍复杂 |
使用GitHub Actions自动部署到服务器
# .github/workflows/deploy.yml
name: Deploy to Server
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: |
npm install
npm run build
- name: Deploy to server
uses: easingthemes/ssh-deploy@v4
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_KEY }}
REMOTE_HOST: ${{ secrets.HOST }}
REMOTE_USER: deploy
SOURCE: "dist/"
TARGET: "/var/www/myblog/"
每次git push到main分支,GitHub Actions自动构建并部署到服务器。真正的"push就上线"。
16.7 简易后端API(Python Flask)
前端有了,还需要一个能处理数据的后端。
# app.py — 一个带数据库的简易API
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
app = Flask(__name__)
CORS(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
db = SQLAlchemy(app)
# 数据模型
class Article(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
def to_dict(self):
return {'id': self.id, 'title': self.title, 'content': self.content}
with app.app_context():
db.create_all() # 创建数据库表
# API路由
@app.route('/api/articles', methods=['GET'])
def list_articles():
articles = Article.query.order_by(Article.id.desc()).all()
return jsonify([a.to_dict() for a in articles])
@app.route('/api/articles', methods=['POST'])
def create_article():
data = request.json
article = Article(title=data['title'], content=data['content'])
db.session.add(article)
db.session.commit()
return jsonify(article.to_dict()), 201
@app.route('/api/articles/', methods=['GET'])
def get_article(article_id):
article = Article.query.get_or_404(article_id)
return jsonify(article.to_dict())
if __name__ == '__main__':
app.run(host='127.0.0.1', port=5000)
部署方式(使用systemd管理Flask进程):
# /etc/systemd/system/myblog.service
[Unit]
Description=My Blog Flask App
After=network.target
[Service]
User=deploy
WorkingDirectory=/home/deploy/myblog
ExecStart=/home/deploy/myblog/venv/bin/gunicorn -w 2 -b 127.0.0.1:5000 app:app
Restart=always
Environment=FLASK_ENV=production
[Install]
WantedBy=multi-user.target
# 生产环境用Gunicorn运行Flask
cd /home/deploy/myblog
python3 -m venv venv
source venv/bin/activate
pip install flask flask-sqlalchemy flask-cors gunicorn
# 启动服务
sudo systemctl enable --now myblog
sudo systemctl status myblog
⚠️ 生产环境请用PostgreSQL/MySQL替代SQLite,并把SECRET_KEY等配置放到环境变量而非代码中。
16.8 备案流程(中国大陆)
如果你的服务器在国内,域名必须备案。这不是可选的,是法律要求。
备案前准备
1. ✅ 域名已完成实名认证(注册商处操作)
2. ✅ 服务器已购买(需要有至少3个月有效期)
3. ✅ 准备身份证件(个人)或营业执照(企业)
备案流程
第1步:登录云厂商备案系统
→ 阿里云:aliyun.com → 备案
→ 腾讯云:cloud.tencent.com → 备案
第2步:填写备案信息
→ 主体信息(你是谁)
→ 网站信息(网站名称、域名、服务内容)
→ 网站负责人信息
第3步:云厂商初审(1-2个工作日)
→ 检查填写是否正确
→ 网站名称不能含"中国""国家""官方"等敏感词
第4步:人脸核验 + 上传资料
第5步:工信部短信验证
第6步:管局审核(3-20个工作日,各省不同)
→ 审核通过后会收到工信部短信
→ 获得备案号(如 京ICP备2025XXXXXX号)
第7步:备案号必须放在网站底部
京ICP备2025XXXXXX号
常见踩坑:
- 🚫 备案期间网站不能访问(未备案域名解析到国内IP会被拦截)
- 🚫 个人备案不能包含商业/电商/论坛等内容
- 🚫 备案信息变更(换服务器、改域名)需要更新备案
- 💡 如果嫌麻烦,可以先用香港/海外服务器学习(不需要备案),正式上线再迁回国内
本章小结
整个流程走下来,你有了:
yourdomain.com ──DNS──▶ 云服务器IP ──Nginx──▶ 静态网站 + Flask API
🔒 HTTPS (Let's Encrypt自动续期)
🔄 GitHub Actions 自动部署
核心技能清单:
- [x] 域名注册与DNS解析
- [x] 云服务器购买与SSH配置
- [x] Nginx安装、静态托管、反向代理
- [x] Let's Encrypt HTTPS证书配置
- [x] Flask后端API + systemd进程管理
- [x] GitHub Actions CI/CD自动部署
- [x] 理解国内备案流程
⬅️ [上一章:15-人工智能入门](15-人工智能入门.html) | ➡️ [下一章:17-职业发展路径](17-职业发展路径.html)