Docker Compose 提升 ThinkPHP 自动化部署效能

目前我们一直使用 lnmp.org 集成安装包进行环境的搭建,不过 Centos 8 在 lnmp.org 上是不支持的,只能用 Centos 7.X 系列,也将在明年6月30号完成最后的安全周期。使用 lnmp.org 进行网站设置和搭建可能会存在一些复杂的步骤,这时使用 Docker 就可以解决很多问题,Docker 的强大功能可以让你快速、简单地部署 web 应用,且提供了非常多的高级功能,比如服务器间的环境隔离,多应用之间的数据共享以及应用容器的快速缩放等。

与 K8s 相比,Docker 具有易用性和可读性优势。K8s 是一种复杂的容器编排系统,它可以在大规模的集群上部署容器应用,提供了高级服务,如负载均衡、服务发现、高可用性和自动伸缩等。但是安装运行起来非常复杂,而 Docker 则更加简单,可以让你更快速、更容易的完成部署任务。

而我们 PHP 部署是需要用到 Docker Compose,需要方便的建立一个网络连接,让 nginx 可以访问到 php-fpm。

完整流程图

目前我们一步一步来实现整个流程

  1. 最开始,我在 GitHub 创建一个 test-thinkphp-docker-mbzrjdwz4502a44i 仓库来存储我们需要的代码。

  1. 仓库创建完成后,要弄点 Demo 代码进去才行,这里我就直接 composer create-project topthink/think tp -vvv --no-cache 弄一个干净的 TP6 了。

  1. 这一步就重要了,我们需要把进行构建的 Dockerfile 放进来,一个是构建 Nginx,一个构建 PHP。

docker/nginx/Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM library/nginx:1.22@sha256:4c5e1e4ab724db750979851cd2f4e2dec13648792280be1cd052bf9c638285da as nginx

WORKDIR /web

ADD https://cdn.hongfs.cn/external/raw.githubusercontent.com/hongfs/hongfs/762cd92804b828d31d28c65e7fceecb45f61a245/php/release.conf /etc/nginx/templates/default.conf

COPY $PROJECT_DIR/ .

ENV WEB_ROOT=/web

EXPOSE 80
EXPOSE 443

CMD envsubst '${WEB_DOMAIN},${WEB_ROOT},${WEB_SSL_PORT},${WEB_SSL_PEM},${WEB_SSL_KEY},${WEB_FASTCGI}' < /etc/nginx/templates/default.conf > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'

docker/php/Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
FROM composer:2.5.4@sha256:082ed124b68e7e880721772a6bf22ad809e3bc87db8bbee9f0ec7127bb21ccad as composer

RUN composer config -g repo.packagist composer https://hk.hongfs.dev/composer/

FROM php:8.2.3-fpm@sha256:d219dfa4e6d55292f093c93618cec1dc11a6a7be88e63bf4f3e91f15786643dd as php

WORKDIR /web

COPY --from=composer /usr/bin/composer /usr/bin/composer

COPY $PROJECT_DIR/ .

RUN apt-get update && \
apt-get install -y git zip libpng-dev libzip-dev && \
rm -rf /var/lib/apt/lists/* && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && \
pecl install redis-5.3.7 && \
docker-php-ext-install pdo pdo_mysql mysqli gd zip bcmath opcache && \
docker-php-ext-enable mysqli gd redis

RUN echo "[opcache]\n\
opcache.enable=1\n\
opcache.enable_cli=1\n\
opcache.memory_consumption=256\n\
opcache.interned_strings_buffer=128\n\
opcache.max_accelerated_files=1000000\n\
opcache.max_wasted_percentage=10\n\
opcache.validate_timestamps=0\n\
opcache.enable_file_override=1" > /usr/local/etc/php/conf.d/opcache.ini

RUN composer install -vvv && \
composer clear-cache

EXPOSE 9000

CMD ["php-fpm"]
  1. 进入流水线前,我们还需要创建一个容器仓库,来存放等一会的构建物,阿里云是有个人免费版可以使用的,创建选哪个地域都行,然后最后面的代码源我们可以选本地仓库这样子就不需要设置。

  1. Flow 创建一个空白流水线

  1. 配置流水线源,就是代码要从哪里拉取,这里需要经过一个授权才可以的。

开启“开启代码源触发”,然后会给一个 WebHook 地址,这个需要去 GitHub 那边添加,后面符合我们设置的允许分支,就可以触发构建。

  1. GitHub 配置 WebHook,记得 content-type 要选 JSON 格式的。

  1. 配置 PHP 的编译,构建集群最好选香港

${CI_COMMIT_REF_NAME} 这个变量值是分支的名称,更多可以参考:https://help.aliyun.com/document_detail/153688.html

  1. 配置 Nginx 的编译,构建集群最好选香港

  1. 配置主机组,就是我们要部署的服务器集群

  1. 自有主机会提供一个命令来进行连接,我们需要在相关服务器进行执行

  1. 配置运行的脚本
1
$ cd ~/docker-compose && curl -s https://cdn.hongfs.cn/external/raw.githubusercontent.com/hongfs/hongfs/7e94aa3d59a134f140b17c15a25cbf01d0ccf586/docker-compose/thinkphp/6/script.sh | NAME=$CI_COMMIT_REF_NAME sh

  1. 在相关服务器上的 ~/docker-compose 目录上存放允许分支的 yaml 文件。

~/docker-compose/release.yaml release 分支

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: '3'
services:
web:
image: registry.cn-hongkong.aliyuncs.com/hongfs/test-thinkphp-docker-mbzrjdwz4502a44i:nginx-release
environment:
WEB_DOMAIN: "release-compose.hongfs.cn" # 域名
WEB_SSL_PORT: "443" # 监听端口
WEB_SSL_PEM: "/ssl/fullchain.cer" # SSL PEM 地址
WEB_SSL_KEY: "/ssl/hongfs.cn.key" # SSL KEY 地址
WEB_FASTCGI: "php:9000"
ports:
- "8000:443"
volumes:
- ~/ssl/:/ssl/ # 把外部 SSL 文件挂载进来
links:
- php
depends_on:
- php
php:
image: registry.cn-hongkong.aliyuncs.com/hongfs/test-thinkphp-docker-mbzrjdwz4502a44i:php-release

好了,现在可以保存了,然后进行测试。

服务器上 ~/docker-compose/~/ssl/ 一定要放相关文件。

容器仓库最好是私有库,所以你需要进行必要的 docker login。(docker login --username=${DOCKER_USERNAME} --password=${DOCKER_PASSWORD} registry.${CR_REGION}.aliyuncs.com

最后,PHP 的 Dockerfile 可以优化下,提升构建速度。

1
2
3
4
5
6
7
8
9
10
11
12
FROM hongfs/env:php8-docker-compose@sha256:20f05e12f0cf1f4c628311e8b6101ac0dce343c23e9551e4fa90452a5d0cfa44

WORKDIR /web

COPY $PROJECT_DIR/ .

RUN composer install -vvv && \
composer clear-cache

EXPOSE 9000

CMD ["php-fpm"]

整体的构建速度提升了非常多,相当于一分钟完成了部署。

这里还要提供一个压测数据,在一台 4H8G 的服务器上,使用 wrk 压测,没有开启 opcache 是 200/request/s ,开启 opcache 后是 1000/request/s。

往上