docker利用Dockerfile创建镜像,上传docker hub

栏目: 编程工具 · 发布时间: 7年前

内容简介:docker利用Dockerfile创建镜像,上传docker hub

前面写过一篇,关于上传镜像到docker hub的文章。 docker 创建image上传到 docker hub ,并下载 。这篇文章里面的镜像是,是docker pull下来的,是别人镜像。接下来,我们来说说怎么样创建一个完全属于自己的镜像。

1,创建一个文件夹,在该文件夹下创建一个Dockerfile文件

$ cat Dockerfile
# Version: 1
FROM centos:latest
MAINTAINER tankzhang "***ying@gmail.com"
RUN yum -y install epel-release
RUN yum install -y nginx
RUN echo 'this is test images' > /usr/share/nginx/html/index.html
CMD ["nginx", "-g", "daemon off;"]

很简单的一个安装nginx并启的一个镜像。关于里面的参数,下面会详细的说到。

2,docker build创建一个镜像

$ docker build -t tankzhang/centos_nginx:v1 .  //注意.表示当前目录
Sending build context to Docker daemon 2.048 kB
Step 1/6 : FROM centos:latest
 ---> 8140d0c64310
。。。。。。。。。。。。。。。。。。。。。。。。
Removing intermediate container a075d8c1ffdc
Successfully built 35a2f6b9e8a3
Successfully tagged tankzhang/centos_nginx:v1

出现Successfully的字样表示成功,如果不成功的话,用docker images查看,会发现不成功的都是<none>。

3,启动nginx容器

$ docker run --name mynginx -d -p 8081:80 tankzhang/centos_nginx:v1

$ docker ps -a |grep mynginx  //运行中状态是UP,反之是exited
81639bc494f0     tankzhang/centos_nginx:v1    "nginx -g 'daemon off"   22 minutes ago      Up 18 minutes        0.0.0.0:8081->80/tcp   mynginx

docker命令行的用法非常的多,请参考: docker命令详解

在这里要注意8081是容器外端口,80是容器内端口。这个时候我们就可以通过localhost:8081进行访问了。容器外是没有WEB服务器的,8081端口是被什么程序占用了呢。

$ netstat -tpnl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1187/sshd
tcp        0      0 :::22                   :::*                    LISTEN      1187/sshd
tcp        0      0 :::2376                 :::*                    LISTEN      1237/dockerd
tcp        0      0 :::8081                 :::*                    LISTEN      20108/docker-proxy

8081被docker-proxy占用了

4,docker hub上面创建远程镜像并且上传

先到https://cloud.docker.com/ 创建一个仓库名为centos_nginx,然后在本地登录,并上传

$ docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username (tankzhang):
Password:
Login Succeeded

$ docker push tankzhang/centos_nginx:v1
The push refers to a repository [docker.io/tankzhang/centos_nginx]
2f1c6546cfa5: Pushed
a69b66773d0a: Pushing [===============>                                   ] 53.77 MB/175 MB
2e2e2c15a2d4: Pushing [===================>                               ] 35.61 MB/93.1 MB
b51149973e6a: Pushing [==========>                                        ] 38.59 MB/192.6 MB

到这儿,自己创建的镜像已经传到docker hub了。

下面详细说一下,Dockerfile的参数:

5.  Dockerfile 中使用指令

5.1 FROM

FROM 指令用于指定其后构建新镜像所使用的基础镜像。 FROM 指令必是 Dockerfile 文件中的首条命令,启动构建流程后,Docker将会基于该镜像构建新镜像, FROM 后的命令也会基于这个基础镜像。

FROM 语法格式为:

FROM <image>

FROM <image>:<tag>

FROM <image>:<digest>

通过 FROM 指定的镜像,可以是任何有效的基础镜像。 FROM 有以下限制:

  • FROM 必须是 Dockerfile 中第一条非注释命令
  • 在一个 Dockerfile 文件中创建多个镜像时, FROM 可以多次出现。只需在每个新命令 FROM 之前,记录提交上次的镜像ID。
  • tagdigest 是可选的,如果不使用这两个值时,会使用 latest 版本的基础镜像

5.2 RUN

RUN 用于在镜像容器中执行命令,其有以下两种命令执行方式:

shell 执行

在这种方式会在 shell 中执行命令,Linux下默认使用 /bin/sh -c ,Windows下使用 cmd /S /C

注意: 通过 SHELL 命令修改 RUN 所使用的默认 shell

RUN <command>

exec 执行

RUN ["executable", "param1", "param2"]

RUN 可以执行任何命令,然后在当前镜像上创建一个新层并提交。提交后的结果镜像将会用在 Dockerfile 文件的下一步。

通过 RUN 执行多条命令时,可以通过 \ 换行执行:

RUN /bin/bash -c 'source $HOME/.bashrc; \
echo $HOME'

也可以在同一行中,通过分号分隔命令:

RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'

RUN 指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定 --no-cache 参数,如: docker build --no-cache

5.3 CMD

CMD 用于指定在容器启动时所要执行的命令。 CMD 有以下三种格式:

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

CMD 不同于 RUNCMD 用于指定在容器启动时所要执行的命令,而 RUN 用于指定镜像构建时所要执行的命令。

CMDRUN 在功能实现上也有相似之处。如:

docker run -t -i itbilu/static_web_server /bin/true

等价于:

cmd ["/bin/true"]

CMDDockerfile 文件中仅可指定一次,指定多次时,会覆盖前的指令。

另外, docker run 命令也会覆盖 DockerfileCMD 命令。如果 docker run 运行容器时,使用了 DockerfileCMD 相同的命令,就会覆盖 Dockerfile 中的 CMD 命令。

如,我们在构建镜像的 Dockerfile 文件中使用了如下指令:

CMD ["/bin/bash"]

使用 docker build 构建一个新镜像,镜像名为 itbilu/test 。构建完成后,使用这个镜像运行一个新容器,运行效果如下:

$ sudo docker run -i -t itbilu/test
root@e3597c81aef4:/#

在使用 docker run 运行容器时,我们并没有在命令结尾指定会在容器中执行的命令,这时 Docker 就会执行在 DockerfileCMD 中指定的命令。

如果不想使用 CMD 中指定的命令,就可以在 docker run 命令的结尾指定所要运行的命令:

$ sudo docker run -i -t itbilu/test /bin/ps
  PID TTY          TIME CMD
    1 ?        00:00:00 ps

这时, docker run 结尾指定的 /bin/ps 命令覆盖了 DockerfileCMD 中指定的命令。

5.4 ENTRYPOINT

ENTRYPOINT 用于给容器配置一个可执行程序。也就是说,每次使用镜像创建容器时,通过 ENTRYPOINT 指定的程序都会被设置为默认程序。 ENTRYPOINT 有以下两种形式:

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

ENTRYPOINTCMD 非常类似,不同的是通过 docker run 执行的命令不会覆盖 ENTRYPOINT ,而 docker run 命令中指定的任何参数,都会被当做参数再次传递给 ENTRYPOINTDockerfile 中只允许有一个 ENTRYPOINT 命令,多指定时会覆盖前面的设置,而只执行最后的 ENTRYPOINT 指令。

docker run 运行容器时指定的参数都会被传递给 ENTRYPOINT ,且会覆盖 CMD 命令指定的参数。如,执行 docker run <image> -d 时, -d 参数将被传递给入口点。

也可以通过 docker run --entrypoint 重写 ENTRYPOINT 入口点。

如:可以像下面这样指定一个容器执行程序:

ENTRYPOINT ["/usr/bin/nginx"]

完整构建代码:

# Version: 0.0.3
FROM ubuntu:16.04
MAINTAINER 何民三 "cn.liuht@gmail.com"
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'Hello World, 我是个容器' \
   > /var/www/html/index.html
ENTRYPOINT ["/usr/sbin/nginx"]
EXPOSE 80

使用 docker build 构建镜像,并将镜像指定为 itbilu/test

$ sudo docker build -t="itbilu/test" .

构建完成后,使用 itbilu/test 启动一个容器:

$ sudo docker run -i -t  itbilu/test -g "daemon off;"

在运行容器时,我们使用了 -g "daemon off;" ,这个参数将会被传递给 ENTRYPOINT ,最终在容器中执行的命令为 /usr/sbin/nginx -g "daemon off;"

5.5 LABEL

LABEL 用于为镜像添加元数据,元数以键值对的形式指定:

LABEL <key>=<value> <key>=<value> <key>=<value> ...

使用 LABEL 指定元数据时,一条 LABEL 指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条 LABEL 指令指定,以免生成过多的中间镜像。

如,通过 LABEL 指定一些元数据:

LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"

指定后可以通过 docker inspect 查看:

$sudo docker inspect itbilu/test
"Labels": {
    "version": "1.0",
    "description": "这是一个Web服务器",
    "by": "IT笔录"
},

注意; Dockerfile 中还有个 MAINTAINER 命令,该命令用于指定镜像作者。但 MAINTAINER 并不推荐使用,更推荐使用 LABEL 来指定镜像作者。如:

LABEL maintainer="itbilu.com"

5.6 EXPOSE

EXPOSE 用于指定容器在运行时监听的端口:

EXPOSE <port> [<port>...]

EXPOSE 并不会让容器的端口访问到主机。要使其可访问,需要在 docker run 运行容器时通过 -p 来发布这些端口,或通过 -P 参数来发布 EXPOSE 导出的所有端口。

5.7 ENV

ENV 用于设置环境变量,其有以下两种设置形式:

ENV <key> <value>
ENV <key>=<value> ...

如,通过 ENV 设置一个环境变量:

ENV ITBILU_PATH /home/itbilu/

设置后,这个环境变量在 ENV 命令后都可以使用。如:

WORKERDIR $ITBILU_PATH

这些环境变量不仅可以构建镜像过程使用,使用该镜像创建的容器中也可以使用。如:

$ docker run -i -t  itbilu/test
root@196ca123c0c3:/# cd $ITBILU_PATH
root@196ca123c0c3:/home/itbilu#

5.8 ADD

ADD 用于复制构建环境中的文件或目录到镜像中。其有以下两种使用方式:

ADD <src>... <dest>
ADD ["<src>",... "<dest>"]

通过 ADD 复制文件时,需要通过<src>指定源文件位置,并通过 <dest> 来指定目标位置。<src>可以是一个构建上下文中的文件或目录,也可以是一个 URL ,但不能访问构建上下文之外的文件或目录。

如,通过 ADD 复制一个网络文件:

ADD http://wordpress.org/latest.zip $ITBILU_PATH

在上例中, $ITBILU_PATH 是我们使用 ENV 指定的一个环境变量。

另外,如果使用的是本地归档文件( gzipbzip2xz )时,Docker会自动进行解包操作,类似使用 tar -x

5.9 COPY

COPY 同样用于复制构建环境中的文件或目录到镜像中。其有以下两种使用方式:

COPY <src>... <dest>
COPY ["<src>",... "<dest>"]

COPY 指令非常类似于 ADD ,不同点在于 COPY 只会复制构建目录下的文件,不能使用 URL 也不会进行解压操作。

5.10 VOLUME

VOLUME 用于创建挂载点,即向基于所构建镜像创始的容器添加卷:

VOLUME ["/data"]

一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:

  • 卷可以容器间共享和重用
  • 容器并不一定要和其它容器共享卷
  • 修改卷后会立即生效
  • 对卷的修改不会对镜像产生影响
  • 卷会一直存在,直到没有任何容器在使用它

VOLUME 让我们可以将源代码、数据或其它内容添加到镜像中,而又不并提交到镜像中,并使我们可以多个容器间共享这些内容。

如,通过 VOLUME 创建一个挂载点:

ENV ITBILU_PATH /home/itbilu/
VOLUME [$ITBILU_PATH]

构建的镜像,并指定镜像名为 itbilu/test 。构建镜像后,使用新构建的运行一个容器。运行容器时,需 -v 参将能本地目录绑定到容器的卷(挂载点)上,以使容器可以访问宿主机的数据。

$ sudo docker run -i -t -v ~/code/itbilu:/home/itbilu/  itbilu/test
root@31b0fac536c4:/# cd /home/itbilu/
root@31b0fac536c4:/home/itbilu# ls
README.md  app.js  bin  config.js  controller  db  demo  document  lib  minify.js  node_modules  package.json  public  routes  test  views

如上所示,我们已经可以容器的 /home/itbilu/ 目录下访问到宿主机 ~/code/itbilu 目录下的数据了。

5.11 USER

USER 用于指定运行镜像所使用的用户:

USER daemon

使用 USER 指定用户时,可以使用用户名、 UIDGID ,或是两者的组合。以下都是合法的指定试:

USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group

使用 USER 指定用户后, Dockerfile 中其后的命令 RUNCMDENTRYPOINT 都将使用该用户。镜像构建完成后,通过 docker run 运行容器时,可以通过 -u 参数来覆盖所指定的用户。

5.12 WORKDIR

WORKDIR 用于在容器内设置一个工作目录:

WORKDIR /path/to/workdir

通过 WORKDIR 设置工作目录后, Dockerfile 中其后的命令 RUNCMDENTRYPOINTADDCOPY 等命令都会在该目录下执行。

如,使用 WORKDIR 设置工作目录:

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

在以上示例中, pwd 最终将会在 /a/b/c 目录中执行。

在使用 docker run 运行容器时,可以通过 -w 参数覆盖构建时所设置的工作目录。

5.13 ARG

ARG 用于指定传递给构建运行时的变量:

ARG <name>[=<default value>]

如,通过 ARG 指定两个变量:

ARG site
ARG build_user=IT笔录

以上我们指定了 sitebuild_user 两个变量,其中 build_user 指定了默认值。在使用 docker build 构建镜像时,可以通过 --build-arg <varname>=<value> 参数来指定或重设置这些变量的值。

$ sudo docker build --build-arg site=itiblu.com -t itbilu/test .

这样我们构建了 itbilu/test 镜像,其中 site 会被设置为 itbilu.com ,由于没有指定 build_user ,其值将是默认值 IT笔录

5.14 ONBUILD

ONBUILD 用于设置镜像触发器:

ONBUILD [INSTRUCTION]

当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发。

如,当镜像被使用时,可能需要做一些处理:

[...]
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]

5.15 STOPSIGNAL

STOPSIGNAL 用于设置停止容器所要发送的系统调用信号:

STOPSIGNAL signal

所使用的信号必须是内核系统调用表中的合法的值,如: 9SIGKILL

5.16 SHELL

SHELL 用于设置执行命令( shell 式)所使用的的默认 shell 类型:

SHELL ["executable", "parameters"]

SHELL 在Windows环境下比较有用,Windows下通常会有 cmdpowershell 两种 shell ,可能还会有 sh 。这时就可以通过 SHELL 来指定所使用的 shell 类型:

FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

产品心经

产品心经

闫荣 / 机械工业出版社 / 2014-9-30 / 59

产品经理如何才能迅速地、全方位地提升自己的能力,从而打造出让用户尖叫并疯狂爱上的产品?有没有捷径?从成功的、有经验的产品经理的实践真知和智慧中学习是一个很好的途径!本书就是一位拥有近10年产品经验的资深产品经理的实践真知和智慧的结晶,从产品经理核心素养、产品认知、战略与规划、精益开发、需求分析与管理、用户体验、精细运营7大方面,系统梳理了能全面、迅速提升产品经理能力,从而打造出让用户尖叫的产品的5......一起来看看 《产品心经》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具