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

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

内容简介: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

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

查看所有标签

猜你喜欢:

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

The Definitive Guide to Django

The Definitive Guide to Django

Adrian Holovaty、Jacob Kaplan-Moss / Apress / 2007-12-06 / CAD 45.14

Django, the Python-based equivalent to the Ruby on Rails web development framework, is presently one of the hottest topics in web development today. In The Definitive Guide to Django: Web Development ......一起来看看 《The Definitive Guide to Django》 这本书的介绍吧!

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具