很多站长第一次接触 Docker,多半是被"容器化部署很省事"这句话吸引,可真到自己上手,又被镜像、容器、数据卷、端口映射这一堆概念绕得晕头转向。买一台 VPS,装了宝塔或者一键环境,网站确实能跑起来,可一旦要换服务器、升级环境、迁移多套应用,就会发现传统方式维护起来越来越吃力。这篇文章按真实操作顺序,把 Docker 部署网站从安装、拉镜像、跑容器,到域名接入、HTTPS、开机自启和日常维护一次讲清,照着做就能把网站平滑迁进容器,往后搬家、备份、扩容都轻松一大截。
一、为什么推荐用 Docker 部署
传统部署方式里,环境是装在服务器上的:PHP、MySQL、Nginx 一个个装,版本还要小心别冲突。换一台机器,这套环境得从头再装一遍,装完还得排查各种差异。Docker 的思路是把"应用 + 它需要的环境"打包成一个镜像,哪里都能一键运行。好处很实在:环境一致,本地能跑的生产基本也能跑;隔离干净,多套应用互不干扰;迁移方便,镜像打包即走;回滚简单,换回旧镜像就还原。对个人站长来说,最直观的感受就是:换服务器不再是一场灾难,而是一次几分钟的操作。
二、安装 Docker
大部分 VPS 都是 CentOS、Debian 或 Ubuntu。这里用官方脚本安装,最快也最不容易出错:
curl -fsSL https://get.docker.com | bash -s docker
装完先启动并设置开机自启:
systemctl enable docker && systemctl start docker
验证是否安装成功:
docker version
能正常显示 Client 和 Server 版本信息,就说明装好了。顺手把常用组件补齐:
apt install docker-compose -y
三、跑起第一个容器:Nginx
先拉取镜像再启动,一步到位:
docker run -d --name web -p 8080:80 nginx
命令拆开看:-d 表示后台运行,--name web 给容器起个名字,-p 8080:80 把宿主机的 8080 端口映射到容器内的 80 端口。浏览器访问 http://你的IP:8080,看到 Nginx 欢迎页就说明第一个容器跑起来了。
不过直接这么跑,配置文件和网站文件都写死在容器里,容器一删就什么都没了。正式部署要把文件和配置"挂"出来,用数据卷:
docker run -d --name web -p 8080:80 -v /www/web:/usr/share/nginx/html:ro -v /www/nginx/conf:/etc/nginx/conf.d:ro nginx
-v 把宿主机目录挂载进容器,宿主机改文件,容器立刻生效,备份也方便。
四、用 docker-compose 编排多服务
一个网站往往不止一个容器:Nginx、PHP、MySQL、Redis。一个个手动 docker run 太麻烦,用 docker-compose 一个文件管全部。新建 /www/docker-compose.yml:
version: '3'
services:
nginx:
image: nginx
ports:
- "80:80"
- "443:443"
volumes:
- /www/web:/usr/share/nginx/html
- /www/nginx/conf:/etc/nginx/conf.d
restart: always
php:
image: php:8.2-fpm
volumes:
- /www/web:/var/www/html
restart: always
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: 你的密码
volumes:
- /www/mysql:/var/lib/mysql
restart: always
然后在 /www 目录执行:
docker-compose up -d
一条命令,三套服务全部拉起。以后想停就 docker-compose down,想重启某个服务就 docker-compose restart nginx,所有配置都在这一个文件里,清清楚楚。
五、数据持久化:容器可以删,数据不能丢
容器是"一次性"的,删了重建很常见,但数据库和网站文件绝不能跟着丢。持久化就靠数据卷:上面配置里 -v /www/mysql:/var/lib/mysql 就是把 MySQL 的数据目录映射到宿主机,容器再删再建,数据都还在。写代码之前先想清楚:哪些目录必须持久化?数据库目录、上传目录、配置目录,这三类基本都要挂出来。养成这个习惯,Docker 才真正敢用在生产环境。
六、接入域名和 HTTPS
容器里的服务都跑在自定义端口上,对外还得回到 80/443。最常规的做法是把 80/443 交给宿主机的 Nginx 或容器里的 Nginx 做反向代理,把域名流量转发到对应容器。在 nginx 的 conf.d 里新建一个站点配置:
server {
listen 80;
server_name www.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
证书直接用免费的 Let's Encrypt,一条命令签发,自动续期也一起配好:
certbot --nginx -d www.example.com
配完刷新,地址栏的小绿锁就来了。整站从 http 升级到 https,对收录和信任度都有好处。
七、开机自启与日常维护
服务器重启后容器要能自己回来,每个容器都加上 restart: always 即可(docker-compose 文件里已经写了)。日常维护常用命令记这几个:
docker ps # 查看运行中的容器
docker logs -f web # 看某个容器的日志
docker exec -it web bash # 进容器操作
docker-compose up -d # 应用配置变更并重启
docker image prune -f # 清理无用镜像
给镜像打了新版本,想升级也很简单:拉新镜像,重建容器,两分钟完成。
八、常见的坑与排错
权限问题:容器内进程默认是 root,宿主机挂载目录权限不对会导致写入失败,目录先 chown 到合适用户再挂。端口冲突:80/443 被宝塔或系统 Nginx 占了,容器端口映射就会起不来,先停掉占用服务的监听。时区问题:容器默认是 UTC,数据库和日志时间会差八小时,启动时加 -e TZ=Asia/Shanghai。网络问题:不同 compose 项目容器间互访要用自定义 network,别指望默认 bridge 直连。
结语
Docker 部署看着概念多,真正跑通一次,后面全是红利:换服务器、做备份、开多站、回滚版本,都比传统方式省心得多。建议先用一台闲置 VPS 拿测试站练手,把上面的流程完整走一遍,再考虑把正式站迁进去。按这套流程把基础打牢,你的网站在服务器这块,基本就能高枕无忧了。