docker VS 虚拟机
docker 不仅仅是虚拟机,具体细节我也不清楚,但这并不影响对docker的理解。把docker理解为:可以独立运行的一个进程,就好了。
比如说,我只需要一个PHP-FPM来运行PHP,而我的WEB服务器可以是在我MAC本地,也可以是存在另外的地方,可以是nginx,也可以是apache等。而不像虚拟机,一整个环境都是搭建好的。虽然docker也可以搭建这样一个环境,但是官方还是强烈建议服务粒度要细,一个容器只做一件事情。
一开始我也是范了这个错误,把docker当成vbox一样的虚拟机,装环境,然后做文件夹共享,然后开发。这样的话,docker的优势就没有体现出来。特别是在win7下,docker还是基于vbox的,那会儿还感觉,docker反而把事情搞得麻烦了,还不如直接vbox来的直接。
关于镜像
基于centos自行搭建
线上环境,我用centos6.9居多。然后编译环境(php7.2+php-fpm),结果弄出来的镜像1.45G,吓到我了。然后从网上找了一些docker镜像瘦身的方法。我简单列了一下,可看看最后的说明。
使用官方镜像
像php,nginx等常用环境,官方都提供dockerfile(各种版本的,如基于alpine的php-cli等等),总有一款适合你。后期有更新,也可以跟上官方的脚步。同时也可以基于官方的基础镜像,自己再进行修改和扩充。
原则:线上环境,在哪个系统下使用,就在哪个系统下编译
PHP的环境,我用上述自行搭建的方式,然后精简一下,确实是可以跑起来的。但是,nginx这样弄就出错了,缺少一个nginx.pm这个文件,ldd没有显示出来
所以在线上环境,请勿使用系统移植这种方式
想要镜像小,推荐使用alpine这个系统,原始才5M大小,然后可以自行编译环境
个人推荐使用官方的构建,虽然我也不习惯目录的存放位置等。但是,一旦修改,那么后续就得自己维护,无形中增加了成本。
基于官方alpine的php-fpm二次构建
官方dockerfile的github网址,请点击这里
官方提供的是最基本的,官方提供一些基本的扩展直接安装,如:pdo_mysql,pdo_gd等,也提供pecl安装。而我用的环境里面有phalcon,redis,所以需要自行编译。(说明:按官方的方法安装redis扩展,会安装不上,提示一个.h文件不存在,具体什么文件,我一下子也忘了)
具体过程请见文章后面的说明
Nginx + PHP-FPM
上面说了,一个容器就做一个服务。那么,Nginx和FPM,该如何通信呢?如果是在一台机器上,首选unix socket,都不在一台机器上,那么可以使用TCP方式。当然,docker有Volume这个概念,也可以实现unix socket。
docker run --rm -d --name fpm -v /Docker/app/www:/app:ro alpine_php-fpm:v1
docker run --rm -d --name app --link fpm -v /Docker/app/www:/app:ro -v /Docker/app/server/config/nginx.conf:/etc/nginx/conf.d/app.conf:ro -p 9091:80 nginx1.14
这里是使用TCP通信,app(nginx)通过--link,链接到fpm(php-fpm)。
请注意,fpm也需要将文档目录用-v挂载进来,否则访问php文件的时候,会提示:File Not Found
这里分享一个删除所有停止的容器的命令
docker ps -a | grep "Exited" | awk '{print $1}' | xargs docker rm
多个docker容器管理
既然一个容器只干一件事情,那么跑一个php的网站,至少需要3个容器(php,nginx,mysql),那么该如何统一部署管理这些容器呢?
简单一点,docker-compose,将一个项目的所用到的镜像组合起来,然后使用docker-compose up启动即可
当然再复杂一些,就需要用上k8s这类的了,这也是我需要学习的一个东西
附件
docker 瘦身方法
-
将dockerfile里面的命令合并,减少docker文件的Layers,达到减少镜像容量的目的。
-
将程序运行所需要的库全部找出来,找个mini的linux系统(如:busybox),打包成tar,然后将tar文件做成镜像。
#/usr/bin
mkdir /mini
cd /mini
mkdir bin etc dev dev/pts lib usr proc sys tmp var
mkdir -p usr/lib64 usr/bin usr/local/bin
mkdir app data
touch etc/resolv.conf
cp /etc/nsswitch.conf etc/nsswitch.conf
echo root:x:0:0:root:/:/bin/sh > etc/passwd
echo root:x:0: > etc/group
echo www:x:1001:1001:root:/:/bin/sh >> etc/passwd
echo www:x:1001: >> etc/group
ln -s lib lib64
ln -s bin sbin
curl -o /sbin/busybox https://busybox.net/downloads/binaries/1.21.1/busybox-x86_64
chmod +x /sbin/busybox
cp /sbin/busybox bin
busybox --install -s bin
cd /mini && cp /lib64/ld* ./lib64 \
&& ldd /opt/php/bin/php | awk -F '=>' '{print $2}' | awk '{print $1}' | grep "usr" | xargs -i cp {} ./usr/lib64/ \
&& ldd /opt/php/bin/php | awk -F '=>' '{print $2}' | awk '{print $1}' | grep -v "usr" | grep "lib64" | xargs -i cp {} ./lib64/
cp -R /opt/php /mini/opt/
php-fpm 安装 phalcon
我是将phalcon,igbinary,installer这三个文件下载下来(在镜像里面下,太慢,跟网络有关),通过COPY的方式到镜像里面。installer是指:php composer的installer
dockerfile如下:
FROM alpine_php72_fpm:v1
COPY ./alpine_php_ext.sh \
./v3.3.2.zip \
./igbinary-2.0.6.tgz \
./php.ini \
./installer \
/opt/src/
RUN chmod +x /opt/src/alpine_php_ext.sh \
&& /opt/src/alpine_php_ext.sh
EXPOSE 9000
ENTRYPOINT ["php-fpm"]
alpine_php_ext.sh如下:
apk update \
&& apk add --no-cache --virtual .build-deps bash autoconf gcc libc-dev make re2c libpng libpng-dev \
&& srcDir="/opt/src" && phalconVer="3.3.2" && igbVersion="igbinary-2.0.6" && redisVersion="redis-4.0.2" && xdebugVersion="xdebug-2.6.0" \
&& if [ ! -d $srcDir ]; then
mkdir $srcDir
fi \
&& cd $srcDir \
\
&& unzip v${phalconVer}.zip \
&& cd ./cphalcon-${phalconVer}/build/php7/64bits/ \
&& phpize \
&& ./configure \
&& make && make install \
&& echo "phalcon installed" && sleep 3s \
&& cd $srcDir \
\
&& tar xf ${igbVersion}.tgz \
&& cd ${igbVersion} \
&& phpize \
&& ./configure \
&& make && make install \
&& cd $srcDir \
&& wget -c "https://pecl.php.net/get/${redisVersion}.tgz" -t 3 -T 3 \
&& tar xf ${redisVersion}.tgz \
&& cd ${redisVersion} \
&& phpize \
&& ./configure --enable-redis-igbinary=yes --enable-redis-lzf=yes \
&& make && make install \
&& cd $srcDir \
&& wget "https://pecl.php.net/get/${xdebugVersion}.tgz" -t 3 -T 3 \
&& tar xf ${xdebugVersion}.tgz \
&& cd ${xdebugVersion} \
&& phpize \
&& ./configure \
&& make && make install \
&& cd $srcDir \
\
&& php installer --install-dir=/usr/bin --filename=composer \
&& docker-php-ext-install pdo_mysql \
&& docker-php-ext-install gd \
&& docker-php-ext-enable phalcon xdebug \
&& echo "ext-enable" \
&& sed -i -e "s/;daemonize\s*=\s*yes/daemonize = no/g" /usr/local/etc/php-fpm.conf \
&& echo "sed" \
&& find /usr/local/bin /usr/local/sbin -type f -perm +0111 -exec strip --strip-all '{}' + || true \
&& echo "strip" \
&& docker-php-source delete \
&& echo "delete" \
&& runDeps="$( \
scanelf --needed --nobanner --format '%n#p' --recursive /usr/local \
| tr ',' '\n' \
| sort -u \
| awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' \
)" \
&& apk add --no-cache --virtual .php-rundeps $runDeps \
&& apk del .build-deps \
\
&& rm -rf /tmp/pear ~/.pearrc \
&& apk del bash autoconf gcc libc-dev make re2c libpng libpng-dev \
&& cp ${srcDir}/php.ini /usr/local/etc/php/ \
&& rm -rf /opt/*
网友评论