美文网首页
通过Dockerfile来构建优化容器

通过Dockerfile来构建优化容器

作者: lizilong007 | 来源:发表于2016-12-10 11:47 被阅读0次

回顾上一篇的操作上一篇:docker实践

上一篇文章中我们使用了daocloud.io/centos这个基础镜像,在基础镜像上面通过/bin/bash的交互模式启动容器,然后在上面做了一系列的操作,来部署我们的开发环境必备的软件nginx+php5.3+phpbrew+php7.1,部署完成后,我们使用了docker commit命令提交了这个镜像,用来作为以后快速部署测试,开发,生产环境的统一镜像,保证了系统的一致性。

但是这样部署是有很大的问题的:

1.构建的镜像特别的大
2.别人拿到这个镜像,无法了解构建流程

先说第一个问题

简单的说其实docker有点类似于git,git是管理代码,docker是管理容器,git的每一次提交都会把这一次我门做的所有的操作记录下来,以便于回滚和查询。docker也是类似,当我们提交的时候,这次提交的每一个命令都回生成一个layer(层),用于记录这个命令前后的文件变化。事实上造成docker镜像过大,主要原因就是layer多,也就是我们的命令执行过多,那么解决办法也就是要简化我们的命令数。

再说第二个问题

我们需要一个文件来记录,这个镜像装了哪些东西,启动了什么服务,做了什么修改,并且可以正确的构建出容器。比如php的composer ,javascript的npm,java的maven ,当写好构建项目所有的依赖,和操作,一键执行就可以构建我们想要的项目。

引出本文主角Dockerfile!

废话不多说,我们直接上代码,代码中涉及到的命令很好理解,大家也可以自行查询.dockerfile 命令介绍
# 表明我们需要的基础镜像
FROM daocloud.io/centos:6
# 作者
MAINTAINER Ice Dragon <517icedragon@gmail.com>
# 这里为了尽可能少的命令个数,我们把所有命令拼接起来
#install nginx/php-5.3/phpbrew/php-7.1 +default +mysql +pdo +fpm +curl +memcached
RUN yum install -y gcc \
    libxml2-devel \
    libxslt-devel \
    bzip2-devel \
    m4 \
    autoconf \
    libcurl-devel \
    libmemcached-devel \
    cyrus-sasl-devel \
    epel-release \
    libmcrypt \
    libmcrypt-devel \
    mcrypt \
    mhash \
    readline-devel \
    openssl* \
    wget \
    gcc+ \
    gcc-c++ \
    libtool && ln -s /usr/lib64/libssl.so /usr/lib/ && \
    rpm -ivh http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm \
    && yum install -y nginx && yum install -y php && \
    curl -L -O https://github.com/phpbrew/phpbrew/raw/master/phpbrew && \
    chmod +x phpbrew && \
    mv phpbrew /usr/bin/phpbrew && \
    cd ~ && phpbrew init && \
    echo "[[ -e ~/.phpbrew/bashrc ]] && source ~/.phpbrew/bashrc" >> ~/.bashrc && \
    source ~/.phpbrew/bashrc && \
    wget http://www.atomicorp.com/installers/atomic && \
    sh ./atomic && \
    yum  install -y  php-mcrypt  libmcrypt  libmcrypt-devel supervisor openssh-server && \
    phpbrew install php-7.1.0 as php-7.1 +default +mysql +pdo +fpm +curl && \
    phpbrew switch php-7.1 && \
    wget https://launchpad.net/libmemcached/1.0/1.0.18/+download/libmemcached-1.0.18.tar.gz && \
    tar -zxvf libmemcached-1.0.18.tar.gz && \
    cd libmemcached-1.0.18 && \
    ./configure && \
    make && \
    make install && \
    phpbrew ext install https://github.com/php-memcached-dev/php-memcached php7 -- --disable-memcached-sasl && \
    # 配置php短标签和fpm监听端口
    # Update the php-fpm config file, php.ini enable <? ?> tags and quieten logging.
    sed -i "s/listen = \/root\/\.phpbrew\/php\/php-7\.1\/var\/run\/php-fpm\.sock/listen = 127\.0\.0\.1:9000/" /root/.phpbrew/php/php-7.1/etc/php-fpm.d/www.conf && \
    sed -i "s/short_open_tag = Off/short_open_tag = On/" /root/.phpbrew/php/php-7.1/etc/php.ini && \
    mkdir -p /etc/nginx/vhosts && rm -f /etc/nginx/nginx.conf && \
    # 配置ssh这样可以用ssh key 登录到容器
    # Config ssh login container
    sed -i "s/#RSAAuthentication yes/RSAAuthentication yes/" /etc/ssh/sshd_config && \
    sed -i "s/#PubkeyAuthentication yes/PubkeyAuthentication yes/" /etc/ssh/sshd_config && \
    ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -P '' && \
    ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -P '' && \
    ## Public keys dir
    mkdir -p ~/.ssh/id_rsa.pub/

# 这里我们可以使用ENV 来配置一些变量给容器内的程序使用
# Manually set up the nginx log dir,php.ini and php-fpm config file environment variables
ENV NGINX_LOG_DIR /var/log/nginx
ENV PHPINI_FILE_PAHT /root/.phpbrew/php/php-7.1/etc
ENV PHPFPM_FILE_PATH /root/.phpbrew/php/php-7.1/etc/php-fpm.d

# 这里表示我们的容器对外可以提供的端口,只是一种说明,并不能真正达到端口映射的功能,需要端口映射的话,要在启动的时候加 `-p 80:80` 类似这样进行映射 
# Expose nginx ssh
EXPOSE 80
EXPOSE 22

# 把一些我们写好的配置文件,添加到容器中
# Update the default nginx site with the config we created.
ADD config/nginx.conf /etc/nginx/nginx.conf
ADD config/upstream.conf.enabled /etc/nginx/conf.d/upstream.conf.enabled
ADD config/vhosts/* /etc/nginx/vhosts/
# Update the enable public keys
ADD config/id_rsa/*.pub.enabled /root/.ssh/id_rsa.pub/

# 这里配置我们的启动后执行的命令 `RUN`是在构建容器时执行 `CMD` 是在启动容器时执行。这里有个事情要注意,当执行启动容器的时候,容器会在执行`CMD`命令后立刻终止掉容器,所以要想让容器一直运行的话,必须启动一个不会挂起或终止的进程,这里我使用`/usr/sbin/sshd -D`这个命令,也可以用类似`tail -F /var/log/nginx/error.log`这样的命令
# start-up nginx and fpm and ssh
CMD service nginx start && \
    phpbrew init && \
    [[ -e ~/.phpbrew/bashrc ]] && \
    source ~/.phpbrew/bashrc && \
    phpbrew use php-7.1 && \
    phpbrew fpm start && \
    cat ~/.ssh/id_rsa.pub/*.pub.enabled > ~/.ssh/authorized_keys && \
    chmod 600 ~/.ssh/authorized_keys && \
    /usr/sbin/sshd -D

最后我非常感谢daocloud.io提供的云端免费测试功能,在云端可以快速构建,祝daocloud.io越做越好,同时可以为广大开发者提供更好的服务。
这是本项目的github地址, 更多详情请看README.md,欢迎大家fork && issue GitHub lizilong007/docker-partner

看一下使用dockerfile后镜像大小对比(dockerfile中安装的软件比我们上一篇安装的还要多)

$ docker images
REPOSITORY                     TAG                 IMAGE ID            CREATED             SIZE
daocloud.io/lizilong/partner   latest              f5bda9732147        12 hours ago        1.492 GB
daocloud.io/centos             v3                  98ef1bdd1555        43 hours ago        2.167 GB

相关文章

网友评论

      本文标题:通过Dockerfile来构建优化容器

      本文链接:https://www.haomeiwen.com/subject/yunymttx.html