knowledge/docs/php/docker81.md

247 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 为workerman制作跨平台的PHP8.1环境Docker镜像
## 说明
本方法基于PHP官方`8.1.27-cli`版本的镜像制作安装好workerman开发常用的依赖和扩展并通过`docker buildx`构建跨平台的Docker镜像。
## Dockerfile文件
```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
# 安装一些依赖
RUN apt-get update && apt-get install -y \
libfreetype6-dev libjpeg62-turbo-dev \
libpng-dev libwebp-dev zlib1g-dev \
libzip-dev zip \
libevent-dev libssl-dev \
lsb-release libpq-dev \
libgmp-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
docker info
```
执行以上命令可以看到类似下面的信息:
```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
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
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
```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
```
### composer命令脚本
> 仅适用于linux系统
```sh
#!/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
chmod +x ./composer
```
然后就可以用`./composer`代替composer命令了。
也可以直接把这个composer脚本复制到/usr/bin/目录下以供全局使用(不建议这样,失去了多版本共存的意义)。
### php命令脚本
```sh
#!/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"
```
同样要为`php`脚本赋予可执行权限
```sh
chmod +x ./php
```
然后就可以执行`./php`代替php命令了。
### 最佳实践
建议把composer脚本和php脚本都保存在项目工程目录下另外再把容器内`/usr/local/etc/php/php-production.ini`文件也复制到工程目录下并命名为`php.ini`,在`docker-compose.yml`文件中配置卷映射
```yml
volumes:
- ./:/app/service
- ./php.ini:/usr/local/etc/php/php.ini
```
### 工程示例
<https://git.wandoubaba.com/wandoubaba/docker-webman>
```sh
git clone git@git.wandoubaba.com:wandoubaba/docker-webman.git
cd docker-webman
./composer install
./php start.php start
```