本文介绍如何制作PHP镜像并部署到 Serverless应用引擎SAE(Serverless App Engine) 。
前提条件
- 安装Docker 。
- 开通阿里云SAE服务 。
- 开通阿里云容器镜像ACR服务 ,个人版实例和企业版实例皆可。
背景信息
通常来说,您无需从空镜像开始安装PHP以及其他各种组件,而是可以通过 dockerhub 获取PHP官方镜像。官方的系统镜像是Debian或Alpine(Alpine镜像的体积小于Debian镜像),其中已经包含PHP以及一些辅助命令。官方镜像的版本命令规则如下:
-
php:8.0.12-cli-bullseye
:表示PHP版本为8.0.12,基于系统镜像bullseye(Debian 11)进行构建。其中cli
表示未开启CGI,即不能运行fpm
,只可运行命令行。 -
php:7.3.32-fpm-alpine3.13
:表示PHP版本为7.3.32,基于系统镜像alpine3.13进行构建。其中fpm
表示开启了CGI,可用来运行Web服务,也可用来运行CLI命令。
步骤一:制作基础镜像
基础镜像里包含常用的扩展和配置,在后续每次构建时就无需重复执行这些步骤。
-
创建项目文件。
- 创建一个用于存放PHP资源的项目文件夹,命名为 php 。
- 在PHP文件夹下,创建一个用于存放基础镜像资源的项目文件夹,命名为 base 。
-
执行以下命令,进入项目目录。
cd php/base
-
创建并编辑
Dockerfile
文件,文件内容如下:
FROM php:7.3.32-fpm-alpine3.13 LABEL MAINTAINER="sae@aliyun.com" ENV TZ "Asia/Shanghai" RUN echo ${TZ} >/etc/timezone # COPY composer.phar /usr/local/bin/composer # 创建www用户 RUN addgroup -g 1000 -S www && adduser -s /sbin/nologin -S -D -u 1000 -G www www # 配置阿里云镜像源,加快构建速度。 RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories # PHPIZE_DEPS包含gcc g++等编译辅助类库,完成后删除;pecl安装扩展。 RUN apk add --no-cache $PHPIZE_DEPS \ && apk add --no-cache libstdc++ libzip-dev vim\ && apk update \ && pecl install redis-5.3.0 \ && pecl install zip \ && pecl install swoole \ && docker-php-ext-enable redis zip swoole\ && apk del $PHPIZE_DEPS # docker-php-ext-install安装扩展。 RUN apk update \ && apk add --no-cache nginx freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev \ && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/ \ && docker-php-ext-install -j$(nproc) gd \ && docker-php-ext-install -j$(nproc) pdo_mysql opcache bcmath mysqli # 在run.sh COPY run.sh /run.sh RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" && mkdir -p /run/nginx/ && chmod +x /run.sh ENTRYPOINT ["/run.sh"]
说明 该镜像文件同时采用pecl和docker-php-ext-install安装扩展,二者差异如下:- pecl可以自动下载或者指定包安装扩展,安装完以后需要用docker-php-ext-enable启用扩展。
- docker-php-ext-install可以安装的扩展有限,可以通过docker-php-ext-install help查询可以安装的扩展列表,安装以后默认启用。
-
可选:
修改镜像。
说明 步骤1的基础镜像将Nginx和PHP配置在同一个镜像内,同时启动php-fpm和nginx,符合常见的虚拟机部署习惯,但并不满足容器提倡的单进程管理模型。您可以考虑将php-fpm和nginx分别部署成两个应用,只需要针对上述镜像做少许修改即可。
#!/usr/bin/env sh set -e php-fpm -D nginx -g 'daemon off;'
-
执行以下命令,构建镜像。
docker build -t php-bash:v1 .
输出示例如下:
Sending build context to Docker daemon 4.096kB Step 1/11 : FROM php:7.3.32-fpm-alpine3.13 ---> 2e127e9a**** ...... Step 11/11 : ENTRYPOINT ["/run.sh"] ---> Using cache ---> dfde0cef**** Successfully built dfde0cef**** Successfully tagged php-bash:v1
步骤二:制作业务镜像
您可以按需对 步骤一 的镜像进行部分修改,以此作为您企业内使用的基础镜像,则后续的业务镜像都可以将其作为父镜像。
-
在
php
项目目录下,创建
Dockerfile
文件。
FROM php-bash:v1 # 把阿里云镜像地址换成内网地址,不开公网就可以安装各种软件。 RUN sed -i "s/mirrors.aliyun.com/mirrors.cloud.aliyuncs.com/g" /etc/apk/repositories && sed -i "s/https/http/g" /etc/apk/repositories # php-fpm配置 COPY www.conf /usr/local/etc/php-fpm.d/www.conf # Nginx配置 COPY default.conf /etc/nginx/http.d/ COPY index.php /var/www/html
-
创建并编辑
www.conf
文件,文件内容如下:
[www] user = www group = www listen = 0.0.0.0:9000 pm = dynamic pm.max_children = 100 pm.start_servers = 30 pm.min_spare_servers = 20 pm.max_spare_servers = 50
-
创建并编辑
default.conf
文件,文件内容如下:
server { listen 80; root /var/www/html; index index.html index.htm index.php; location ~ .*\.(php|php5)?$ fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; access_log /tmp/nginx_access.log; error_log /tmp/nginx_error.log; }
-
创建并编辑
index.php
文件,文件内容如下:
<html> <title>PHP Hello SAE!</title> </head> <?php echo '<h1>Hello SAE</h1>'; ?> <?php phpinfo(); ?> </body> </html>
-
在
容器镜像服务控制台
创建两个镜像仓库,分别命名为
php-base
和
php-server
。
个人版和企业版实例均适用本文的操作,本文以个人版实例为例。具体操作,请参见以下文档:
- 个人版实例: 构建仓库与镜像
- 企业版实例: 使用企业版实例构建镜像
-
构建并推送镜像。
成功推送后,您可以登录 容器镜像服务控制台 ,在目标镜像仓库的 镜像版本 页面查看推送的版本。
步骤三:部署镜像
-
创建PHP应用。
在 应用部署配置 配置向导页面, 技术栈语言 需选择 PHP , 应用部署方式 需选择 镜像 。具体操作,请参见 在SAE控制台使用镜像部署PHP应用 。说明 除创建新应用外,您还可以修改现有应用的配置镜像。具体操作,请参见 升级应用 。
-
为PHP应用绑定公网SLB。
绑定完成后,您可以在 应用访问设置 区域查看公网访问地址。
-
结果验证。
按照 http://slbip:port/ 的格式,在浏览器地址栏输入 步骤2 设置的公网地址并回车。结果如下:
更多信息
您如果不想每次都是手动构建、推送、部署,可以对接开源的jenkins或者阿里云云效。具体信息,请参见以下文档: