docker学习系列(二):使用Dockerfile创建自己的镜像

dockerfile可以允许我们自己创建镜像,通过编写里面的下载软件命令,执行docker build 即可生成镜像文件。

初尝dockerfile

新建一个目录test,然后进入这个目录,创建一个名为Dockerfile的文件,在里面写入以下内容:

FROM alpine:latest
MAINTAINER sbb
CMD echo "hello world"

然后执行下面命令就会生成docker镜像。

$ docker build -t hello-world .

执行docker run hello-world 就会输出hello world了。
可能会有童鞋会问上面写的是什么,下面会根据命令讲解的。

dockerfile命令

dockerfile的指令分为两种:构建指令和设置指令。
构建命令:用于构建镜像的时候执行的,不会在该镜像上的容器里执行。 设置命令:用于设image的属性,将会在运行的容器里执行。

FROM

指定基础image,其实大部分镜像都是基于另一个镜像的基础上去进行修改的,比如说我这个apt-get安装的nginx是基于ubuntu的(上面例子里的alpine是docker提供的最小镜像),这个命令需要放在最前面。
命令格式如下:

FROM 镜像名字:版本

MAINTAINER

构建命令,用于指定创建者是谁。

RUN

构建命令,RUN可以运行全部被基础镜像支持的命令,常用于搭建环境。

RUN apt-get update
RUN apt-get install -y nginx

CMD

设置命令,在docker容器启动时候执行的命令,多个CMD命令存在的话只会运行最后一个CMD命令,因此只需要写一个CMD命令即可。CMD命令有三种执行方式

# 方式一,运行一个可执行文件,并提供参数(like an exec, this is the preferred form)
CMD ["executable","param1","param2"] 
# 方式二,利用”/bin/sh -c”去执行, (as a shell)
CMD command param1 param2
# 方式三,作为ENTRYPOINT的默认参数
CMD ["param1", "param2"]

在使用docker run imagename command新建并启动容器的时候,command会替换dockerfile里的CMD命令,如上面我们创建的docker镜像,如果后面输入了hello docker,则不会输出hello world了,本来dockerfile里面指定了输出hello world。

$ docker run hello_docker echo "hello docker"
hello docker
$ docker run hello_docker                    
hello world

ENTRYPOINT

设置命令,在docker容器启动时候执行的命令,一个dockerfile只能有一个ENTRYPOINT命令,有两种执行方式:

ENTRYPOINT ["executable", "param1", "param2"] 
ENTRYPOINT command param1 param2 

和CMD命令很相似,但是区别在于docker run imagename command的时候,command部分是作为参数传给ENTRYPOINT的。

USER

指定允许启动的用户,默认是root

EXPOSE

指定容器要暴露的端口,常用于一些需要通信的应用,如nginx,就会在dockerfile指定暴露80端口,或者在docker run时指定 --expose=1234,这两种方式作用相同,但是--expose可以接受区间范围的端口作为参数。

注意expose暴露的是容器的端口,如果外面主机需要通过端口连接到这个服务,需要进行一个映射,把容器的端口映射到主机的端口。

docker run -p 本地端口:暴露端口 镜像

最后附上一个简单创建nginx的dockerfile

FROM ubuntu
MAINTAINER sbb
RUN apt-get update
RUN apt-get install -y nginx
ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
EXPOSE 80