2016年10月30日星期日

Docker_005:使用 Dockerfile 构建 docker image

环境:MAC OS  X 10.12.1 + Docker 1.12.1 

1. 创建
$ mkdir static_web
$ cd static_web
$ touch Dockerfile
文件内容如下:
# FROM ubuntu
FROM maping930883/apache2:webserver
MAINTAINER Ma Ping "maping930883@hotmail.com"
# RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'Hi, I am in your container' > /usr/share/nginx/html/index.html
EXPOSE 80

$ docker build -t="maping930883/static_web" .
maping930883/static_web:v1 是镜像标签,其中 maping930883 是仓库,static_web 是镜像名称,如果没有 :v1,Docker 将自动为镜像设置一个 latest 标签。
命令中最后的 . 告诉 Docker 到本地目录中去找 Dockerfile 文件。

$ docker run -d -p 80 --name static_web maping930883/static_web nginx -g "daemon off;"
参数说明:
(1)-d 以后台方式运行 docker 容器。
(2)-p 80 也可以省略为 -p,这样对外公开在 Dockerfile 中的 EXPOSE 指令中设置的所有端口。
(3)nginx -g "daemon off;" 以前台方式运行 nginx。

$ docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED              STATUS              PORTS                   NAMES
be5b4ceac719        maping930883/static_web   "nginx -g 'daemon off"   About a minute ago   Up About a minute   0.0.0.0:32768->80/tcp   static_web

$ docker port be5b4ceac719 80
0.0.0.0:32768
访问 http://localhost:32768/

2. push 刚创建的 docker image 到 Docker Hub 上
(1)注册 https://hub.docker.com/
说明:
MAC 环境下,你的身份验证凭证将被存储在 ~/.docker/config.json 文件中。
{
    "auths": {
        "https://index.docker.io/v1/": {
            "auth": "bWFwaW5nOTMwODgzOk1hcCM5ODc2"
        }
    }
}
Linux 环境下,你的身份验证凭证将被存储在 ~/.dockercfg 文件中。
(2)$ docker login
(3)$ docker push maping930883/static_web
(4)$ docker logout

3. Dockerfile 中的指令及参数说明
每条指令都必须是大写字符,# 开头的为注释。

(1)FROM:第1条指令,指定一个已经存在的镜像。
(2)MAINTAINER:告诉 Docker 该镜像的作者是谁
(3)RUN:构建当前镜像要运行的命令,每条 RUN 指令都会创建一个新的镜像层。
(4)EXPOSE:告诉 Docker 该容器内的应用将会使用容器的指定端口。
(5)CMD:指定一个容器启动时要运行的命令。在 Dockerfile 中只能指定一条 CMD 命令。
比如:CMD ["/bin/bash", "-l"]
注意,docker run 命令可以覆盖 CMD 指令。
(6)ENTRYPOINT:跟 CMD 指令类似,但是不容易被 docker run 命令覆盖。
比如:ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]
docker run 命令行中指定的任何参数都会被当做参数再次传递给 ENTRYPOINT。
同时使用 ENTRYPOINT 和 CMD,比如:
ENTRYPOINT ["/usr/sbin/nginx"]
CMD ["-h"]
$ docker run -d -p 80 --name static_web maping930883/static_web -g "daemon off;"
如果确实需要,可以通过 docker run 的 --entrypoint 参数覆盖 ENTRYPOINT 指令。
(7)WORKDIR:创建新容器时,在容器内部设置一个工作目录。ENTRYPOINT 或 CMD 指定的程序会在这个目录下执行。
比如:WORKDIR /opt/webapp
docker run 命令行中的 -w 参数可以覆盖工作目录
(8)ENV:在镜像构建过程中设置环境变量。
比如:ENV REFRESHED_AT  2016-12-31
docker run 命令行中的 -e 参数可以传递环境变量
比如:docker run -it -e "WEB_PORT=8080" ubuntu env
(9)USER:创建容器时,会以什么用户与运行。默认不指定会使用 root 用户。
(10)VOLUME:给基于镜像创建的容器添加卷。
比如:VOLUME ["/opt/project", "/data"] 指定多个卷。
docker run 命令行中的 -v 参数可以指定卷
比如:docker run -d -p 80 --name website -v $PWD/website:/var/www/html/website jamtur01/nginx nginx
一个卷可以存在于一个或多个容器内的指定目录,对数据提供持久化的功能:
  • 卷可以在容器间共享和重用。
  • 一个容器也可以不和其它容器共享卷。
  • 对卷的修改是立即生效的。
  • 对卷的修改不会对更新镜像产生影响。
  • 卷会一直存在直到没有任何容器使用它。
(11)ADD:把构建环境下的文件和目录复制到镜像中。
比如:ADD latest.tar.gz /var/www/wordpress/
(12)COPY:与 ADD 类似,但是文件源路径只能是与当前构建环境相对的文件或目录,不能复制该目录以外的任何文件。
如果目的位置不存在,Docker 会自动创建需要的目录结构。
(13)ONBUILD:为镜像添加触发器。当一个镜像被用作其它镜像的基础镜像时,比如从某些位置添加源代码,执行构建脚本等等。

4. Docker 是如何执行 Dockerfile 的?
(1)Docker 从基础镜像运行一个容器。
(2)执行一条指令,对容器做出修改。
(3)执行类似 docker commit 的操作,提交一个新的镜像层。
(4)执行 Dockerfile 中的下一条指令,直到所有指令都执行完毕。

没有评论: