Dockerfile
Dockerfile
Dockfile指令
docker之Dockerfile指令介绍
Docker通过对于在Dockerfile中的一系列指令的顺序解析实现自动的image的构建
通过使用build命令,根据Dockerfiel的描述来构建镜像
通过源代码路径的方式
通过标准输入流的方式
通过源代码路径
Dockerfile需要放置在项目的根目录位置
在构建的时候,Dockerfile client会把整个context打包发送到Docker Server端,然后由server端负责build镜像,在构建成功后,会删除context目录
docker build -t {镜像名字} {项目路径可以是相对路径}
docker利用Dockerfile来构建新镜像之前,先来了解一下Dockerfile创建中使用到的指令
通过标准输入流:
通过标准输入流的方式获取Dockerfile的内容
client不会打包上传context目录,因此对于一些ADD、COPY等涉及host本地文件复制的操作不能够支持
docker build -t {镜像名字} - < Dockerfile路径
build cache:
Dockerfile中的每一个指令执行完毕后,都会提交为一个image,这样保证了指令之间不会有影响
Dockerfile会尽可能尝试重用之前已经构建的镜像
可以通过在build命令中增加–no-cache的方式来禁用这个cache
Dockerfile指令:
只支持Docker自己定义的一套指令,不支持自定义
大小写不敏感,但是建议全部使用大写
根据Dockerfile的内容顺序执行
FROM:
FROM {base镜像}
必须放在DOckerfile的第一行,表示从哪个baseimage开始构建
MAINTAINER:
可选的,用来标识image作者的地方
RUN:
每一个RUN指令都会是在一个新的container里面运行,并提交为一个image作为下一个RUN的base
一个Dockerfile中可以包含多个RUN,按定义顺序执行
RUN支持两种运行方式:RUN 这个会当作/bin/sh -c “cmd” 运行
RUN [“executable”,“arg1”,。。],Docker把他当作json的顺序来解析,因此必须使用双引号,而且executable需要是完整路径
RUN 都是启动一个容器、执行命令、然后提交存储层文件变更。第一层 RUN command1 的执行仅仅是当前进程,一个内存上的变化而已,其结果不会造成任何文件。而到第二层的时候,启动的是一个全新的容器,跟第一层的容器更完全没关系,自然不可能继承前一层构建过程中的内存变化。而如果需要将两条命令或者多条命令联合起来执行需要加上&&。如:cd /usr/local/src && wget xxxxxxx
CMD:
CMD的作用是作为执行container时候的默认行为(容器默认的启动命令)
当运行container的时候声明了command,则不再用image中的CMD默认所定义的命令
一个Dockerfile中只能有一个有效的CMD,当定义多个CMD的时候,只有最后一个才会起作用
CMD定义的三种方式:
CMD 这个会当作/bin/sh -c “cmd"来执行
CMD [“executable”,“arg1”,…]
CMD [“arg1”,“arg2”],这个时候CMD作为ENTRYPOINT的参数
EXPOSE 声明端口
格式为 EXPOSE <端口1> [<端口2>…]。
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务。在 Dockerfile 中写入这样的声明有两个好处,一个是帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射;另一个用处则是在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。
entrypoint:
entrypoint的作用是,把整个container变成了一个可执行的文件,这样不能够通过替换CMD的方法来改变创建container的方式。但是可以通过参数传递的方法影响到container内部
每个Dockerfile只能够包含一个entrypoint,多个entrypoint只有最后一个有效
当定义了entrypoint以后,CMD只能够作为参数进行传递
entrypoint定义方式:
entrypoint [“executable”,“arg1”,“arg2”],这种定义方式下,CMD可以通过json的方式来定义entrypoint的参数,可以通过在运行container的时候通过指定command的方式传递参数
entrypoint ,当作/bin/bash -c “cmd"运行命令
ADD & COPY:
当在源代码构建的方式下,可以通过ADD和COPY的方式,把host上的文件或者目录复制到image中
ADD和COPY的源必须在context路径下
当src为网络URL的情况下,ADD指令可以把它下载到dest的指定位置,这个在任何build的方式下都可以work
ADD相对COPY还有一个多的功能,能够进行自动解压压缩包
ENV:
ENV key value
用来设置环境变量,后续的RUN可以使用它所创建的环境变量
当创建基于该镜像的container的时候,会自动拥有设置的环境变量
WORKDIR:
用来指定当前工作目录(或者称为当前目录)
当使用相对目录的情况下,采用上一个WORKDIR指定的目录作为基准
USER:
指定UID或者username,来决定运行RUN指令的用户
ONBUILD:
ONBUILD作为一个trigger的标记,可以用来trigger任何Dockerfile中的指令
可以定义多个ONBUILD指令
当下一个镜像B使用镜像A作为base的时候,在FROM A指令前,会先按照顺序执行在构建A时候定义的ONBUILD指令
ONBUILD <DOCKERFILE 指令>
VOLUME:
用来创建一个在image之外的mount point,用来在多个container之间实现数据共享
运行使用json array的方式定义多个volume
VOLUME [”/var/data1”,"/var/data2"]
或者plain text的情况下定义多个VOLUME指令
先查看下本地的镜像,选一个作为base image:
构建lnmp
构建nginx镜像
1、下载nginx源码包到nginx这个目录下:
2、以下是编写好的Dockerfile镜像文件
# bash image
FROM centos:7
# put nginx-1.6.2.tar.gz into /usr/local/src and unpack nginx
ADD nginx-1.6.0.tar.gz /usr/local/src
# running required command
RUN yum install -y gcc gcc-c++ glibc make autoconf openssl openssl-devel
RUN yum install -y libxslt-devel -y gd gd-devel GeoIP GeoIP-devel pcre pcre-devel
RUN useradd -M -s /sbin/nologin nginx
# change dir to /usr/local/src/nginx-1.6.0
WORKDIR /usr/local/src/nginx-1.6.0
# execute command to compile nginx
RUN ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-file-aio --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_geoip_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_auth_request_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_stub_status_module && make && make install
EXPOSE 80
3、查看nginx目录情况:
4、执行docker build进行构建:
docker build -t lnmp/nginx:1.0 .
后面的.代表的是相对路径的当前目录,如果需要全路径则为/root/docker_demo(就是找到Dockerfile文件)
构建成功后,查看新构建的镜像:
5、然后使用构建的镜像启动一个container并开启nginx服务:
docker run -d lnmp/nginx:1.0 /usr/local/nginx/sbin/nginx -g “daemon off;”
构建php镜像
1、下载php源码包到php-fpm这个目录下:
2、构建php镜像的Dockerfile:vim Dockerfile
from centos:7
# put php-5.3.28.tar.gz into /usr/local/src and unpack nginx
ADD php-5.3.28.tar.gz /usr/local/src
# running command
RUN yum -y install wget && yum -y install epel-release && wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo && wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo && yum makecache
RUN yum -y groupinstall "Development Tools"
RUN yum -y install git lrzsz libxml2 libxml2-devel openssl openssl-devel curl curl-devel libjpeg-turbo libjpeg-turbo-devel libpng-devel libpng freetype-devel freetype icu libicu-devel libicu libmcrypt libmcrypt-devel libxslt libxslt-devel php-mysql
RUN useradd -M -s /sbin/nologin php
# change dir to /usr/local/src/php-5.3.28
WORKDIR /usr/local/src/php-5.3.28
# execute command to compile php
RUN ./configure --prefix=/usr/local/php5 --with-gd --with-zlib --with-mysql=mysqlnd --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --with-config-file-path=/usr/local/php5 --enable-mbstring --enable-fpm --with-jpeg-dir=/usr/lib && make && make install
#WORKDIR /usr/local/src/php-5.3.28
#RUN cp /usr/local/php-5.3.28/php.ini-production /usr/local/php/etc/php.ini
RUN mv /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
RUN useradd -M -s /sbin/nologin php
RUN sed -i -e 's\;pid = run/php-fpm.pid\pid = run/php-fpm.pid\g' -e 's\nobody\php\g' -e 's\listen = 127.0.0.1:9000\listen = 0.0.0.0:9000\g' /usr/local/php/etc/php-fpm.conf
RUN sed -i 's\;daemonize = yes\daemonize = no\g' /usr/local/php/etc/php-fpm.conf
EXPOSE 9000
CMD ["/usr/local/php/sbin/php-fpm"]
3、查看php-fpm目录情况:
4、执行docker build进行构建:
docker build -t lnmp/php:1.0 .
构建mysql镜像
1、构建mysql镜像的Dockerfile:vim Dockerfile
FROM centos:centos6
RUN yum install -y mysql-server mysql
ADD ./startup.sh /opt/startup.sh
RUN chmod +x /opt/startup.sh
EXPOSE 3306
CMD ["/bin/bash","/opt/startup.sh"]
2、启动脚本:vim startup.sh
#!/bin/bash
if [ ! -f /var/lib/mysql/ibdata1 ]; then
mysql_install_db
/usr/bin/mysqld_safe &
sleep 10s
mysql -e "grant all privileges on *.* to 'root'@'%' identified by '123456'; FLUSH PRIVILEGES;"
killall mysqld
sleep 10s
fi
/usr/bin/mysqld_safe
正常启动的时候,是没有问题的;当时当我们用-v做持久化的时候,好像说用户就失去对/var/lib/mysql的控制权,所以启动的时候我们要判断初始化才可以用-v来持久化相关目录,这个地方之前搞了好久就是挂不起来,后面原来是这个地方。
3、开始构建mysql镜像:
docker build -t lnmp/mysql:1.0 .
开始启动相关容器
docker run -dit --name php -v /web:/web lnmp/php:1.0
docker run -dit --name web -p 80:80 -v /web:/web --link php:php lnmp/nginx:1.0
docker run -dit --name mysql -p 3306:3306 -v /opt/data:/var/lib/mysql lnmp/mysql:1.0
删除名称或标签为none的镜像docker rmi -f docker images | grep '<none>' | awk '{print $3}'
删除异常停止的docker容器docker rm docker ps -a | grep Exited | awk '{print $1}'
下一篇: 超全spark性能优化总结