PHP经验分享码农的世界程序员

Docker 使用心得(1)

2018-05-20  本文已影响20人  陈晓风

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 瘦身方法

  1. 将dockerfile里面的命令合并,减少docker文件的Layers,达到减少镜像容量的目的。

  2. 将程序运行所需要的库全部找出来,找个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/*
上一篇 下一篇

猜你喜欢

热点阅读