Docker 部署网站实战:安装、镜像、容器、数据卷与 Compose 一次讲清


很多站长第一次接触 Docker 时,会把它和虚拟机混为一谈。实际上 Docker 不虚拟硬件,只隔离进程,所以启动一个容器通常只要一两秒,占用内存也小得多。对只有 2 核 2G 的 VPS 来说,用 Docker 把 Nginx、PHP、MySQL 拆成独立容器,既方便升级,也方便迁移。这篇文章按实际操作顺序,从安装到用 Compose 跑起一个完整站点,把容易踩的坑一次讲清楚。

一、Docker 适合什么场景

Docker 最大的价值是环境一致性:本地跑得起来的镜像,换一台服务器同样能跑,不用再为 PHP 版本、扩展、依赖库折腾半天。适合的场景包括多站点隔离、快速回滚、迁移服务器,以及同一台机器上跑多个不同版本的服务。

但如果你的站点只有一个 WordPress,服务器配置也够用,直接装宝塔或 LNMP 反而更简单。Docker 带来便利的同时,也多了一层网络和存储的抽象,出问题时需要多看一层日志。

二、安装 Docker 与配置镜像加速

主流 Linux 发行版用官方脚本安装最省事:

curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
docker version
docker compose version

国内机器拉取镜像经常卡住,需要配置加速地址。新建或编辑 /etc/docker/daemon.json:

{
  "registry-mirrors": ["https://docker.1ms.run", "https://docker.xuanyuan.me"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "50m",
    "max-file": "3"
  }
}

然后执行 systemctl daemon-reload && systemctl restart docker 生效。日志大小限制一定要加,否则某个容器疯狂写日志,几天就能把系统盘写满。

三、镜像、容器、数据卷别搞混

  • 镜像(image):只读模板,相当于装系统用的 ISO,本身不产生数据。
  • 容器(container):镜像运行起来的实例,容器删除后,写在容器内部的数据会一起消失。
  • 数据卷(volume):独立于容器存在的存储,删容器不影响数据,是生产环境必须用的东西。
  • 端口映射:-p 8080:80 表示访问宿主机 8080 端口,转发到容器内的 80 端口。

四、跑一个 Nginx 静态站

mkdir -p /data/www /data/nginx/conf.d /data/nginx/logs
docker run -d --name nginx \
  -p 80:80 -p 443:443 \
  -v /data/www:/usr/share/nginx/html:ro \
  -v /data/nginx/conf.d:/etc/nginx/conf.d:ro \
  -v /data/nginx/logs:/var/log/nginx \
  --restart unless-stopped \
  nginx:1.27-alpine

几个参数值得注意:--restart unless-stopped 让容器跟随 Docker 服务自启;挂载网站目录和配置目录,改完执行 docker exec nginx nginx -s reload 即可生效;alpine 版本体积小、攻击面也小。

不要把网站文件 COPY 进镜像。代码一改就要重新构建,既慢又容易丢数据。镜像只放运行环境,代码和数据一律挂载。

五、MySQL 容器化:数据卷是底线

docker run -d --name mysql \
  -e MYSQL_ROOT_PASSWORD=换成强密码 \
  -e MYSQL_DATABASE=wordpress \
  -v /data/mysql:/var/lib/mysql \
  -p 127.0.0.1:3306:3306 \
  --restart unless-stopped \
  mysql:8.4 \
  --character-set-server=utf8mb4 \
  --collation-server=utf8mb4_unicode_ci

两个细节:端口写成 127.0.0.1:3306:3306,只允许本机访问,千万不要把 3306 直接暴露到公网;/data/mysql 必须挂载到宿主机,容器删了数据还在。数据库容器不要用 --rm,更不要随手 docker rm -f。

六、用 Compose 编排整站

容器多了以后,一条条 docker run 难以维护。Compose 用一个 YAML 文件描述所有服务,一条命令启停。下面是一个最小可用的 WordPress 编排示例:

services:
  db:
    image: mysql:8.4
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: 换成强密码
      MYSQL_DATABASE: wordpress
    volumes:
      - ./mysql:/var/lib/mysql
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

  web:
    image: wordpress:php8.3-fpm
    restart: unless-stopped
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_NAME: wordpress
      WORDPRESS_DB_PASSWORD: 换成强密码
    volumes:
      - ./html:/var/www/html
    depends_on:
      - db

  nginx:
    image: nginx:1.27-alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./html:/var/www/html:ro
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - web

同一网络里的容器可以直接用服务名通信,web 连接数据库写 db 就行,不需要记 IP。启动用 docker compose up -d,看状态用 docker compose ps,看日志用 docker compose logs -f nginx,改完配置用 docker compose up -d 重建。

还要注意 PHP-FPM 的 Nginx 配置,fastcgi_pass 要指向 web:9000,而不是 127.0.0.1:9000,否则容器之间根本连不通,页面直接 502。

七、日常运维常用命令

场景命令
查看运行中的容器docker ps
进入容器排查docker exec -it nginx sh
查看容器日志docker logs -f --tail 100 nginx
查看资源占用docker stats
重启服务docker compose restart nginx
查看磁盘占用docker system df

八、生产环境要守住的几条线

  • 不要用 latest 标签:升级后行为可能变化,固定版本号才能可控回滚。
  • 限制资源:Compose 里设置 cpus 和 mem_limit,避免一个容器吃光整台机器。
  • 日志必须限制大小:daemon.json 的 max-size、max-file 是最容易被忽略的一项。
  • 数据卷要单独备份:容器可以随时重建,数据卷丢了就真没了。
  • 端口暴露要收敛:数据库、Redis 只监听 127.0.0.1,公网只开 80 和 443。
  • 防火墙别和 Docker 打架:Docker 会自行写 iptables 规则,ufw 的默认策略可能被绕过,端口控制优先在 Compose 里做。

九、常见问题

  • 容器起来了但网站 502:Nginx 连不上 PHP-FPM,检查 fastcgi_pass 是否指向容器名和 9000 端口,两个容器是否在同一网络。
  • 改了配置不生效:挂载单文件时,宿主机编辑器保存会替换 inode,容器里看到的还是旧文件。改成挂载整个目录,或重启容器。
  • 磁盘涨得很快:先 docker system df 看镜像、容器、数据卷各占多少,再分别清理,不要一上来就 prune -a。
  • 数据库连不上:确认密码没有特殊字符导致 YAML 解析错误,服务名和端口是否写对。

总结

Docker 部署网站的核心就四件事:镜像固定版本、数据挂载到宿主机、日志限制大小、端口只暴露必要的。把这四条守住,再用 Compose 管理多容器,迁移和升级都会比传统装环境轻松很多。新手建议先在一台测试机上跑通整站,再动生产环境。


手机扫码阅读

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

Linux 服务器磁盘空间不足怎么排查?df、du、日志清理与扩容一次讲清

Let's Encrypt 免费 SSL 证书实战:acme.sh 签发、Nginx 配置与自动续期一次讲清

评 论