容器化部署

本指南基于框架仓库根目录自带的 Dockerfiledocker-compose.yml,讲解如何用 Docker(Docker)构建 Viswoole 镜像并启动应用、MySQL 与 Redis 服务,最后给出面向生产的增强建议。

仓库自带的 Dockerfile

框架仓库根目录的 Dockerfile 内容如下:

dockerfile
# 基础镜像
FROM phpswoole/swoole:php8.5-alpine

# 设置工作目录
WORKDIR /var/www/app

# 复制项目文件到工作目录
COPY . /var/www/app

# 暴露容器监听的端口号(容器内固定 9501,与框架 config/server.php 默认监听一致;
# 宿主机访问端口由 docker-compose.yml 映射决定)
EXPOSE 9501

要点:

指令说明
FROM phpswoole/swoole:php8.5-alpineSwoole 官方镜像,内置 Swoole 扩展,满足框架 php >= 8.4ext-swoole >= 5.1 的要求
WORKDIR /var/www/app应用工作目录,php viswoole 命令需在此目录下执行
COPY . /var/www/app整体复制项目文件(含 vendor/config/app/ 等)
EXPOSE 9501声明容器内监听端口,与 config/server.php 默认的 host: 0.0.0.0port: 9501 一致

镜像不含 composer install

该 Dockerfile 直接 COPY . 整个项目,假定 vendor/ 依赖已在构建前通过本机 composer install 安装完成。生产镜像建议改为在镜像内安装依赖(见下文「生产增强建议」)。

仓库自带的 docker-compose.yml

框架仓库根目录的 docker-compose.yml 是一套面向开发调试的编排,包含 app、mysql、redis 三个服务:

yaml
version: '3.2'
services:
  app:
    build: ./
    ports:
      # 宿主机 9511 -> 容器 9501
      - "9511:9501"
    volumes:
      # 代码目录挂载进容器,本地改动实时同步
      - ./:/var/www/app
    environment:
      - TZ=Asia/Shanghai
      - REDIS_HOST=redis
    # 保持容器运行
    command: [ "tail", "-f", "/dev/null" ]
  mysql:
    image: mysql:latest
    restart: always
    volumes:
      # MySQL 官方镜像数据目录为 /var/lib/mysql
      - mysql:/var/lib/mysql
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: "123456"
  redis:
    image: redis:latest
    ports:
      - "6380:6379"
    volumes:
      - redis:/data
    environment:
      - TZ=Asia/Shanghai
volumes:
  mysql:
  redis:

编排设计解读

配置项意图
9511:9501 端口映射容器内监听端口保持框架默认的 9501,宿主机通过 9511 访问,避免与宿主机上其他 9501 服务冲突
./:/var/www/app 挂载本地代码目录直接挂载进容器,宿主机改代码、容器内立即生效,适合开发
command: tail -f /dev/null让容器保持常驻,由开发者手动进入容器执行启动命令
REDIS_HOST=redis通过 Docker 网络的服务名互访,Redis 主机名不再是 127.0.0.1
mysql:/var/lib/mysqlMySQL 数据持久化到命名卷,容器重建不丢数据
6380:6379宿主机用 6380 端口访问 Redis,避免与本机已有 Redis 冲突

启动与使用

bash
# 构建镜像并启动全部服务(后台运行)
docker compose up -d --build

# 进入应用容器(该编排下服务需手动启动)
docker compose exec app sh

# 在容器内启动 Viswoole 服务
php viswoole server:start

# 宿主机验证:框架默认路由返回 Hello Viswoole
curl http://127.0.0.1:9511/

数据库连接地址

容器内访问 MySQL 的主机名是 mysql(服务名),应在 .env 中设置 DATABASE_HOST=mysql;对应地 Redis 主机名为 redis(编排中已默认注入 REDIS_HOST=redis)。

生产增强建议

仓库自带编排面向开发,生产部署建议在以下方面增强(需按项目实际调整,以下为推荐做法而非仓库现状)。

生产 Dockerfile 模板

dockerfile
FROM phpswoole/swoole:php8.5-alpine

WORKDIR /var/www/app

# 先复制依赖清单并安装,利用 Docker 层缓存加速重复构建
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-interaction --optimize-autoloader --no-scripts

# 再复制业务代码(vendor 已生成,被覆盖前先复制清单可命中缓存)
COPY . /var/www/app

EXPOSE 9501

# 容器内前台运行(不加 -d):主进程即容器进程,配合 restart 策略由 Docker 负责拉起
CMD ["php", "viswoole", "server:start"]

与仓库版相比的变化:

  1. composer install --no-dev 在镜像内安装生产依赖,构建产物自包含;
  2. 先复制 composer.json / composer.lock 再复制代码,依赖不变时命中层缓存;
  3. CMD 前台启动服务,容器生命周期与服务进程绑定,配合 restart: unless-stopped 实现崩溃自动重启。

.dockerignore

排除不需要进入镜像的文件,缩小体积并避免泄漏:

text
.git
.env
.env.*
runtime/
tests/
docs/
.vscode/
.idea/
docker-compose*.yml

切勿打包 .env

.env 携带生产密钥。容器化部署应通过 environment、Docker Secrets 或编排工具注入环境变量,而不是把 .env 文件打进镜像。

生产 compose 示例(应用部分)

yaml
services:
  app:
    build: ./
    restart: unless-stopped
    ports:
      - "9501:9501"          # 生产环境建议仅映射到内网,由 Nginx 反代
    environment:
      - TZ=Asia/Shanghai
      - app_debug=false       # 生产必须关闭调试
      - DATABASE_HOST=mysql
      - REDIS_HOST=redis
    depends_on:
      - mysql
      - redis
    logging:
      driver: json-file
      options:
        max-size: "50m"
        max-file: "5"

注意环境变量优先级

.env 文件的读取优先级高于注入的系统环境变量。若镜像或挂载卷中存在项目根目录的 .envenvironment 注入的同名变量会被覆盖,详见 环境变量

健康检查

可增加一个简单的健康检查路由(如 GET /health 返回 JSON),在镜像或编排中配置:

dockerfile
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
    CMD curl -f http://127.0.0.1:9501/health || exit 1

常用运维命令

bash
# 构建镜像
docker build -t viswoole-app:v1.0 .

# 启动 / 更新服务
docker compose up -d --build

# 查看应用日志
docker compose logs -f app

# 进入容器执行框架命令(如完整重启服务)
docker compose exec app php viswoole server:close
docker compose exec app php viswoole server:start -d

# 清理路由缓存(升级框架后如遇路由缓存不兼容)
docker compose exec app php viswoole router:clear-cache

# 查看容器资源占用
docker stats

容器内变更生效

代码以镜像形式固化时,每次发布都要重新构建镜像;若沿用仓库版的目录挂载方式,宿主机代码变更后仍需在容器内重启 Swoole 进程才生效,重启策略见 生产环境配置

下一步