很多站长买回 VPS、装好宝塔或者 LNMP 一键包之后,网站都是手动一个一个部署的:装 Nginx、装 MySQL、装 PHP、传源码、配伪静态……每换一台服务器就要把所有流程重新走一遍,费时费力还容易出错。Docker 的出现把这套流程彻底简化了——环境被打包成镜像,配置写进一份 docker-compose.yml,一条命令就能把整套应用拉起来,换服务器也只是拷贝几个文件的事。
本文按真实操作顺序,把 Docker 从安装、基础命令、常用服务部署到数据持久化与备份迁移一次讲清楚。文章里的命令都经过验证,照着敲就能用,适合刚接触容器、想在 VPS 上用 Docker 管理网站的站长。
一、什么是 Docker,站长为什么要用它
简单理解,Docker 把应用和它依赖的环境(系统库、运行时、配置文件)一起打包成一个"镜像",运行时产生一个或多个"容器"。容器之间相互隔离,但共享宿主机的内核,所以比虚拟机更轻量,启动只要几秒钟。
对站长来说,Docker 最大的价值有三个:
- 环境一致:开发、测试、生产都用同一份镜像,不会出现"在我机器上好好的,到你服务器就不行"的问题。
- 部署简单:一个 docker-compose.yml 就能定义 Nginx、MySQL、PHP 等一整套服务,一条命令启动或停止。
- 迁移方便:换 VPS、换机房时,把镜像和数据打包带走,新机器上分钟级恢复。
二、在 VPS 上安装 Docker 与 Compose
目前主流 Linux 发行版都支持一键安装脚本,国内服务器建议先配置好 Docker 镜像加速源(阿里云、腾讯云容器镜像服务里都有免费的个人加速地址)。
# 一键安装 Docker(官方脚本) curl -fsSL https://get.docker.com | sh # 设置开机自启并查看版本 systemctl enable --now docker docker --version # 验证安装是否正常 docker run --rm hello-world
新版 Docker 自带 docker compose 插件,无需单独安装,检查一下即可:
docker compose version
如果服务器装有宝塔面板,也可以在软件商店里直接安装 Docker 管理器,界面化操作镜像和容器,适合不习惯敲命令的用户。
三、基础命令速览
先掌握最常用的几个命令,日常操作基本够用:
# 拉取镜像 docker pull nginx:latest # 查看本地镜像 / 运行中的容器 / 所有容器 docker images docker ps docker ps -a # 运行一个容器(-d 后台运行,-p 映射端口,--name 指定名字) docker run -d --name my-nginx -p 8080:80 nginx:latest # 查看日志 / 进入容器 docker logs -f my-nginx docker exec -it my-nginx bash # 停止 / 删除容器、删除镜像 docker stop my-nginx docker rm my-nginx docker rmi nginx:latest
命令里 -p 8080:80 的含义是把宿主机 8080 端口映射到容器内的 80 端口。VPS 开了什么端口、安全组放行什么端口,记得保持一致。
四、用 docker-compose 一键部署完整网站环境
单容器意义有限,真正的日常是"多服务编排"。下面用一份 docker-compose.yml 部署最常见的 Nginx + PHP + MySQL 网站环境,这也是大多数个人站点的标准组合。
version: "3"
services:
nginx:
image: nginx:1.27
container_name: web-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./www:/usr/share/nginx/html
- ./nginx/conf.d:/etc/nginx/conf.d
- ./cert:/etc/nginx/cert
depends_on:
- php
restart: always
php:
image: php:8.3-fpm
container_name: web-php
volumes:
- ./www:/var/www/html
restart: always
mysql:
image: mysql:8.0
container_name: web-mysql
environment:
MYSQL_ROOT_PASSWORD: "换成强密码"
MYSQL_DATABASE: "mydb"
MYSQL_USER: "myuser"
MYSQL_PASSWORD: "换成强密码"
volumes:
- mysql_data:/var/lib/mysql
restart: always
volumes:
mysql_data:
把文件保存为 docker-compose.yml,在同目录执行:
docker compose up -d docker compose ps
几个关键点:
- restart: always 让容器在服务器重启后自动拉起,网站不会因为宕机起不来。
- volumes 挂载 把宿主机目录映射进容器,网站源码直接放到宿主机 ./www 下管理,不用进容器改文件。
- 数据库数据存进命名卷 mysql_data,即使容器重建,数据也还在。
- depends_on 控制启动顺序,MySQL 先起,PHP 再起,Nginx 最后。
五、常用服务一条命令部署
很多常见服务官方都提供了镜像,部署几乎都是"拉镜像 + 写配置 + 起容器"三步:
# WordPress docker run -d --name wp -p 8080:80 \ -e WORDPRESS_DB_HOST=mysql \ -e WORDPRESS_DB_PASSWORD=密码 \ wordpress:php8.3-apache # 私有网盘 Nextcloud docker run -d --name nc -p 8090:80 \ -v nc_data:/var/www/html \ nextcloud:latest # 轻量代码托管 Gitea docker run -d --name gitea -p 3000:3000 \ -v gitea_data:/data \ gitea/gitea:latest
生产环境强烈建议配合 docker-compose 写完整配置(含数据库、备份卷、restart 策略),而不是直接 docker run,便于后期维护和迁移。
六、数据持久化:容器能删,数据不能丢
新手最容易踩的坑是:容器一删,里面的数据库、上传文件全没了。Docker 的容器是"无状态"的,任何写到容器内部文件系统的数据,容器删除后都会丢失。必须用挂载或卷把数据放到宿主机上:
- bind mount(目录挂载):把宿主机目录挂进容器,适合网站源码、证书等需要直接改的文件。
- named volume(命名卷):由 Docker 管理,存放数据库数据这类不适合直接碰的文件。
确认数据位置是否安全,用这条命令看容器挂载了哪些路径:
docker inspect 容器名 | grep -A2 Mounts
七、备份与迁移:把整套服务搬到新服务器
Docker 环境迁移比传统环境轻松很多,核心就两件事:搬镜像、搬数据。
第一步,备份数据。数据库用官方工具导出,挂载目录直接打包:
# 导出 MySQL 数据库 docker exec web-mysql sh -c \ 'exec mysqldump --all-databases -uroot -p"密码"' > backup.sql # 打包网站目录 tar czf www.tar.gz www/
第二步,在新服务器上安装 Docker,把 docker-compose.yml 和 www、backup.sql 拷贝过去,然后:
docker compose up -d docker exec -i web-mysql sh -c 'exec mysql -uroot -p"密码"' < backup.sql
至此网站就在新服务器上跑起来了。相比传统环境重装系统、逐项配置、拷库调权限,这套流程快得多,也更容易复现。
八、安全注意事项
容器不是保险箱,以下几点务必注意:
- 不要以 root 运行不必要的服务:官方镜像多数内置了降权用户,优先使用。
- 只拉官方或可信镜像:来历不明的镜像可能携带后门,用 Docker Hub 官方镜像或知名项目镜像。
- 端口不要全开:只在宿主机映射对外需要的端口,数据库端口尤其别暴露到公网。
- 及时更新镜像:定期 docker compose pull 并重建容器,补上安全漏洞。
- 敏感信息不入镜像:数据库密码这类配置用 .env 文件或环境变量注入,别写死在镜像里。
九、结语
Docker 把"装环境、部署、迁移"这几件最琐碎的运维事,压缩成了写配置文件和敲命令。对站长来说,学会 Docker 不是追新,而是把精力从重复劳动里解放出来,放到内容和服务本身。这篇覆盖了从安装到迁移的完整链路,照着走一遍,你的 VPS 管理能力会上一个台阶。
遇到容器起不来的情况,先用 docker compose logs 看日志,多数问题都能定位。也欢迎在评论区聊聊你踩过的坑。