Docker Desktop 开发 & 生产部署
本项目开发环境为 Windows + WSL2 + Docker Desktop,生产环境为 Linux + Docker Engine。 本文档涵盖:本地开发环境搭建、Docker 服务使用、生产环境部署、数据库备份还原。
第一部分:本地开发环境搭建
1.1 Docker 服务概览
本项目 docker-compose.yml 包含以下服务:
| 服务 | 说明 | 端口 | 绑定地址 |
|---|---|---|---|
| nginx | Nginx 1.25 Web 服务器 | 8000 | 127.0.0.1 |
| php | PHP 8.4-FPM (ThinkPHP 8) | 9000 | 容器内网 |
| mysql | MySQL 8.0 数据库 | 3306 | 127.0.0.1 |
| redis | Redis 7 缓存 | 6379 | 127.0.0.1 |
| phpmyadmin | 数据库管理面板(可选) | 8081 | 127.0.0.1 |
所有容器端口均绑定
127.0.0.1,不直接暴露公网,由宿主机 Nginx 统一反代并处理 SSL。
1.2 整体架构
┌─────────────────────────────────────────────────┐
│ Windows 11 │
│ ┌───────────────────────────────────────────┐ │
│ │ WSL2 虚拟机 │ │
│ │ ┌─────────────────────────────────────┐ │ │
│ │ │ Docker Desktop │ │ │
│ │ │ │ │ │
│ │ │ Docker Engine (原生 Linux) │ │ │
│ │ │ ├── nginx :8000 │ │ │
│ │ │ ├── php :9000 │ │ │
│ │ │ ├── mysql :3306 │ │ │
│ │ │ ├── redis :6379 │ │ │
│ │ │ └── phpmyadmin :8081 │ │ │
│ │ │ │ │ │
│ │ │ │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────┘ │
│ │
│ 浏览器访问: http://localhost:8000 │
└─────────────────────────────────────────────────┘
1.3 第一步:安装 WSL2
在 Windows PowerShell(管理员) 中执行:
# 1. 启用 WSL 功能
wsl --install
# 2. 重启电脑后,进入 Ubuntu,首次启动会提示创建用户名和密码
wsl
更多细节参考微软官方文档:安装 WSL
1.4 第二步:安装 Docker Desktop
从 Docker 官网 下载并安装 Docker Desktop for Windows。安装完成后,Docker Desktop 会自动管理 WSL2 中的 Docker Engine。
1.4.1 配置镜像加速
配置镜像加速(国内必做):
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.unsee.tech",
"https://hub.uuuadc.top"
]
}
EOF
不配置镜像加速可能导致
docker compose up -d时拉取镜像极慢或超时。
1.5 第三步:启动项目
# 启动所有 Docker 服务
docker compose up -d
首次启动会自动:构建 PHP 镜像 → 创建数据库 → 执行 database/init_database.sql 初始化 → 配置 Nginx。
首次启动后,安装 ThinkPHP 依赖(vendor/ 目录通过 Volume 挂载,不会自动安装):
docker exec -it gmm-php composer install
验证:
curl http://localhost:8000
若宿主机内已安装 PHP + Composer,也可在启动前于
backend/目录执行composer install。
访问地址
| 服务 | 地址 |
|---|---|
| 后端 API | http://localhost:8000 或 http://<本机IP>:8000 |
| phpMyAdmin | http://localhost:8081 |
| MySQL | 127.0.0.1:3306(root / root) |
停止
docker compose stop # 保留容器和数据
docker compose down # 删除容器,保留数据
docker compose down -v # ⚠️ 全部清除(含数据库数据)
第二部分:Docker 服务详解
2.1 生产环境安装 Docker
Ubuntu / Debian(推荐从 Ubuntu 源安装)
# 1. 备份当前源
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
# 2. 写入 Ubuntu 24.04 (Noble) 阿里云镜像源
sudo tee /etc/apt/sources.list <<-'EOF'
deb http://mirrors.aliyun.com/ubuntu/ noble main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ noble main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ noble-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ noble-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ noble-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ noble-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ noble-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ noble-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ noble-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ noble-backports main restricted universe multiverse
EOF
# 3. 安装 Docker
sudo apt update
sudo apt install docker.io
# 启动并设置开机自启
sudo systemctl enable docker --now
# 将当前用户加入 docker 组(需重新登录 SSH 才能永久生效)
sudo usermod -aG docker $USER
# 验证
docker --version
docker compose version
docker.io是 Docker 核心程序。newgrp docker仅在当前 shell 临时生效,重新登录 SSH 后docker组权限才会永久生效。
CentOS / RHEL
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl enable docker --now
sudo usermod -aG docker $USER
以上均使用阿里云镜像源,国内下载速度更快。
Docker 镜像加速(国内必配)
与上文 1.4.1 节配置相同,生产服务器同样需要。
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.unsee.tech",
"https://hub.uuuadc.top"
]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
2.2 常用命令
| 用途 | 命令 |
|---|---|
| 查看容器状态 | docker compose ps |
| 查看实时日志 | docker compose logs -f |
| 进入 PHP 容器 | docker exec -it gmm-php sh |
| 进入 MySQL | docker exec -it gmm-mysql mysql -uroot -proot general_management |
| 查看容器日志 | docker logs gmm-php -f |
| 重新构建 PHP | docker compose build php |
| 无缓存重建 | docker compose build --no-cache |
| 重新构建并启动 | docker compose up -d --build |
| 测试后端 | curl http://localhost:8000 |
| 手动执行备份 | docker exec gmm-mysql-backup backup.sh |
| 查看备份文件 | ls -lh docker/backup/ |
| 查看备份日志 | docker exec gmm-mysql-backup cat /var/log/backup.log |
| 进入备份容器 | docker exec -it gmm-mysql-backup sh |
2.3 注意事项
- 端口安全 — 容器端口均绑定
127.0.0.1,不暴露公网,由宿主机 Nginx 反代接入 - 前端开发 — 前端是微信小程序 uni-app,本地使用
npm run dev:mp-weixin,不运行在 Docker 中 - 热重载 — 后端代码通过 Volume 挂载,修改
backend/下的文件实时生效,无需重启容器 - PHP 扩展 — 编辑
docker/php/Dockerfile后执行docker compose build php重新构建 - 编辑 .env 文件 — Docker 配置在
.env;ThinkPHP 配置在backend/.env(从.env.example复制),两个文件都需正确配置 - 手动生成 init_database.sql — 表结构变更后更新初始化脚本:
docker exec gmm-mysql mysqldump -uroot -proot --no-data general_management > database/init_database.sql
2.4 Docker 目录结构
docker/ # Docker 配置目录
├── php/
│ ├── Dockerfile # PHP 镜像构建文件
│ └── php.ini # PHP 自定义配置
├── nginx/
│ ├── conf.d/
│ │ └── default.conf # Docker 内 Nginx 配置
│ ├── host-nginx-template.conf # 宿主机 HTTP 反代模板(阶段一)
│ ├── host-nginx-https-template.conf # 宿主机 HTTPS 反代模板(阶段二)
│ └── host-default-deny.conf # 宿主机默认阻断(拒绝未匹配域名)
├── backup/ # 数据库备份服务
│ ├── Dockerfile # 备份容器镜像
│ ├── backup.sh # 备份脚本
│ ├── restore.sh # 还原脚本
│ ├── entrypoint.sh # 容器入口
│ └── db_*.sql.gz # 自动生成的备份文件
└── README.md # 本文件
第三部分:生产环境部署
3.1 生产架构
浏览器 HTTPS ──→ 宿主机 Nginx (:80/:443) ← SSL 在这里终结
│
┌────────────┼────────────┐
▼ ▼ ▼
127.0.0.1:8000 127.0.0.1:9000 127.0.0.1:8080
[本项目 Docker] [其他项目A] [其他项目B]
纯 HTTP 通信 纯 HTTP 纯 HTTP
Docker 内所有服务只跑裸 HTTP,不碰 SSL 证书。SSL 统一在宿主机 Nginx 管理,一份泛域名证书覆盖所有子域名。
3.2 前置条件
- Linux 服务器(CentOS 7+ / Ubuntu 20.04+ / Debian 11+)
- root 或 sudo 权限
- Docker Engine 已安装(参考上方 2.1)
3.3 步骤 1:部署项目代码
scp -r ./ root@your-server:/var/www/general-member-management/
3.4 步骤 2:配置环境变量
# Docker Compose 环境变量
cp .env.example .env
nano .env # 修改 DB_PASS、NGINX_PORT 等
# ⚠️ 生产环境务必添加:BIND_ADDRESS=127.0.0.1
# ThinkPHP 后端配置
cp backend/.env.example backend/.env
nano backend/.env # DB_HOST=mysql, CACHE_HOST=redis
3.5 步骤 3:启动 Docker 服务
cd /var/www/general-member-management
docker compose up -d
docker compose ps # 验证
3.6 步骤 4:安装 ThinkPHP 依赖
docker exec -it gmm-php composer install --no-dev --optimize-autoloader
curl http://127.0.0.1:8000 # 验证
若部署前已在宿主机执行过
composer install,则vendor/目录已存在,容器启动后直接可用。
3.7 步骤 5:安装宿主机 Nginx
Docker 内的 Nginx 仅监听 127.0.0.1,需要宿主机安装 Nginx 统一反向代理并处理 SSL。
# CentOS / RHEL
sudo yum install -y nginx
# Ubuntu / Debian
sudo apt update && sudo apt install -y nginx
sudo systemctl enable nginx --now
3.8 步骤 6:配置宿主机 Nginx 反代
项目已提供配置模板,复制到 sites-available 并创建软链接启用:
sudo cp docker/nginx/host-nginx-template.conf /etc/nginx/sites-available/gmm.shouchunyun.cn.conf
sudo sed -i 's/YOUR_DOMAIN/gmm.shouchunyun.cn/g; s/YOUR_PORT/8000/g' /etc/nginx/sites-available/gmm.shouchunyun.cn.conf
sudo ln -s /etc/nginx/sites-available/gmm.shouchunyun.cn.conf /etc/nginx/sites-enabled/gmm.shouchunyun.cn.conf
sudo nginx -t && sudo nginx -s reload
3.9 步骤 7:申请 SSL 证书(推荐 acme.sh)
curl https://get.acme.sh | sh
source ~/.bashrc
# 以腾讯云 DNSPod 为例,前往 https://console.dnspod.cn/account/token/token 创建密钥
export DP_Id="你的DNSPod ID"
export DP_Key="你的DNSPod Token"
acme.sh --issue --dns dns_dp -d '*.shouchunyun.cn' -d shouchunyun.cn
# 安装证书到宿主机 Nginx
sudo mkdir -p /etc/nginx/ssl
sudo chown -R $USER:$USER /etc/nginx/ssl
~/.acme.sh/acme.sh --install-cert -d '*.shouchunyun.cn' \
--key-file /etc/nginx/ssl/privkey.key \
--fullchain-file /etc/nginx/ssl/fullchain.pem \
--reloadcmd "sudo nginx -s reload"
sudo chown root:root /etc/nginx/ssl/*
泛域名证书
*.shouchunyun.cn一份即可覆盖所有子域名。
部署默认阻断
防止不存在的子域名被路由到其他站点:
sudo cp docker/nginx/host-default-deny.conf /etc/nginx/sites-available/000-default-deny
sudo ln -s /etc/nginx/sites-available/000-default-deny /etc/nginx/sites-enabled/000-default-deny
sudo nginx -t && sudo nginx -s reload
000-开头确保 Nginx 优先将其作为default_server,不匹配的域名请求return 444直接关闭连接。
3.10 步骤 8:启用 HTTPS
sudo cp docker/nginx/host-nginx-https-template.conf /etc/nginx/sites-available/gmm.shouchunyun.cn.conf
sudo sed -i 's/YOUR_DOMAIN/gmm.shouchunyun.cn/g; s/YOUR_PORT/8000/g' /etc/nginx/sites-available/gmm.shouchunyun.cn.conf
sudo nginx -t && sudo nginx -s reload
两个模板区别:
host-nginx-template.conf纯 HTTP,host-nginx-https-template.confHTTPS 重定向 + SSL。
3.11 增加新站点
使用 sites-available/sites-enabled 模式管理:
# 启用新站点
sudo cp docker/nginx/host-nginx-https-template.conf /etc/nginx/sites-available/新域名.conf
sudo sed -i 's/YOUR_DOMAIN/新域名/g; s/YOUR_PORT/新端口/g' /etc/nginx/sites-available/新域名.conf
sudo ln -s /etc/nginx/sites-available/新域名.conf /etc/nginx/sites-enabled/新域名.conf
sudo nginx -t && sudo nginx -s reload
# 禁用站点(保留配置)
sudo rm /etc/nginx/sites-enabled/新域名.conf
sudo nginx -s reload
第四部分:数据库备份与还原
备份服务 mysql-backup 基于 Debian + MySQL 客户端,定时将数据库 dump 到宿主机磁盘。
4.1 备份服务说明
| 项目 | 说明 |
|---|---|
| ⏰ 执行时间 | 每 6 小时执行一次(北京时间,可自定义 cron 表达式) |
| 📦 备份方式 | mysqldump --single-transaction(保证数据一致性) |
| 🗜️ 压缩格式 | gzip 压缩 |
| 🗑️ 保留策略 | 最近 7 天,自动清理旧文件 |
| 🕐 时区 | Asia/Shanghai(北京时间 UTC+8) |
| 📂 存储位置 | ./docker/backup/db_库名_日期时间.sql.gz |
4.2 启动备份服务
docker compose up -d # 随所有服务一起启动
docker compose up -d --build mysql-backup # 单独构建启动
首次启动会立即执行一次备份,之后按定时任务自动执行。
4.3 手动操作
docker exec gmm-mysql-backup backup.sh # 立即备份
ls -lh docker/backup/ # 查看备份文件
docker exec gmm-mysql-backup ls -lh /backup/ # 容器内查看
4.4 自定义配置
编辑 docker-compose.yml 中 mysql-backup 服务的环境变量:
| 变量 | 默认值 | 说明 |
|---|---|---|
CRON_SCHEDULE | 0 */6 * * * | 备份周期(cron 表达式,北京时间) |
RETENTION_DAYS | 7 | 备份保留天数 |
TZ | Asia/Shanghai | 容器时区 |
cron 表达式示例:0 3 * * *(每天3点)、0 3,15 * * *(每天3点和15点)、0 */6 * * *(每6小时)、30 2 * * 0(每周日2:30)
4.5 还原数据库
推荐 — 通过备份容器还原:
docker exec -it gmm-mysql-backup sh
ls -lh /backup/ # 查看可用备份
restore.sh /backup/db_general_management_20260616_030000.sql.gz
快速 — 一句话还原(无确认):
docker exec gmm-mysql-backup sh -c \
"gunzip -c /backup/db_general_management_20260616_030000.sql.gz | \
mysql -h mysql -u root -p\${DB_PASS:-root} \${DB_NAME:-general_management}"
⚠️ 还原操作会覆盖数据库中的所有现有数据,请谨慎操作!
第五部分:日常使用 & 故障排查
5.1 WSL 日常操作
| 操作 | 命令 |
|---|---|
| 进入 Ubuntu | wsl(Windows 终端/PowerShell) |
| 退出 Ubuntu | exit 或 Ctrl+D |
| 关闭 WSL(省内存) | wsl --shutdown |
| 查看 WSL 状态 | wsl -l -v |
| 前端开发 | 在 Windows 终端用 npm run dev:mp-weixin |
Docker Desktop 用户:Docker 随 Desktop 应用自动启动,无需手动操作。若使用 Docker Engine(直接安装在 WSL 内),首次进入 Ubuntu 后需执行
sudo service docker start。
5.2 网络说明
推荐在 %USERPROFILE%\.wslconfig 中启用 mirrored 镜像网络模式:
- WSL Ubuntu 和 Windows 共享同一个 IP 地址
- 在 Windows 浏览器访问
http://localhost:8000即可访问 WSL 内的 Docker 服务 - 局域网内其他设备可通过 Windows 的局域网 IP 访问,例如
http://192.168.1.100:8000 - 不需要手动配置端口转发(
netsh interface portproxy)
如果未启用 mirrored 模式,WSL 有独立 IP,需用
wsl hostname -I查看 IP 后访问。
5.3 故障排查
Docker 无法连接
# Docker Desktop 用户:确保 Docker Desktop 正在运行(系统托盘图标)
# Docker Engine 用户:
sudo service docker status # 检查是否运行
sudo service docker start # 启动
端口无法访问
docker compose ps # 检查容器状态
docker compose logs nginx # 检查日志
WSL 内存占用过高
编辑 %USERPROFILE%\.wslconfig,调低 memory 值(如 2GB),然后 wsl --shutdown 重启。
DNS 解析失败
确保 %USERPROFILE%\.wslconfig 中已启用 dnsTunneling=true,若仍有问题,可手动指定国内 DNS:
sudo sh -c 'echo "nameserver 223.5.5.5" > /etc/resolv.conf'
223.5.5.5为阿里云公共 DNS,国内用户也可使用114.114.114.114。
文件性能慢
项目代码在 Windows 文件系统(/mnt/d/...)时,Docker Volume 跨文件系统挂载性能较差。可将项目 clone 到 WSL 内部文件系统:
cd ~
git clone <你的仓库地址> general-member-management
cd general-member-management
docker compose up -d
参考
- WSL 官方文档
- Docker Engine 安装指南
- docker/ 目录配置 — Nginx 模板、PHP Dockerfile、备份脚本