疯流涕淌 發表於 2021-6-30 17:34:00

基于官方php:7.2.34-fpm-alpine镜像构建生产可用镜像

<h2 id="1-了解官方php镜像">1 了解官方php镜像</h2>
<p>Dockerhub 上 PHP 官方基础镜像主要分为三个分支:</p>
<ol>
<li>
<p><code>cli</code>: 没有开启 CGI 也就是说不能运行fpm。只可以运行命令行。</p>
</li>
<li>
<p><code>fpm</code>: 开启了CGI,可以用来运行web服务也可以用来运行cli命令。</p>
</li>
<li>
<p><code>zts</code>: 开启了线程安全的版本。</p>
</li>
</ol>
<p><strong>选择什么分支的镜像?</strong></p>
<p>一般在生成环境会使用到 <code>php-fpm</code>。先了解一下什么是php-fpm?</p>
<ul>
<li>
<p>由于nginx本身不能处理PHP,它只是个web服务器,当接收到请求后,如果是php请求,则发给php解释器处理,并把结果返回给客户端;</p>
</li>
<li>
<p>nginx 一般是把请求发fastcgi管理进程处理,fascgi管理进程选择 CGI 子进程处理结果并返回被 nginx ;</p>
</li>
<li>
<p>PHP-FPM 是一个PHP FastCGI管理器,旨在将FastCGI进程管理整合进PHP包中;</p>
</li>
<li>
<p>PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置,比spawn-fcgi具有更多优点,所以被PHP官方收录了。</p>
</li>
</ul>
<p>所以,LNMP架构的一般会选择 <code>fpm</code> 分支的镜像。</p>
<h2 id="2-需求分析和镜像选择">2 需求分析和镜像选择</h2>
<p><strong>镜像选择</strong></p>
<p>首先是基础镜像版本的选择,我这里选择的是 <code>php:7.2.34-fpm-alpine</code> 镜像。php 版本为 <code>7.2.34</code> (php版本需要结合具体业务代码进行选择),这个官方镜像基于alpine 镜像进行构建,alpine镜像体积非常小 ,大小只有5m左右。</p>
<p><strong>需求分析</strong></p>
<p>对于php应用来说,都需要自己额外安装一些扩展。官方基础镜像的扩展一般满足不我们的需求,所以需要看看官方镜像有哪些扩展,然后再按需安装我们要的扩展。</p>
<p>查看官方基础镜像有什么扩展:</p>
<pre><code class="language-shell"># docker runphp:7.2.34-fpm-alpinephp -m

Core
ctype
curl
date
dom
fileinfo
filter
ftp
hash
iconv
json
libxml
mbstring
mysqlnd
openssl
pcre
PDO
pdo_sqlite
Phar
posix
readline
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
tokenizer
xml
xmlreader
xmlwriter
zlib


</code></pre>
<p>安装经验,一般需要额外安装的扩展:</p>
<ul>
<li><code>redis</code>:redis是目前主流的Nosql数据库,常用。</li>
<li><code>zip</code>:文件压缩扩展。</li>
<li><code>gd</code>:图片处理扩展,一些图形验证码的生成不能没有这个扩展。</li>
<li><code>bcmath</code>:没有这个库的话可能一些框架或者类库的<code>composer</code>依赖校验会无法通过。</li>
<li><code>pdo_mysql</code>:连接数据库扩展。</li>
<li><code>opcache</code>: 是 PHP 中的 Zend 扩展,可以大大提升 PHP 的性能。</li>
<li><code>swoole</code>:一个PHP高级Web开发框架,可按需添加。</li>
</ul>
<p>除了扩展之外,还可以安装一个php的包管理工具 <code>composer</code>。<code>composer</code> 是PHP的包管理、包依赖关系管理工具,有了它,我们就很轻松一个命令就可以把他人优秀的代码用到我们的项目中来,而且很容易管理依赖关系,更新删除等操作也很轻易的实现。</p>
<h2 id="3-构建准备">3 构建准备</h2>
<ol>
<li>创建工程目录</li>
</ol>
<pre><code class="language-shell"># mkdir lnmp/php -p
# cd lnmp/php/
</code></pre>
<ol start="2">
<li>准备 <code>composer</code> 包,放在工程目录下,下载链接:https://github.com/composer/composer/releases</li>
</ol>
<pre><code class="language-shell"># wget https://github.com/composer/composer/releases/download/2.0.13/composer.phar
</code></pre>
<ol start="3">
<li>准备 <code>date.ini</code> 文件,设置PHP默认时区为东八区:</li>
</ol>
<pre><code class="language-shell"># mkdir conf.d
# echo "date.timezone = Asia/Shanghai" &gt; conf.d/date.ini
</code></pre>
<ol start="4">
<li>准备 <code>opcode.ini</code> 文件,用于设置opcode默认的参数,并且设置环境变量 <code>OPCODE</code> 以控制其是否被开启。当环境变量OPCODE的值被设置为1的时候表示开启opcode,0则关闭。</li>
</ol>
<pre><code class="language-shell"># 这里加 \EOF 是防止${OPCODE}被转义
# cat &gt;&gt; conf.d/opcode.ini &lt;&lt; \EOF
&gt; opcache.enable=${OPCODE}
&gt; enable_clopcache.enable_cli=1
&gt; opcache.revalidate_freq=60
&gt; opcache.max_accelerated_files=100000
&gt; opcache.validate_timestamps=1
&gt; EOF
</code></pre>
<ol start="5">
<li>准备 <code>php-fpm.conf</code> 文件</li>
</ol>
<pre><code class="language-shell"># cat www.conf

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
</code></pre>
<p>准备工作完成,接下来创建Dockerfile进行构建。</p>
<h2 id="4-创建dockerfile">4 创建Dockerfile</h2>
<pre><code class="language-shell"># touch Dockerfile
</code></pre>
<p>Dockerfile文件内容如下:</p>
<pre><code class="language-dockerfile">FROM php:7.2.34-fpm-alpine
LABEL MAINTAINER="syushin moliyoyoyo@163.com"
ENV TZ "Asia/Shanghai"
ENV TERM xterm
# 默认关闭opcode
ENV OPCODE 0

COPY ./conf.d/ $PHP_INI_DIR/conf.d/
COPY composer.phar /usr/local/bin/composer
COPY www.conf /usr/local/etc/php-fpm.d/www.conf
# 创建www用户
RUN addgroup -g 1000 -S www &amp;&amp; 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++ 等编译辅助类库,完成编译后删除
RUN apk add --no-cache $PHPIZE_DEPS \
    &amp;&amp; apk add --no-cache libstdc++ libzip-dev vim\
    &amp;&amp; apk update \
    &amp;&amp; pecl install redis-5.3.4 \
    &amp;&amp; pecl install zip \
    &amp;&amp; pecl install swoole \
    &amp;&amp; docker-php-ext-enable redis zip swoole\
    &amp;&amp; apk del $PHPIZE_DEPS
# docker-php-ext-install 指令已经包含编译辅助类库的删除逻辑
RUN apk add --no-cache freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev \
    &amp;&amp; apk update \
    &amp;&amp; docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/ \
    &amp;&amp; docker-php-ext-install -j$(nproc) gd \
    &amp;&amp; docker-php-ext-install -j$(nproc) pdo_mysql \
    &amp;&amp; docker-php-ext-install -j$(nproc) opcache \
    &amp;&amp; docker-php-ext-install -j$(nproc) bcmath \
    &amp;&amp; docker-php-ext-install -j$(nproc) mysqli \
    &amp;&amp; chmod +x /usr/local/bin/composer

RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
EXPOSE 9000
ENTRYPOINT ["php-fpm"]
</code></pre>
<p>说明:</p>
<ul>
<li><code>PHP_INI_DIR</code> : 这个环境变量的定义在php基础镜像的Dockerfile有定义,变量值是 <code>/usr/local/etc/php</code></li>
<li><code>PHPIZE_DEPS</code> :这个也是定义在基础镜像Dockerfile中,包含了扩展编译安装时需要但是php运行不需要的linux软件库。我们需要把它们挑选出来,在编译完扩展之后删除。变量值: <code>autoconf dpkg-dev dpkg</code></li>
<li><code>php-fpm.conf</code> 配置文件在 <code>/usr/local/etc/</code> 目录下</li>
<li><code>www.conf</code> 配置文件在 <code>/usr/local/etc/php-fpm.d</code> 目录下</li>
</ul>
<p>可以编写一个脚本进行构建,好处是以后可以通过查看脚本知道哪个标签的镜像是此次构建的。</p>
<pre><code># cat build-command.sh
#!/bin/bash
docker build -t php-7.2.34-fpm-alpine:v1 .
</code></pre>
<p>执行构建</p>
<pre><code class="language-shell"># sh build-command.sh
</code></pre>
<p>稍等时间即可看到构建完成</p>
<pre><code class="language-shell"># 编译完成后,镜像体积是160m
# docker images
REPOSITORY                  TAG               IMAGE ID            CREATED             SIZE
php-7.2.34-fpm-alpine         v1                  fb3d05761dfa      2 hours ago         160MB

# 检查扩展
# docker run php-7.2.34-fpm-alpine:v1 php -m

bcmath
Core
ctype
curl
date
dom
fileinfo
filter
ftp
gd
hash
iconv
json
libxml
mbstring
mysqlnd
openssl
pcre
PDO
pdo_mysql
pdo_sqlite
Phar
posix
readline
redis
Reflection
session
SimpleXML
sodium
SPL
sqlite3
standard
swoole
tokenizer
xml
xmlreader
xmlwriter
Zend OPcache
zip
zlib


Zend OPcache

</code></pre>
<p>这样,一个镜像就构建完成了。</p>
<h2 id="5-推送到harbor镜像仓库">5 推送到Harbor镜像仓库</h2>
<p>一般在企业,自己构建好镜像后,需要推送到自己的私有仓库。我这里本地有个harbor的私有仓库,仓库地址:http://192.168.18.100</p>
<p>并且仓库上面有个项目叫 <code>lnmp</code>,存放相关镜像。</p>
<p><img src="https://img2020.cnblogs.com/blog/1686603/202106/1686603-20210630173649385-1271723760.png" alt="" loading="lazy"></p>
<p>将上面构建的镜像推送到harbor仓库:</p>
<pre><code class="language-shell"># Docker登录仓库
# docker login 192.168.18.100:80
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

# 给镜像打标签
# docker tag php-7.2.34-fpm-alpine:v1 192.168.18.100:80/lnmp/myphp:7.2

# 上传镜像
# docker push 192.168.18.100:80/lnmp/myphp:7.2
The push refers to repository
7dfdf785728d: Pushed
3ec4258bee2c: Pushed
f01174c9f645: Pushing [================&gt;                                  ]24.29MB/73.92MB
c21c6905870c: Pushed
752870d17619: Pushed
0e7d6edc15aa: Pushed
c9685eb5cbc9: Pushed
e07b1aa3ce21: Pushed
69e56c02a5f3: Pushed
5ce5d9de209b: Pushed
ee81ef73796d: Pushed
738a430a6dab: Pushing [==============&gt;                                    ]15.51MB/53.39MB
7d12c6e1d8f1: Pushing [==================================================&gt;]4.096kB
be80e727dd27: Waiting
24e52497c24f: Waiting
86d905c1f58e: Waiting
22573737ba76: Waiting
777b2c648970: Waiting

</code></pre>
<p>等待推送完成,即可看到仓库上已经有该镜像了。<br>
<img src="https://img2020.cnblogs.com/blog/1686603/202106/1686603-20210630173702636-236132717.png" alt="" loading="lazy"></p>
<h2 id="6-参考资料">6 参考资料</h2>
<ul>
<li>制作一个生产环境可用的PHP基础镜像 泛黄的日历</li>
<li>Dockerhub 官方php镜像</li>
<li>Alpine 系统简介</li>
</ul><br><br>
来源:https://www.cnblogs.com/syushin/p/14955582.html
頁: [1]
查看完整版本: 基于官方php:7.2.34-fpm-alpine镜像构建生产可用镜像