零基础Docker建站实战:用容器在VPS上部署网站的保姆级教程


提起在VPS上建站,很多人的第一反应是:装Nginx、装MySQL、装PHP,然后对着教程改半天配置文件,环境冲突、版本不匹配、迁移服务器时又得重来一遍。Docker的出现彻底改变了这种苦日子:把网站和它依赖的一切打包进"容器",一条命令启动,一条命令销毁,换服务器就是复制粘贴的事。这篇文章从零开始,手把手带你用Docker在一台干净的VPS上部署一个完整的网站,全程不需要理解任何底层原理,照着敲就能跑通。

一、为什么建站要选Docker

先用三个真实场景说明问题:

场景一:你在服务器A上折腾好了环境,某天要迁移到服务器B。传统方式得把所有配置重做一遍,漏一个参数网站就白屏。Docker方式:打包镜像或导出compose文件,新机器上一条命令满血复活。

场景二:你想同时跑一个PHP 7.4的老站和一个PHP 8.2的新站。传统方式下多版本PHP共存能把人折腾疯,而每个容器有独立的运行环境,互不干扰。

场景三:网站被黑了,环境被污染。传统方式排查清理遥遥无期,容器方式:删掉容器重建,30秒恢复如初,数据还在数据卷里安全无恙。

一句话总结:Docker把"环境"本身变成了可管理的文件,这是它对建站用户最大的价值。

二、安装Docker环境

以Ubuntu/Debian为例,使用官方脚本一键安装:

# 更新软件源
sudo apt update
# 安装依赖
sudo apt install -y ca-certificates curl gnupg
# 使用官方安装脚本
curl -fsSL https://get.docker.com | sudo sh
# 启动并设置开机自启
sudo systemctl enable --now docker
# 验证安装
sudo docker run hello-world

看到"Hello from Docker!"的输出就说明装好了。

顺手装上Docker Compose(新版已作为插件内置,无需单独安装):

docker compose version
# 能打印版本号即可,如 Docker Compose version v2.x.x

再设置当前用户免sudo使用docker(可选但强烈推荐,省得每条命令都敲sudo):

sudo usermod -aG docker $USER
# 重新登录SSH后生效

三、三个核心概念,一分钟讲明白

不需要啃文档,记住这三样就够了:

  • 镜像(Image):网站的"安装包",只读模板。比如wordpress镜像里装好了PHP和WordPress程序
  • 容器(Container):镜像跑起来的"进程",一个镜像可以开多个容器。容器删了就没了,但镜像还在,随时重开
  • 数据卷(Volume):容器之外的"硬盘"。容器随时可抛弃,但数据库文件、上传的图片这些重要数据必须放在数据卷里持久化

打个比方:镜像是菜谱,容器是按菜谱炒出来的一盘菜,数据卷是保鲜盒——菜吃完可以再炒,保鲜盒里的东西不受影响。

四、第一个容器:30秒跑起一个网站

先来个最简单的,感受一下容器的威力:

docker run -d -p 8080:80 --name mysite httpd:alpine

解释一下这条命令:

  • -d:后台运行
  • -p 8080:80:把服务器的8080端口映射到容器内的80端口
  • --name mysite:给容器起个名字,方便管理
  • httpd:alpine:Apache的精简版镜像,只有约40MB

现在浏览器访问 http://你的服务器IP:8080,能看到"It works!"页面。就这么快,没有安装Apache,没有改配置文件。

常用管理命令:

docker ps              # 查看运行中的容器
docker ps -a           # 查看所有容器(含已停止)
docker stop mysite     # 停止
docker start mysite    # 再次启动
docker rm mysite       # 删除容器(数据在卷里不受影响)
docker logs mysite     # 查看日志排错

五、实战:用Docker Compose部署一个完整博客

单个容器只是热身,真实网站是"多容器协作":Web程序一个容器、数据库一个容器。Docker Compose就是用来编排这种多容器组合的。我们在一个目录里写一个compose文件,描述整个网站,然后一条命令全部启动。

创建项目目录并编辑:

mkdir -p ~/myblog && cd ~/myblog
nano docker-compose.yml

写入以下内容:

services:
  app:
    image: wordpress:latest
    restart: always
    ports:
      - "80:80"
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: wpuser
      WORDPRESS_DB_PASSWORD: 换成你的强密码
      WORDPRESS_DB_NAME: wordpress
    volumes:
      - wp_data:/var/www/html
    depends_on:
      - db

  db:
    image: mysql:8.0
    restart: always
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wpuser
      MYSQL_PASSWORD: 换成你的强密码
      MYSQL_ROOT_PASSWORD: 换成root的强密码
    volumes:
      - db_data:/var/lib/mysql

volumes:
  wp_data:
  db_data:

这个文件描述了一个标准博客架构:WordPress容器对外提供80端口服务,MySQL容器只被WordPress内部访问,两个数据卷分别保存网站文件和数据库。

启动:

docker compose up -d

第一次会拉取镜像,耐心等一两分钟。完成后访问 http://你的服务器IP,就是熟悉的WordPress安装界面。整个过程没有碰过一次php.ini,没有装过一次MySQL。

六、反向代理:一个VPS跑多个网站的姿势

实际使用中你大概率不止一个网站,或者需要HTTPS。这时候需要一个反向代理统一接管80/443端口,按域名把流量转发给不同容器。推荐用Nginx Proxy Manager(NPM),带Web管理界面,鼠标点点就能配好自动续期的SSL证书。

mkdir -p ~/proxy && cd ~/proxy
nano docker-compose.yml

写入:

services:
  npm:
    image: jc21/nginx-proxy-manager:latest
    restart: always
    ports:
      - "80:80"
      - "443:443"
      - "81:81"
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt

启动后访问 http://服务器IP:81,默认账号 admin@example.com / changeme(首次登录强制改密码)。

使用方法:把你的域名A记录解析到服务器IP,在NPM里添加Proxy Host,域名填blog.example.com,转发目标填你博客容器的内网地址:端口,再在SSL标签页申请Let's Encrypt证书,勾选Force SSL。一个带HTTPS的网站就配好了。

注意一个细节:多个网站共用80端口时,只有NPM监听80/443,其他网站容器不要再用ports映射80端口,改用内部网络+expose,避免端口冲突。

七、数据备份:容器化了更要会备份

容器"随用随抛"的特性让人容易忽略数据安全。其实Docker的备份比传统方式更简单——数据都在卷里,备份卷就行。

备份数据库卷的通用方法:

# 方法一:mysqldump逻辑备份(推荐,通用性最好)
docker exec 容器名 mysqldump -uwpuser -p密码 wordpress \
  | gzip > backup_$(date +%F).sql.gz

# 方法二:直接打包数据卷目录
docker run --rm -v db_data:/data -v $(pwd):/backup \
  alpine tar czf /backup/db_data.tar.gz /data

把备份命令放进crontab每天自动执行,再用rclone把备份文件同步到对象存储或另一台服务器,就是一套完整的容灾方案。备份不是本文重点,展开可以写一整篇,记住核心原则:没做过恢复演练的备份等于没备份。

八、常用命令速查表

把这几条贴在备忘录里,日常管理够用了:

docker compose up -d          # 启动/更新整个项目
docker compose pull           # 拉取最新镜像
docker compose up -d          # 再次up即用新镜像重建容器
docker compose down           # 停止并删除所有容器(卷保留)
docker compose logs -f app    # 实时查看app容器日志
docker stats                  # 查看各容器CPU/内存占用
docker system df              # 查看磁盘占用
docker system prune -a        # 清理无用镜像释放磁盘

其中docker system prune -a要慎用,它会删掉所有未被使用的镜像,下次启动要重新拉取。磁盘紧张时再用。

九、新手避坑指南

最后是几条用血泪换来的经验:

  • 镜像一定要锁定具体版本:wordpress:latest今天可能是8.2,下个月悄悄变成8.3,行为变了都不知道哪出问题。生产环境写wordpress:6.4-php8.2这样的明确版本号
  • 重要数据必须放卷里:直接写进容器文件系统的东西,容器一删就没。第一次部署就规划好volumes
  • 端口映射冲突:80被宿主机Nginx占了容器就起不来,报"port is already allocated",先docker ps看看谁占着
  • 内存别抠太死:MySQL容器默认内存配置偏大,1G小鸡跑WordPress全家桶建议给MySQL加限制参数,或者换更轻的SQLite方案
  • 别用root跑一切:容器天然隔离,但MySQL密码、环境变量里的密钥还是走.env文件管理,别硬编码进compose文件传到公开仓库

十、写在最后

Docker的学习曲线在前半小时,之后全是甜头。这篇教程覆盖了从安装、概念、部署到运维的完整链路,跟着做完你应该已经拥有一个容器化的HTTPS网站。下一步可以研究CI/CD自动化部署、容器监控(如哪吒探针、Uptime Kuma)这些进阶玩法。

建站路上最大的敌人不是技术,是"配置好就再也不敢动"的恐惧。容器给了你随意折腾的底气——反正坏了就重建,怕什么。祝部署顺利,有问题欢迎评论区交流。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

5款轻量级开源建站程序推荐:低配VPS也能流畅建站的宝藏源码

小内存VPS生存指南:512M"小鸡"也能跑得飞起的系统优化全攻略

评 论