站长必备:用 Docker 搭建稳定、易迁移的生产环境指南
Docker 生产环境部署指南|适合站长
对于站长来说,服务器环境的稳定性、可维护性和迁移便利性,往往直接影响网站的长期运营质量。过去部署网站时,我们通常需要手动安装 Nginx、PHP、MySQL、Redis、Node.js 等组件,还要处理版本冲突、依赖缺失、环境差异、权限配置等问题。一旦服务器迁移,整个环境往往需要重新搭建,耗时又容易出错。
Docker 的出现,很大程度上解决了这些痛点。它可以把应用及其依赖封装到容器中,让网站在不同服务器上拥有高度一致的运行环境。无论你运营的是 WordPress、Typecho、Halo、Laravel、Django、Node.js 项目,还是自建 API 服务,Docker 都能让部署、升级、备份、迁移变得更加清晰和可控。
本文面向站长,重点讲解如何在生产环境中合理使用 Docker 部署网站,并给出实用的目录规划、服务编排、安全建议、备份方案和运维经验。
一、为什么站长适合使用 Docker?
很多站长一开始接触 Docker,会觉得它比传统部署更复杂。实际上,Docker 的优势并不体现在第一次部署有多快,而是体现在长期维护中。
1. 环境一致,减少“换服务器就出问题”
传统方式中,你在 A 服务器上安装的是 PHP 8.1,在 B 服务器上可能装成 PHP 8.2;A 服务器 MySQL 配置不同,B 服务器扩展又缺失。迁移后网站报错,排查起来非常麻烦。
使用 Docker 后,应用运行在容器中,依赖版本写在镜像或配置文件里。只要 Docker 和配置文件一致,换服务器后基本可以复现原环境。
2. 部署清晰,服务之间互不污染
站长经常会在一台服务器上运行多个网站,例如一个 WordPress 博客、一个导航站、一个图床、一个监控面板。如果全部直接安装在系统中,不同项目依赖可能互相冲突。
Docker 可以为每个项目创建独立容器。一个网站使用 PHP 7.4,另一个网站使用 PHP 8.2,也可以共存,不必担心系统环境被污染。
3. 升级和回滚更方便
生产环境最怕升级失败。传统方式升级 MySQL、PHP 或应用时,如果没有完整备份,回滚会很麻烦。
Docker 部署通常可以通过替换镜像版本完成升级。如果新版本出现问题,可以快速切回旧版本镜像。只要数据卷和备份策略合理,风险会大大降低。
4. 迁移简单,适合长期运营
很多站长会遇到服务器到期、线路不稳定、云厂商涨价等情况。Docker 项目通常只需要迁移以下内容:
docker-compose.yml- 环境变量文件
- 网站代码
- 数据目录
- 配置文件
- 数据库备份
迁移后重新执行启动命令,网站即可恢复运行。
二、生产环境部署前的准备
在正式部署前,不建议直接复制网上的命令就运行。生产环境需要考虑系统版本、目录规划、安全策略和备份机制。
1. 选择稳定的服务器系统
推荐使用长期支持版本的 Linux 系统,例如:
- Ubuntu 22.04 LTS / 24.04 LTS
- Debian 12
- Rocky Linux 9
- AlmaLinux 9
对于大多数站长,Ubuntu LTS 或 Debian 是更省心的选择,社区资料多,Docker 支持成熟。
2. 更新系统并安装基础工具
部署前建议先更新系统:
sudo apt update && sudo apt upgrade -y
安装常用工具:
sudo apt install -y curl wget vim git ufw htop unzip ca-certificates
这些工具在后续下载文件、查看日志、编辑配置、排查问题时都会用到。
3. 安装 Docker 与 Docker Compose
推荐使用 Docker 官方安装方式,而不是系统默认源中的旧版本。
curl -fsSL https://get.docker.com | sudo sh
安装完成后查看版本:
docker version
docker compose version
如果你希望普通用户也能执行 Docker 命令,可以加入 docker 用户组:
sudo usermod -aG docker $USER
然后重新登录终端。
注意:加入
docker组的用户相当于拥有较高权限,只应给可信用户使用。
三、推荐的生产目录结构
生产环境中,目录结构非常重要。目录混乱会导致后期备份、迁移、排查都变得困难。
推荐使用如下结构:
/opt/docker/
├── nginx/
│ ├── docker-compose.yml
│ ├── conf.d/
│ ├── certs/
│ └── logs/
├── mysql/
│ ├── docker-compose.yml
│ └── data/
├── redis/
│ ├── docker-compose.yml
│ └── data/
├── sites/
│ ├── example.com/
│ │ ├── docker-compose.yml
│ │ ├── app/
│ │ ├── data/
│ │ └── .env
│ └── blog.example.com/
└── backups/
这样的目录规划有几个好处:
- 每个服务独立管理,方便定位问题
- 数据目录集中,便于备份
- 配置文件清晰,迁移时不容易遗漏
- 多站点部署时结构统一,后期维护成本低
如果你只有一个网站,也可以将 Nginx、数据库和应用写在同一个 docker-compose.yml 中。但如果你打算长期运行多个站点,建议从一开始就规划好目录。
四、使用 Docker Compose 管理服务
生产环境不建议使用一长串 docker run 命令部署服务,因为参数太多,不便维护。更推荐使用 Docker Compose。
Docker Compose 可以用一个 YAML 文件描述多个容器、网络、端口、数据卷和环境变量。例如,一个简单的网站可能包含:
- Web 应用容器
- MySQL 数据库容器
- Redis 缓存容器
- Nginx 反向代理容器
启动时只需要:
docker compose up -d
停止服务:
docker compose down
查看日志:
docker compose logs -f
重启服务:
docker compose restart
相比零散命令,Compose 文件更适合长期维护,也更适合备份和迁移。
五、反向代理与 HTTPS 配置
生产环境网站通常需要通过 Nginx、Caddy 或 Traefik 暴露到公网。对于站长来说,最常见方案是:
- Nginx 负责反向代理
- Certbot 或 acme.sh 负责申请 SSL 证书
- 后端应用运行在 Docker 内部网络中
1. 为什么不要直接暴露所有容器端口?
很多教程会把 MySQL、Redis、应用端口直接映射到公网,例如:
ports:
- "3306:3306"
这在生产环境中非常危险。数据库和缓存服务一般不应该暴露到公网,只应在 Docker 内部网络访问。
更推荐的方式是:
- 只有 Nginx 暴露
80和443 - 应用容器只在内部网络提供服务
- MySQL、Redis 不映射公网端口
这样可以显著减少攻击面。
2. Nginx 反向代理示例
假设应用容器名称为 site_app,内部端口为 3000,Nginx 可以这样配置:
server {
listen 80;
server_name example.com www.example.com;
location / {
proxy_pass http://site_app:3000;
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;
}
}
如果启用 HTTPS,则需要添加 SSL 证书配置,并将 HTTP 自动跳转到 HTTPS。
六、数据卷:生产环境的核心
Docker 容器本身是可以随时删除和重建的,真正重要的是数据。对于站长来说,以下内容必须持久化:
- 数据库数据
- 网站上传文件
- 用户生成内容
- 配置文件
- SSL 证书
- 日志文件
不要把重要数据只保存在容器内部。如果容器删除,内部数据可能一起丢失。
1. 推荐使用绑定挂载
生产环境中,站长更容易理解和备份的是绑定挂载,例如:
volumes:
- ./data/mysql:/var/lib/mysql
- ./app/uploads:/app/uploads
这样数据会明确保存在宿主机目录中,备份时直接打包相关目录即可。
2. 数据库目录要谨慎操作
MySQL、PostgreSQL 这类数据库的数据目录不能随意复制热备份。正在运行时直接打包数据库目录,可能得到不一致的数据。
更推荐使用数据库自带工具导出:
docker exec mysql mysqldump -uroot -p database_name > backup.sql
对于 PostgreSQL:
docker exec postgres pg_dump -U username database_name > backup.sql
如果站点数据量较大,可以结合定时任务、对象存储和异地备份。
七、环境变量与敏感信息管理
很多 Docker 项目会使用 .env 文件保存配置,例如数据库密码、管理员邮箱、密钥等。
示例:
MYSQL_DATABASE=site_db
MYSQL_USER=site_user
MYSQL_PASSWORD=strong_password_here
MYSQL_ROOT_PASSWORD=another_strong_password
生产环境中需要注意:
- 不要使用弱密码
- 不要把
.env文件公开到网站目录 - 不要提交到公开 Git 仓库
- 不要在文章、截图、日志中泄露密钥
- 定期更换重要密码
如果你的服务器上有多个用户,还应限制配置文件权限:
chmod 600 .env
这样可以降低敏感信息泄露风险。
八、防火墙与端口安全
Docker 部署不等于安全部署。站长必须重视服务器端口管理。
1. 常见端口建议
一般网站服务器只需要开放:
22:SSH,建议改端口或限制 IP80:HTTP443:HTTPS
如果使用宝塔、1Panel、Portainer 等面板,还要额外注意面板端口安全,最好限制访问 IP,不要直接暴露给所有人。
2. 使用 UFW 配置防火墙
Ubuntu / Debian 可以使用 UFW:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status
如果你修改了 SSH 端口,一定要先放行新端口,再关闭旧端口,避免把自己锁在服务器外。
3. 不要公开数据库端口
除非你非常明确地知道自己在做什么,否则不要将以下端口暴露到公网:
- MySQL:
3306 - PostgreSQL:
5432 - Redis:
6379 - MongoDB:
27017 - Elasticsearch:
9200
很多服务器被入侵,都是因为数据库或 Redis 没有鉴权或弱密码,并且直接暴露在公网。
九、日志管理与问题排查
生产环境一定要会看日志。Docker 中常用命令如下:
查看所有容器:
docker ps
查看某个项目日志:
docker compose logs -f
查看指定服务日志:
docker compose logs -f app
查看容器资源占用:
docker stats
进入容器内部:
docker exec -it container_name sh
如果容器中有 Bash,也可以使用:
docker exec -it container_name bash
站长常见问题包括:
- 容器不断重启
- 数据库连接失败
- 反向代理 502
- SSL 证书过期
- 磁盘空间不足
- 权限不足导致上传失败
- 镜像版本升级后兼容性问题
遇到问题时,不要盲目重装。正确排查顺序一般是:
- 查看容器是否运行
- 查看容器日志
- 查看 Nginx 反向代理日志
- 检查端口和网络
- 检查环境变量
- 检查数据目录权限
- 回退到上一个可用版本
十、备份策略:站长必须重视
没有备份的生产环境是不完整的。无论 Docker 多方便,都不能代替备份。
1. 至少备份哪些内容?
对于一个典型网站,至少需要备份:
- 数据库导出文件
- 上传文件
docker-compose.yml.env文件- Nginx 配置
- SSL 证书
- 应用配置文件
如果你使用 WordPress,那么数据库和 wp-content/uploads 尤其重要。如果你使用 Halo、Typecho、Discuz、Nextcloud 等程序,也要明确哪些目录保存用户数据。
2. 备份频率建议
根据网站更新频率制定备份策略:
- 个人博客:每天或每周备份一次
- 内容站:每天备份一次
- 电商或会员站:每天多次备份
- 重要业务站:实时或准实时备份
备份不要只保存在本机。服务器硬盘损坏、误删目录、被入侵加密,都可能导致本机备份不可用。建议至少保留一份异地备份,例如对象存储、另一台服务器、本地 NAS 或云盘。
3. 定期测试恢复
很多人以为有备份就安全,直到真正恢复时才发现备份文件损坏、缺少配置或密码忘记了。
建议定期在测试服务器上演练恢复流程,确认:
- 数据库可以导入
- 上传文件完整
- 配置文件可用
- 容器可以正常启动
- 域名切换后网站可访问
备份的价值不在于“生成了文件”,而在于“能成功恢复”。
十一、镜像版本管理
生产环境不要盲目使用 latest 标签。很多镜像的 latest 会随着时间变化,如果重新拉取镜像,可能直接升级到不兼容版本。
不推荐:
image: mysql:latest
推荐:
image: mysql:8.0
或者更精确:
image: mysql:8.0.36
对于核心服务,例如 MySQL、PostgreSQL、Redis、Elasticsearch,版本升级前必须阅读官方升级说明,并提前备份数据。
应用类镜像也一样。升级前建议:
- 备份数据库和数据目录
- 查看更新日志
- 在测试环境验证
- 低峰期执行升级
- 观察日志和访问状态
- 保留回滚方案
十二、容器资源限制与稳定性
如果一台服务器运行多个容器,建议设置资源限制,避免某个服务占满 CPU 或内存,影响整台服务器。
Compose 中可以配置内存限制,具体写法会因 Compose 版本和运行模式略有差异。对于普通站长,至少要养成观察资源的习惯:
docker stats
同时也要关注宿主机:
df -h
free -m
htop
生产环境中,磁盘满是非常常见的问题。日志无限增长、数据库膨胀、备份文件堆积,都可能导致磁盘耗尽。磁盘满后,数据库可能无法写入,网站可能报错,甚至服务无法启动。
建议定期清理无用镜像:
docker image prune
谨慎清理无用资源:
docker system prune
执行清理前要确认不会删除仍需使用的数据卷。对于生产环境,不建议随手执行带 --volumes 的清理命令,除非你非常确定后果。
十三、更新与发布流程
站长在生产环境更新网站时,最好形成固定流程,而不是想到什么做什么。
推荐流程如下:
- 查看当前运行状态
- 备份数据库和数据目录
- 记录当前镜像版本
- 拉取新镜像或更新代码
- 重启服务
- 查看日志
- 测试前台和后台功能
- 如果异常,快速回滚
常用命令:
docker compose pull
docker compose up -d
docker compose logs -f
如果你的网站是自己开发的项目,建议使用 CI/CD 或至少使用 Git 管理代码。不要直接在服务器上手动改大量代码,否则后期难以追踪变更。
十四、常见部署模式
1. 单站点一体化部署
适合小型网站或个人博客。一个 docker-compose.yml 中包含应用、数据库、缓存和反向代理。
优点是简单直观,迁移方便。缺点是多个网站共用能力较弱。
2. 公共 Nginx + 多站点应用
适合一台服务器部署多个站点。Nginx 作为公共入口,每个站点独立运行自己的应用和数据库。
优点是结构清晰,扩展方便。缺点是初期配置稍复杂。
3. 面板化 Docker 管理
一些站长喜欢使用 1Panel、Portainer、宝塔 Docker 管理器等工具。这类工具可以降低操作门槛,但不要完全依赖图形界面。你仍然应该理解 Compose 文件、数据卷、端口映射和日志查看。
面板适合辅助管理,但核心配置最好能用文件形式保存,便于迁移和恢复。
十五、生产环境安全建议
最后,总结一些非常实用的安全建议:
- 使用强密码,尤其是数据库、后台、SSH
- SSH 禁止 root 密码登录,优先使用密钥
- 只开放必要端口
- 数据库和 Redis 不暴露公网
- 后台地址增加访问限制或二次验证
- 定期更新系统安全补丁
- 不使用来历不明的镜像
- 不在容器中保存明文敏感文件到公开目录
- 定期检查登录日志和容器日志
- 重要站点启用异地备份
- 升级前先备份,升级后看日志
Docker 让部署更标准化,但不会自动让系统变安全。安全来自合理配置、最小暴露、及时更新和持续监控。
十六、适合站长的最佳实践清单
如果你不想记太多细节,可以直接参考下面这份清单:
- 使用
docker compose管理项目 - 生产镜像固定版本,不使用
latest - 应用、数据库、上传文件全部持久化
- 只让 Nginx 或 Caddy 暴露公网端口
- MySQL、Redis 等服务仅限内部网络访问
.env文件保存敏感配置并限制权限- 每个站点使用独立目录
- 定期导出数据库备份
- 备份文件至少保留一份异地副本
- 升级前备份,升级后检查日志
- 定期清理无用镜像和旧备份
- 使用防火墙限制端口
- 定期测试备份恢复流程
结语
Docker 非常适合站长用于生产环境部署,但前提是使用方式要规范。它不是简单地把传统命令换成容器命令,而是一套更清晰的服务管理方式:用镜像固定运行环境,用 Compose 描述服务结构,用数据卷保存核心数据,用反向代理统一入口,用备份和版本控制降低风险。
对于个人站长和中小网站来说,Docker 的最大价值在于降低长期维护成本。服务器迁移、环境重建、版本升级、多站点共存,这些过去很容易让人头疼的问题,在 Docker 体系下都可以变得更加可控。
如果你刚开始使用 Docker,建议先从一个非核心站点或测试环境练手,熟悉 Compose、日志、数据卷、网络和备份流程。等你真正理解“容器可以重建,数据必须保护”这句话后,再将重要网站迁移到 Docker 生产环境中。
一个稳定的网站,不只是能跑起来,更要能备份、能恢复、能升级、能迁移、能排错。Docker 正是帮助站长实现这些目标的高效工具。