使用 Docker 搭建个人博客:Nginx Proxy Manager + Typecho + MariaDB 完整实践
基于 Docker 搭建稳定安全的 Typecho 博客系统[cite: 1]
最近在一台 OVH VPS 上重新规划个人博客环境,希望搭建一个稳定、安全、方便扩展的 Docker 化博客系统[cite: 1]。
技术栈选型:
- 操作系统:Debian[cite: 1]
- 容器化:Docker / Docker Compose[cite: 1]
- 反向代理:Nginx Proxy Manager[cite: 1]
- 博客程序:Typecho[cite: 1]
- 数据库:MariaDB[cite: 1]
- 网络隔离:Docker 自定义网络[cite: 1]
本文记录整个搭建过程[cite: 1]。
一、服务器环境[cite: 1]
服务器配置[cite: 1]
- CPU:Intel Core i7-7700K[cite: 1]
- 内存:32GB[cite: 1]
- 硬盘:双 SSD[cite: 1]
- 带宽:1Gbps[cite: 1]
- 系统:Debian[cite: 1]
服务器用途[cite: 1]
- 个人博客[cite: 1]
- 图床[cite: 1]
- 邮件服务[cite: 1]
- 其他 Web 服务[cite: 1]
因此整体采用服务隔离的 Docker 架构[cite: 1]。
二、整体架构[cite: 1]
拓扑结构[cite: 1]
Internet
|
HTTPS 443
|
Nginx Proxy Manager (反向代理)
|
Docker proxy 网络
|
+-------------+
| |
Typecho 其他服务
|
database 网络
|
MariaDB设计原则[cite: 1]
- 只开放必要公网端口[cite: 1]。
- 应用服务不直接暴露至公网[cite: 1]。
- 数据库仅允许内部网络访问[cite: 1]。
- 全局使用 Docker 网络进行通信[cite: 1]。
三、创建 Docker 公共网络[cite: 1]
在部署容器前,需先手动创建一个独立的 Docker 公共网络,用于跨项目/容器间的通信[cite: 1]。
创建命令[cite: 1]
docker network create proxy网络架构示意[cite: 1]
proxy (外部网络)
├── nginx-proxy-manager
└── typecho作用与优势[cite: 1]
在 docker-compose.yml 中声明 external: true 意味着 Docker Compose 将直接使用已存在的 proxy 网络而不会重复创建[cite: 1]。这样一来,NPM 容器即可直接通过容器名访问同一网络内的 typecho:80[cite: 1]。
四、部署 Nginx Proxy Manager[cite: 1]
Nginx Proxy Manager (NPM) 主要负责:域名转发、HTTPS SSL 证书自动申请与续签、反向代理以及作为整个服务器的 Web 服务统一入口[cite: 1]。
- 工作目录:
/opt/docker/nginx-proxy-manager[cite: 1]
docker-compose.yml 配置[cite: 1]
services:
npm:
image: jc21/nginx-proxy-manager:2.15.1
container_name: nginx-proxy-manager
restart: always
ports:
- "80:80"
- "443:443"
- "127.0.0.1:81:81"
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
networks:
- proxy
networks:
proxy:
external: true五、为什么关闭 81 端口公网访问?[cite: 1]
Nginx Proxy Manager 默认的端口绑定规则为 0.0.0.0:81,这意味着任何人都可以在公网上直接尝试访问管理后台[cite: 1]。
修改为 127.0.0.1:81:81 后的访问路径对比:
- 公网访问:
公网➔X➔81 端口关闭[cite: 1] - 本机访问:
本机➔127.0.0.1:81➔NPM 管理后台[cite: 1]
远程管理方式[cite: 1]
如需从本地电脑安全访问管理后台,可使用 SSH 隧道进行端口转发:
ssh -L 8081:127.0.0.1:81 alice@服务器IP -p 22222执行后,在本地浏览器打开 http://127.0.0.1:8081 即可安全进入 NPM 管理后台[cite: 1]。
六、部署 Typecho 与 MariaDB[cite: 1]
- 博客镜像:
joyqi/typecho:1.3.0-php8.2-apache(集成 Typecho、Apache 和 PHP 8.2)[cite: 1] - 工作目录:
/opt/docker/typecho[cite: 1]
docker-compose.yml 配置[cite: 1]
services:
mariadb:
image: mariadb:11
container_name: typecho-db
restart: always
environment:
MYSQL_ROOT_PASSWORD: your_root_password
MYSQL_DATABASE: typecho
MYSQL_USER: typecho
MYSQL_PASSWORD: your_password
volumes:
- ./mysql:/var/lib/mysql
networks:
- database
typecho:
image: joyqi/typecho:1.3.0-php8.2-apache
container_name: typecho
restart: always
depends_on:
- mariadb
environment:
TYPECHO_SITE_URL: [https://blog.example.com](https://blog.example.com)
TYPECHO_DB_ADAPTER: Pdo_Mysql
TYPECHO_DB_HOST: mariadb
TYPECHO_DB_PORT: 3306
TYPECHO_DB_USER: typecho
TYPECHO_DB_PASSWORD: your_password
TYPECHO_DB_DATABASE: typecho
volumes:
- ./typecho:/app/usr
networks:
- proxy
- database
networks:
proxy:
external: true
database:七、为什么 Typecho 服务没有映射 ports?[cite: 1]
传统方式[cite: 1]
传统部署会配置 ports: - "8080:80",直接通过 http://服务器IP:8080 访问[cite: 1]。
当前架构[cite: 1]
在当前方案中,访问链路为:
用户 ➔ 端口 443 ➔ Nginx Proxy Manager ➔ Docker内部网络 (proxy) ➔ Typecho因此 Typecho 容器完全不需要在宿主机映射任何端口,只需暴露在内网即可[cite: 1]。
八、MariaDB 数据库隔离[cite: 1]
MariaDB 容器仅加入 database 网络,不加入 proxy 网络[cite: 1]。
Typecho ──(database 网络)── MariaDB- 数据库未暴露到公网[cite: 1]。
- 宿主机不需要开放
3306端口,极大提高了数据安全性[cite: 1]。
九、服务启动与验证[cite: 1]
1. 检查与启动[cite: 1]
# 检查 Compose 配置语法
docker compose config
# 后台启动所有服务
docker compose up -d
# 查看正在运行的容器
docker ps启动完成后,应能看到以下容器运行:
nginx-proxy-manager[cite: 1]typecho[cite: 1]typecho-db[cite: 1]
2. 测试 Docker 网络连通性[cite: 1]
进入 NPM 容器内部进行网络联通性测试:
docker exec -it nginx-proxy-manager bash在容器内执行 HTTP 请求:
curl http://typecho若返回 302 Redirect 或 HTML 网页源码,说明 nginx-proxy-manager 通过 proxy 网络访问 typecho 容器通信正常[cite: 1]。
十、NPM 配置博客域名与 SSL[cite: 1]
登录 NPM 后台,点击 Proxy Hosts ➔ Add Proxy Host,按如下参数配置[cite: 1]:
Details 选项卡[cite: 1]
- Domain Names:
blog.example.com[cite: 1] - Scheme:
http[cite: 1] - Forward Hostname / IP:
typecho[cite: 1] - Forward Port:
80[cite: 1]
SSL 选项卡[cite: 1]
- 勾选 Block Common Exploits
- SSL Certificate: 选择 Request a new SSL Certificate(申请免费证书)[cite: 1]
- 勾选 Force SSL[cite: 1]
- 勾选 HTTP/2 Support[cite: 1]
保存后,在浏览器访问 https://blog.example.com 进入 Typecho 安装界面[cite: 1]。
安装页面数据库填写项[cite: 1]
- 数据库地址:
mariadb[cite: 1] - 数据库名:
typecho[cite: 1] - 用户名:
typecho[cite: 1] - 密码:设置的
MYSQL_PASSWORD[cite: 1]
十一、最终端口与架构总结[cite: 1]
端口开放规划[cite: 1]
| 端口号 | 服务说明 | 开放状态 |
|---|---|---|
| 22222 | SSH 远程登录 | 开放(公网)[cite: 1] |
| 80 | HTTP 流量入站 | 开放(公网)[cite: 1] |
| 443 | HTTPS 安全流量入站 | 开放(公网)[cite: 1] |
| 81 | NPM 后台管理 | 关闭(仅允许 127.0.0.1 / SSH 隧道)[cite: 1] |
| 3306 | MariaDB 数据库 | 关闭(仅限内部网络)[cite: 1] |
| 8080 | Typecho 容器端口 | 关闭(仅限内部网络)[cite: 1] |
架构总览图[cite: 1]
Docker 宿主机环境
│
├── nginx-proxy-manager
│ ├── 公网端口: 80, 443
│ └── 本地监听: 127.0.0.1:81
│
├── typecho
│ └── 内部运行: Apache + PHP
│
└── typecho-db
└── 内部运行: MariaDB架构优势[cite: 1]
- ✅ 服务高度隔离:容器职责单一,互不干扰[cite: 1]。
- ✅ 数据持久化:关键数据挂载至宿主机目录,易于备份[cite: 1]。
- ✅ HTTPS 自动化:自动化证书申请与强制跳转[cite: 1]。
- ✅ 高安全性:核心应用及数据库不直接暴露于公网[cite: 1]。
- ✅ 极佳扩展性:未来新增服务只需加入对应网络即可[cite: 1]。
未来扩展蓝图[cite: 1]
proxy 网络:
├── Typecho
├── MinIO (图床)
├── Uptime Kuma (状态监控)
└── 其他 Web 应用
database 网络:
├── MariaDB
├── Redis
└── PostgreSQL这套 Docker 架构可以作为个人服务器长期运行的稳定基础环境[cite: 1]。