容器化部署
本指南基于框架仓库根目录自带的 Dockerfile 与 docker-compose.yml,讲解如何用 Docker(Docker)构建 Viswoole 镜像并启动应用、MySQL 与 Redis 服务,最后给出面向生产的增强建议。
仓库自带的 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-alpine | Swoole 官方镜像,内置 Swoole 扩展,满足框架 php >= 8.4、ext-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.0、port: 9501 一致 |
镜像不含 composer install
该 Dockerfile 直接 COPY . 整个项目,假定 vendor/ 依赖已在构建前通过本机 composer install 安装完成。生产镜像建议改为在镜像内安装依赖(见下文「生产增强建议」)。
仓库自带的 docker-compose.yml
框架仓库根目录的 docker-compose.yml 是一套面向开发调试的编排,包含 app、mysql、redis 三个服务:
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/mysql | MySQL 数据持久化到命名卷,容器重建不丢数据 |
6380:6379 | 宿主机用 6380 端口访问 Redis,避免与本机已有 Redis 冲突 |
启动与使用
# 构建镜像并启动全部服务(后台运行)
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 模板
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"]与仓库版相比的变化:
composer install --no-dev在镜像内安装生产依赖,构建产物自包含;- 先复制
composer.json/composer.lock再复制代码,依赖不变时命中层缓存; - 用
CMD前台启动服务,容器生命周期与服务进程绑定,配合restart: unless-stopped实现崩溃自动重启。
.dockerignore
排除不需要进入镜像的文件,缩小体积并避免泄漏:
.git
.env
.env.*
runtime/
tests/
docs/
.vscode/
.idea/
docker-compose*.yml切勿打包 .env
.env 携带生产密钥。容器化部署应通过 environment、Docker Secrets 或编排工具注入环境变量,而不是把 .env 文件打进镜像。
生产 compose 示例(应用部分)
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 文件的读取优先级高于注入的系统环境变量。若镜像或挂载卷中存在项目根目录的 .env,environment 注入的同名变量会被覆盖,详见 环境变量。
健康检查
可增加一个简单的健康检查路由(如 GET /health 返回 JSON),在镜像或编排中配置:
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -f http://127.0.0.1:9501/health || exit 1常用运维命令
# 构建镜像
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 进程才生效,重启策略见 生产环境配置。
