首页 > 其他 > 详细

业务镜像的编写————Dockerfile篇

时间:2020-01-06 20:44:59      阅读:89      评论:0      收藏:0      [点我收藏+]

基础镜像,接触docker的人基本上都知道这个概念,用来跑业务,跑环境的基础,举个例子:java业务的需要用到java环境的基础镜像,一般会在镜像使用的时候选择:

java:8或者apline-java:8或者openjdk:8之类的,如果业务要求没有特别高的情况下,一般都是采用官方写好的镜像,毕竟官方优化要比我们自己写和自己优化要好很多。

而在这里,我要提出的是一个特殊的情况,比如一开始就定下的代码运行目录,一开始就决定好的读取代码目录的顺序等等,这种对镜像中某些路径和目录有特殊要求的情况,如果单单使用官方的镜像,在很多地方要遵循官方镜像的编写原则,更改自己的代码,在代码量比较大或者代码模块较多的情况下,会增加很大的工作量。在这个时候就需要自己编写属于自己的业务基础镜像,集成定制属于自己的镜像,当然你也可以基于官方镜像进行更改或者commit。在很多情况下,方便管理和便于修改是硬需求,于是通过Dockerfile的方式生成业务基础镜像的方式,要比commit好很多。以下是我写的一个例子,基于centos7编写的php+nginx的基础镜像(友情提示,写Dockerfile最好是熟悉各种linux的安装方式):

FROM centos:7   #这里是基于centos系列的基础镜像做的包,如果只写centos很有可能拉取的是centos8
MAINTAINER adif0028<longliu2long@163.com>    #写明作者,这句可有可无
COPY ustc.repo /etc/yum.repos.d/ustc.repo    #以下几个copy是把下载好和已经配置好的东西放到刚需目录和路径下。下面会有个公共目录放复制进去的东西和下载的东西。
COPY run.sh /run.sh
COPY php.ini /usr/local/php/etc/php.ini
COPY php-fpm.conf /usr/local/php/etc/php-fpm.conf
COPY nginx.conf /usr/local/nginx/conf/nginx.conf
COPY index.php /usr/local/nginx/html/index.php
COPY www-php.conf /usr/local/php/etc/php-fpm.d/www-php.conf
COPY rsyslog.conf /etc/rsyslog.conf
COPY php-7.0.31.tar.gz /data/php-7.0.31.tar.gz   #这里是指定自己所需的php版本,可以在线下载,我是嫌下载太慢自己本地拷贝进去
RUN yum repolist && yum install wget -y && cd /data && tar -xf php-7.0.31.tar.gz     && mv /etc/yum.repos.d/CentOS-* /data && yum clean all && yum repolist && yum install nc -y && yum install rsyslog -y && yum install ImageMagick-devel -y     && yum install libssh2-devel -y && yum install gcc-c++ -y && yum install cyrus-sasl-devel -y     && wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo && yum repolist && yum install autoconf -y     && wget http://nginx.org/download/nginx-1.16.1.tar.gz && wget https://pecl.php.net/get/msgpack-2.0.2.tgz && wget https://pecl.php.net/get/yar-2.0.4.tgz && wget https://pecl.php.net/get/yaconf-1.0.7.tgz     && wget https://pecl.php.net/get/redis-4.1.0.tgz && wget https://pecl.php.net/get/imagick-3.4.3.tgz && wget https://pecl.php.net/get/swoole-4.0.2.tgz     && wget https://pecl.php.net/get/ssh2-1.1.2.tgz && wget https://pecl.php.net/get/mongodb-1.5.3.tgz && wget https://pecl.php.net/get/grpc-1.19.0.tgz     && wget https://pecl.php.net/get/protobuf-3.7.1.tgz && wget https://pecl.php.net/get/SeasClick-0.1.0.tgz     && yum install gcc -y && yum install libxml2-devel -y && yum install openssl-devel -y && yum install curl-devel -y && yum install libjpeg-devel -y     && yum install libpng-devel -y && yum install libXpm-devel -y && yum install freetype-devel -y && yum install libmcrypt-devel -y && yum install make -y \     #以上是更换yum源,安装php所需依赖和业务所需php模块
    && cd /data/php-7.0.31 \     #这里就是公共目录里的php了。
    && CONFIG="\                 #Dockerfile是支持变量定义的,这里是定义了php的安装路径等变量。
        --prefix=/usr/local/php         --with-config-file-path=/usr/local/php/etc         --with-config-file-scan-dir=/usr/local/php/etc/php.d         --disable-ipv6         --enable-bcmath         --enable-calendar         --enable-exif         --enable-fpm         --with-fpm-user=www         --with-fpm-group=www         --enable-ftp         --enable-gd-jis-conv         --enable-gd-native-ttf         --enable-inline-optimization         --enable-mbregex         --enable-mbstring         --enable-mysqlnd         --enable-opcache         --enable-pcntl         --enable-shmop         --enable-soap         --enable-sockets         --enable-static         --enable-sysvsem         --enable-wddx         --enable-xml         --with-curl         --with-gd         --with-jpeg-dir         --with-freetype-dir         --with-xpm-dir         --with-png-dir         --with-gettext         --with-iconv         --with-libxml-dir         --with-mcrypt         --with-mhash         --with-mysqli         --with-pdo-mysql         --with-pear         --with-openssl         --with-xmlrpc         --with-zlib         --disable-debug         --disable-phpdbg          "     && CONFIGU="\                  #这里是定义了nginx安装路径等等相关变量
        --prefix=/usr/local/nginx         --sbin-path=/usr/sbin/nginx         --modules-path=/usr/lib/nginx/modules         --conf-path=/usr/local/nginx/conf/nginx.conf         --error-log-path=/var/log/nginx/error.log         --http-log-path=/var/log/nginx/access.log         --pid-path=/var/run/nginx.pid         --lock-path=/var/run/nginx.lock         --http-client-body-temp-path=/var/cache/nginx/client_temp         --http-proxy-temp-path=/var/cache/nginx/proxy_temp         --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp         --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp         --http-scgi-temp-path=/var/cache/nginx/scgi_temp         --user=www         --group=www         --with-http_stub_status_module         --with-http_v2_module         --with-ipv6         --with-http_gzip_static_module         --with-http_realip_module         --with-http_flv_module         --with-http_ssl_module           "     && ./configure $CONFIG \        #注意上下文的变量对应,进行config编译。记住一定要在源码目录里进行
    && make && make install \       #编译安装。
    #&& /usr/local/php/bin/pear install channel://pear.php.net/PHP_Archive-0.12.0 \  #这一步其实是针对php的一个排错,但是由于网络原因导致这里经常卡掉镜像,我就去掉了因为不影响使用。
    && cp /data/php-7.0.31/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm && chmod a+x /etc/init.d/php-fpm && cp /usr/local/php/bin/php /usr/sbin/     && groupadd -r www && useradd -r -g www -s /bin/false -M www && cd /data/php-7.0.31/ext/zip && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data/php-7.0.31/ext/opcache && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf msgpack-2.0.2.tgz && cd /data/msgpack-2.0.2 && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf yar-2.0.4.tgz && cd /data/yar-2.0.4 && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf yaconf-1.0.7.tgz && cd /data/yaconf-1.0.7 && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf redis-4.1.0.tgz && cd /data/redis-4.1.0 && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf imagick-3.4.3.tgz && cd /data/imagick-3.4.3 && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf swoole-4.0.2.tgz && cd /data/swoole-4.0.2 && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf ssh2-1.1.2.tgz && cd /data/ssh2-1.1.2 &&  /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf mongodb-1.5.3.tgz && cd /data/mongodb-1.5.3 && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf protobuf-3.7.1.tgz && cd /data/protobuf-3.7.1 && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf grpc-1.19.0.tgz && cd /data/grpc-1.19.0 && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install     && cd /data && tar -xf SeasClick-0.1.0.tgz && cd /data/SeasClick-0.1.0 && /usr/local/php/bin/phpize && ./configure --with-php-config=/usr/local/php/bin/php-config && make && make install \ 
#这里往上是创建了一个www用户,然后php模块的编译安装 && mkdir -p /home/wwwlogs/phplog/ && chown -R www:www /home/wwwlogs/phplog/ && mkdir -p /usr/local/nginx/html && chmod a+x /run.sh && mkdir -p /var/cache/nginx \ #这里有个run.sh我会在后面放出来做解释 && chown www:www -R /var/cache/nginx && chown www:www -R /usr/local/nginx && cd /data && tar -xf nginx-
1.16.1.tar.gz && cd /data/nginx-1.16.1 && ./configure $CONFIGU && make && make install \
#这里是nginx的安装了 && yum remove perl -y && yum remove wget -y && yum remove gcc -y && yum remove make -y && yum remove autoconf -y && yum remove gcc-c++ -y && yum remove kernel-headers -y && yum remove cpp -y && yum clean all && rm -rf /data
/* #删掉一些不影响的功能和数据包,精简镜像 EXPOSE 80 #暴露端口 ENTRYPOINT ["/run.sh"] #执行run.sh CMD ["/bin/sh","-c"] #指定运行bash

上面我做了大概步骤的注释,写Dockerfile优化并且减少体积技巧是:

1,尽量减少RUN层数,增加一层就会使镜像的体积增大不少,我这里只写了一个RUN。不过这一层的RUN也挺大的。

2,因为是centos,基础镜像解压之后200多m,所以尽量的减少依赖的安装。用以减少Dockerfile的体积。

3,除却必要的配置文件,一定要去掉不必要的文件在里面,COPY进去或者下载好的包,安装完成源包删掉,然后清除掉缓存。

4,删掉不必要的组件,比如上例最后,我会删掉不常用或者有漏洞或者删掉不影响镜像使用的包。就像里面的gcc之类的。

5,写的技巧,尽量多使用&& 和  \ 来区分段,我写的自我感觉是很清晰了,当然有大牛欢迎指正。

以上写出的镜像,我精简到最后未压缩的镜像650M左右,运用到公司业务上使运行速度快了一大截。(因为之前的基础镜像未压缩的时候1G多)

关于run.sh的一些东西,脚本如下:

#!/bin/sh
nginx="/usr/sbin/nginx"
NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"
chown -R www:www /dev/shm/
echo "start nginx..."
$nginx -c $NGINX_CONF_FILE

echo "start php-fpm..."
/etc/init.d/php-fpm start --daemonize
/usr/sbin/rsyslogd

tail -f /dev/null                

这里面就是定义了启动程序如何启动,在docker里面是不支持systemd的,当然可以启用,得在容器启动的时候指定参数,这个官网有讲我就不多说了,在自己写的业务里面就不要想着systemd快速启动的法子了,用脚本指定运行程序和配置,启用即可,重点的是下面的tail -f /dev/null这句,因为docker是不支持后台启动程序的(已经成功启用的docker容器不算),需要在docker启动的时候在前台把程序进程hold住,前台hold住需要用输出和tail -f  /dev/null命令了。

以上就是我写公司业务镜像的经验,希望能帮到大家,也欢迎大牛指正共同学习。

业务镜像的编写————Dockerfile篇

原文:https://www.cnblogs.com/adif0028/p/12157888.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!