在使用Docker的过程当中,咱们除了从Docker Hub上下载已经作好的镜像,不少时候须要咱们本身制做镜像。下面想在这个文章中说明一下镜像的制做方法。php
制做镜像的方式主要有两种:mysql
经过docker commit 制做镜像linux
经过docker build 制做镜像sql
这两种方式都是经过改进已有的镜像来达到本身的目的。制做基础镜像,会在另一篇文章“从零开始制做基础镜像”中介绍。docker
docker commitshell
docker commit 是往版本控制系统里提交一次变动。使用这种方式制做镜像,本质上是运行一个基础镜像,而后在基础镜像上进行软件安装和修改。最后再将改动提交到版本系统中。apache
选择基础镜像ubuntu
基础镜像的选择要结合本身的需求。能够选择已有的应用镜像来改造,也能够选择Ubuntu,Debian,OpenSuse这类基础系统镜像bash
咱们以ubuntu为例子来讲明curl
步骤1:运行ubuntu 镜像
docker run -i -t ubuntu /bin/bash
步骤2:安装软件并修改软件配置, 好比:安装apache2
apt-get -yqq update
apt-get -y install apache2
安装完成后,对apache2进行配置和修改
步骤3:退出docker并保存镜像
使用“exit”命令退出容器
运行docker comit 命令, 进行保存
docker commit 61412230ae46 own-apache2
docker commit 命令参数说明
命令格式
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
OPTIONS:
-a, --author= 提交的镜像做者
-c, --change=[] Apply Dockerfile instruction to the created image, 没用过
-m, --message= 提交时的说明文字
-p, --pause=true 在commit时,将container 暂停
CONTAINER:
可使用container 的名字或者ID
REPOSITORY
指定镜像仓库,上述例子中,指定的是本地存储
能够指定远程镜像仓库,如docker hub。也可自建仓库来存放image
TAG:
镜像TAG
docker build
使用docker build建立镜像须要编写Dockerfile.
步骤:
编写本身的Dcokerfile
运行docker build 命令打包镜像
仍然以apache打包为例子。如下是Dockerfile的例子
FROM ubuntu:latest
MAINTAINER sky
#Add 163 mirror for apt
ADD sources.list /etc/apt/sources.listADD .bashrc /root/.bashrcENV DEBIAN_FRONTEND noninteractive# PackagesRUN rm -rf /var/lib/apt/listsRUN apt-get update -q --fix-missingRUN apt-get -y upgrade#ubuntu wwwRUN apt-get install -y apache2 curl libapache2-mod-php5 php5-curl php5-gd php5-mysql rsync mysql-client -qqRUN apt-get autocleanRUN rm -rf /var/lib/apt/lists/*# Setup environmnt for apache's init scriptENV APACHE_CONFDIR /etc/apache2ENV APACHE_ENVVARS $APACHE_CONFDIR/envvarsENV APACHE_RUN_USER www-dataENV APACHE_RUN_GROUP www-dataENV APACHE_RUN_DIR /var/run/apache2ENV APACHE_PID_FILE $APACHE_RUN_DIR/apache2.pidENV APACHE_LOCK_DIR /var/lock/apache2ENV APACHE_LOG_DIR /var/log/apache2ENV LANG CRUN mkdir -p $APACHE_RUN_DIR $APACHE_LOCK_DIR $APACHE_LOG_DIRRUN find "$APACHE_CONFDIR" -type f -exec sed -ri ' \ s!^(\s*CustomLog)\s+\S+!\1 /proc/self/fd/1!g; \ s!^(\s*ErrorLog)\s+\S+!\1 /proc/self/fd/2!g; \' '{}' ';'EXPOSE 80CMD ["apache2", "-DFOREGROUND"]
编辑完成后,在与Dockerfile同一目录下运行docker build 命令
docker build -t apache-img .
若是没有命令出错,docker build会持续运行直到镜像建立完成
而建立的过程本质上是运行一个镜像,而后在镜像中按序执行在Dockerfile中的命令,直到执行结束。
若是中间有命令执行失败,镜像建立会中止。这时就须要看log,并修改Dockerfile,而后再次执行docker build
注:两种镜像建立方式的对比:
docker commit
docker build
难度相对容易,适合新手和对Linux不熟悉的用户相对难,要求有必定的linux和脚本基础知识
文档化
文档化在经过其余文件来实现
Dockerfile自己就是比较好的文档,可读和可理解性比较强。也可配合其余文档带来详细说明
升级,维护
后续升级和维护麻烦,须要再次运行镜像并对内部软件进行升级或者安装新软件增长特性
后续升级和维护会相对简单,能够直接在dockerfile中更改并增长新特性
具体选择哪一种方式来制做镜像须要结合实际状况来选择
Dockerfile 关键字详解
FROM
FROM用来指定基础包。在上面的例子中,基础包用的是ubuntu。
MAINTAINER
镜像做者信息,或者维护人员信息
ADD
将文件拷贝到Container内文件系统对应的路径
格式 ADD <src file> <dst file>
全部拷贝到Container中的文件和文件夹权限为0755,uid和gid为0
若是须要修改owner用户或者权限,须要使用RUN进行修改
ADD文件,文件路径要在docker build<PATH>中指定的<PATH>下
RUN
建立镜像时执行
ENV
用来设置环境变量
EXPOSE
Container内部服务开启的端口
主机上若是要使用,还须要在启动Container时,作host-container的商品映射
使用EXPOSE后,一些自动化布署工具能够直接读取这个信息,自动进行端口映射
EXPOSE能够有多条,指定多个端口
WORKDIR
切换工做目录,可进行屡次切换(至关于cd命令)
切换目录对RUN,CMD,ENTRYPOINT有效
USER
执行container的用户,如未指定,则默认使用root用户
ENTRYPOINT
Container启动时执行的命令,一个Dockerfile中只能有一条ENTRYPOINT
ENTRYPOINT没有CMD的可替换特性
CMD
Container 启动时执行的命令,一个Dockerfile 中只能有一条CMD命令,若是有多条则只执行最后一条CMD
若是有多条命令但愿在启动后执行,能够考虑使用shell 脚本
与ENTRYPOINT的区别
CMD的主要用途是为可执行的container提供默认命令
CMD在运行时是可替换的,好比
在ubuntu中,CMD指定的是/bin/bash。默认状况下运行ubuntu,container中的/bin/bash会被执行
若是使用docker run指定运行命令,那CMD会被替换掉
如:docker run ubuntu /bin/echo "this is a echo". 这时,container 启动后会执行echo 而不是/bin/bash了
ENTRYPOINT是不会替换的,若是在ubuntu镜像中加入ENTRYPOINT,那ENTRYPOINT在启动后会先被执行
CMD能够为ENTRYPOINT来提供参数
例子:
FROM ubuntu:14.10
ENTRYPOINT ["top", "-b"]
CMD ["-c"]
VOLUME
语法:VOLUME [PATH]
VOLUME指令用来设置一个挂载点,能够用来让其余容器挂载以实现数据共享或对容器数据的备份、恢复或迁移
能够将本地文件夹或者其余Container的文件夹挂载到Container中