diff --git a/docs/php/docker81.md b/docs/php/docker81.md index dab4463..2c7b9e7 100644 --- a/docs/php/docker81.md +++ b/docs/php/docker81.md @@ -1,170 +1,246 @@ -# 制作PHP8.1版的workerman环境镜像 +# 为workerman制作跨平台的PHP8.1环境Docker镜像 ## 说明 -用本文方法制作的镜像不是跨平台的,也就是说在amd64平台制作的镜像只适用于amd64平台,在arm64平台制作的镜像则只适用于arm64平台。 +本方法基于PHP官方`8.1.27-cli`版本的镜像制作,安装好workerman开发常用的依赖和扩展,并通过`docker buildx`构建跨平台的Docker镜像。 -## 拉基础镜像 +## Dockerfile文件 -```sh -docker pull php:8.1-cli-bullseye -``` +```dockerfile +# 拉基础镜像 +FROM php:8.1.27-cli -## 启动容器 +# 替换源 +RUN rm /etc/apt/sources.list.d/debian.sources && \ + echo 'deb http://mirror.us.oneandone.net/debian bookworm main' > /etc/apt/sources.list && \ + echo 'deb-src http://mirror.us.oneandone.net/debian bookworm main' >> /etc/apt/sources.list && \ + echo 'deb http://mirror.us.oneandone.net/debian-security bookworm-security main' >> /etc/apt/sources.list && \ + echo 'deb-src http://mirror.us.oneandone.net/debian-security bookworm-security main' >> /etc/apt/sources.list && \ + echo 'deb http://mirror.us.oneandone.net/debian bookworm-updates main' >> /etc/apt/sources.list && \ + echo 'deb-src http://mirror.us.oneandone.net/debian bookworm-updates main' >> /etc/apt/sources.list && \ + echo 'deb http://mirror.us.oneandone.net/debian bookworm-backports main' >> /etc/apt/sources.list && \ + echo 'deb-src http://mirror.us.oneandone.net/debian bookworm-backports main' >> /etc/apt/sources.list -```sh -docker run -itd --net=host --name=workerman php:8.1-cli-bullseye -``` - -> php:8.1-cli-bullseye是基于debian:bullseye制作的 - -### 替换国内源(可选) - -保存一个`sources.list`文件 - -```sh -tee sources.list <<-'EOF' -deb http://repo.huaweicloud.com/debian/ bullseye main non-free contrib -deb-src http://repo.huaweicloud.com/debian/ bullseye main non-free contrib -deb http://repo.huaweicloud.com/debian/ bullseye-updates main non-free contrib -deb-src http://repo.huaweicloud.com/debian/ bullseye-updates main non-free contrib -deb http://repo.huaweicloud.com/debian/ bullseye-proposed-updates main non-free contrib -deb-src http://repo.huaweicloud.com/debian/ bullseye-proposed-updates main non-free contrib -deb http://repo.huaweicloud.com/debian/ bullseye-backports main non-free contrib -deb-src http://repo.huaweicloud.com/debian/ bullseye-backports main non-free contrib -deb http://repo.huaweicloud.com/debian-security bullseye-security/updates main non-free contrib -deb-src http://repo.huaweicloud.com/debian-security bullseye-security/updates main non-free contrib -EOF -``` - -把文件保存到容器中替换原来的源 - -```sh -docker cp sources.list workerman:/etc/apt/ -``` - -## 进入容器 - -```sh -docker exec -it workerman bash -``` - -## 制作环境 - -先安装一些依赖 - -```sh -apt-get update && apt-get install -y \ - libfreetype6-dev libjpeg62-turbo-dev libpng-dev libwebp-dev zlib1g-dev \ +# 安装一些依赖 +RUN apt-get update && apt-get install -y \ + libfreetype6-dev libjpeg62-turbo-dev \ + libpng-dev libwebp-dev zlib1g-dev \ libzip-dev zip \ - libevent-dev \ + libevent-dev libssl-dev \ lsb-release libpq-dev \ libgmp-dev \ - libmagickwand-dev + libmagickwand-dev \ + libzookeeper-mt-dev + +# 安装扩展 +RUN docker-php-ext-configure gd --enable-gd --with-freetype --with-jpeg --with-webp \ + && docker-php-ext-install -j$(nproc) gd \ + && docker-php-ext-install exif \ + && docker-php-ext-install opcache \ + && docker-php-ext-install pdo_mysql \ + && docker-php-ext-install mysqli \ + && docker-php-ext-install zip \ + && docker-php-ext-install pcntl \ + && docker-php-ext-install fileinfo \ + && pecl install https://pecl.php.net/get/redis-6.0.2.tgz \ + && docker-php-ext-enable redis \ + && docker-php-ext-install sockets \ + && pecl install https://pecl.php.net/get/event-3.1.4.tgz \ + && docker-php-ext-enable event \ + && cat /usr/local/etc/php/conf.d/docker-php-ext-event.ini >> /usr/local/etc/php/conf.d/docker-php-ext-sockets.ini \ + && mv /usr/local/etc/php/conf.d/docker-php-ext-sockets.ini /usr/local/etc/php/conf.d/docker-php-ext-event.ini \ + && docker-php-ext-install -j$(nproc) pgsql pdo_pgsql \ + && pecl install https://pecl.php.net/get/mongodb-1.19.3.tgz \ + && docker-php-ext-enable mongodb \ + && docker-php-ext-install -j$(nproc) gmp \ + && pecl install https://pecl.php.net/get/imagick-3.7.0.tgz \ + && docker-php-ext-enable imagick \ + && docker-php-ext-install bcmath \ + && docker-php-ext-enable bcmath \ + && pecl install https://pecl.php.net/get/xlswriter-1.5.5.tgz \ + && docker-php-ext-enable xlswriter \ + && pecl install https://pecl.php.net/get/zookeeper-1.2.1.tgz \ + && docker-php-ext-enable zookeeper + +# 安装Composer +RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ + && php composer-setup.php \ + && php -r "unlink('composer-setup.php');" \ + && mv composer.phar /usr/local/bin/composer + +# 创建应用目录 +RUN mkdir -p /app/service + +# 设置工作目录 +WORKDIR /app/service ``` -### 安装扩展 +> 在`替换源`那一段中,你应该把其中的源地址替换成你的主机可以快速访问的源地址,不建议直接使用本文的源。 + +## 用`docker buildx`构建 + +将上面的Dockerfile脚本直接保存为`Dockerfile`文件。 + +### 检查`docker buildx`环境 ```sh -# gd -docker-php-ext-configure gd --enable-gd --with-freetype --with-jpeg --with-webp -docker-php-ext-install -j$(nproc) gd -# exif -docker-php-ext-install exif -# opcache -docker-php-ext-install opcache -# pdo_mysql -docker-php-ext-install pdo_mysql -# mysqli -docker-php-ext-install mysqli -# zip -docker-php-ext-install zip -# pcntl -docker-php-ext-install pcntl -# fileinfo -docker-php-ext-install fileinfo -# redis (回答都用默认值) -pecl install redis -docker-php-ext-enable redis -# event (Include libevent OpenSSL support问题回答为no,其他默认) -docker-php-ext-install sockets -pecl install event -docker-php-ext-enable event -cat /usr/local/etc/php/conf.d/docker-php-ext-event.ini >> /usr/local/etc/php/conf.d/docker-php-ext-sockets.ini -mv /usr/local/etc/php/conf.d/docker-php-ext-sockets.ini /usr/local/etc/php/conf.d/docker-php-ext-event.ini -# 上面操作原因:event扩展依赖sockets扩展,所以要先安装sockets扩展,同时保证sockets扩展要在event之前被加载 -# pgsql和pdo_pgsql -docker-php-ext-install -j$(nproc) pgsql pdo_pgsql -# mongodb -pecl install mongodb -docker-php-ext-enable mongodb -# gmp(一个开源的数学运算库,一些加密组件需要这个扩展) -docker-php-ext-install -j$(nproc) gmp -# imagick(一个可以读写多种格式图片的扩展) -pecl install imagick -docker-php-ext-enable imagick +docker info ``` -### 安装composer +执行以上命令可以看到类似下面的信息: + +```txt +Client: Docker Engine - Community + Version: 27.0.3 + Context: default + Debug Mode: false + Plugins: + buildx: Docker Buildx (Docker Inc.) + Version: v0.15.1 + Path: /usr/libexec/docker/cli-plugins/docker-buildx + compose: Docker Compose (Docker Inc.) + Version: v2.28.1 + Path: /usr/libexec/docker/cli-plugins/docker-compose +... +``` + +一般情况下,如果是通过包管理器安装的docker engine或者docker desktop的话,默认就已经安装好了buildx和compose插件了。 + +### 跨平台构建并发布 + +接下来,我们的目标是用上面的Dockerfile构建跨平台的`workerman:8.1.27`镜像并直接推送到`quay.io`平台上: + +(本文中我的quay.io账号是wandoubaba517,你要替换成你自己的账号。) ```sh -php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" -php composer-setup.php -php -r "unlink('composer-setup.php');" -mv composer.phar /usr/local/bin/composer +docker login quay.io +docker buildx create --use +docker buildx build --platform linux/386,linux/s390x,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8 --push -t quay.io/wandoubaba517/workerman:8.1.27 . ``` -### 创建一个应用目录 +执行上面的命令,执行过程中会自动从docker hub上拉取名为`moby/buildkit:buildx-stable-1`的镜像并启动容器开始自动构建和推送,整个过程在我的2核4G服务器上会执行数小时,可以使用`tmux`等终端工具异步执行。 + +## 使用镜像 ```sh -mkdir -p /app/service +docker pull quay.io/wandoubaba517/workerman:8.1.27 +docker run -itd -p 8787:8787 -v ./:/app/service quay.io/wandoubaba517/workerman:8.1.27 ``` -### 生成镜像 +### docker-compose.yml -如果还有容器内,先用`exit`命令退出到宿主机。 +```yml +services: + workerman: + image: quay.io/wandoubaba517/workerman:8.1.27 + container_name: workerman + restart: always + volumes: + - ./:/app/service + working_dir: /app/service + stdin_open: true + ports: + - 8787:8787 + ommand: ['php', 'start.php', 'start'] + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8787/"] + interval: 5s + retries: 3 + start_period: 5s + timeout: 10s +``` -用`docker ps -a`命令可以看到对应的 +### composer命令脚本 + +> 仅适用于linux系统 ```sh -docker commit workerman workerman:8.1 +#!/bin/bash + +# 使用heredoc构建docker run命令 +read -r -d '' DOCKER_COMMAND <<'EOF' +docker run --rm \ +-v "$(pwd)":/app/service \ +-w /app/service \ +quay.io/wandoubaba517/workerman:8.1.27 \ +composer +EOF + +# 检查是否有传递参数,并将它们附加到命令的末尾 +if [ $# -gt 0 ]; then + DOCKER_COMMAND+=" $@" +fi + +# 执行docker run命令 +eval "$DOCKER_COMMAND" ``` -### 使用镜像 - -在宿主机中进行项目代码根目录,执行下面的命令 +把上面的脚本保存为`compose`文件,设置可执行权限: ```sh -docker run -it -d --net=host -v ./:/app/service -w /app/service workerman:8.1 +chmod +x ./composer ``` -执行容器中的composer命令: +然后就可以用`./composer`代替composer命令了。 + +也可以直接把这个composer脚本复制到/usr/bin/目录下以供全局使用(不建议这样,失去了多版本共存的意义)。 + +### php命令脚本 ```sh -docker exec <容器ID> composer install -docker exec <容器ID> composer require xxxx +#!/bin/bash + +# 获取脚本所在目录的绝对路径 +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) + +# 切换工作目录到脚本所在目录 +cd "$SCRIPT_DIR" || exit 1 + +# 使用heredoc构建docker run命令 +read -r -d '' DOCKER_COMMAND <<'EOF' +docker run --rm \ +--network host \ +-v "$(pwd)":/app/service \ +-v "$(pwd)/php.ini":/usr/local/etc/php/php.ini \ +-w /app/service \ +quay.io/wandoubaba517/workerman:8.1.27 \ +php +EOF + +# 检查是否有传递参数,并将它们附加到命令的末尾 +if [ $# -gt 0 ]; then + DOCKER_COMMAND+=" $@" +fi + +# 执行docker run命令 +eval "$DOCKER_COMMAND" ``` -启动容器中的workerman服务: +同样要为`php`脚本赋予可执行权限 ```sh -docker exec <容器ID> php start.php start +chmod +x ./php ``` -### 发布镜像 +然后就可以执行`./php`代替php命令了。 -可以把镜像发布到hub.docker.com上,也可以参照阿里云的容器镜像服务中的文档,把本地镜像发布到阿里云上,以便于在其他主机中使用。 +### 最佳实践 -## 推荐 +建议把composer脚本和php脚本都保存在项目工程目录下,另外再把容器内`/usr/local/etc/php/php-production.ini`文件也复制到工程目录下并命名为`php.ini`,在`docker-compose.yml`文件中配置卷映射 -本文作者已将制作好的环境镜像发布到hub.docker.com上,地址 +```yml + volumes: + - ./:/app/service + - ./php.ini:/usr/local/etc/php/php.ini +``` + +### 工程示例 + + ```sh -docker pull wandoubaba517/workerman:8.1 -``` - -或者 - -```sh -docker pull wandoubaba517/workerman:8.1-arm64 +git clone git@git.wandoubaba.com:wandoubaba/docker-webman.git +cd docker-webman +./composer install +./php start.php start ```