制作docker镜像

编写Dockerfile

# 使用哪个镜像为基础
FROM nginx

# 安装apt-get后清理垃圾文件
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

# 复制文件
COPY index.html /usr/share/nginx/html/index.html

# 声明这个容器对外使用的端口
EXPOSE 80 443

# 开启健康检查
HEALTHCHECK --interval=5s --timeout=3s \
  CMD curl -fs http://localhost/ || exit 1

# 添加作者信息(键值对)
LABEL maintainer="liuyalong"
LABEL documentation="https://baidu.com"

编写忽略文件.dockerignore

build的时候,会忽略的文件,不会copy到镜像中

.git/
node_modules/
*.bak
test*/
test*

执行

  • 使用docker build -t mynginx:v1 .创建镜像

    • -t name:tag 给这个镜像打个标签xxx
    • . 最后有个点,指定镜像的上下文为当前的目录路径,相当于指定了根目录路径,在Dockerfile中的路径就以此路径为根路径
    • docker build -t mytest:v1 -f xxx.dockerfile . 使用-f 指定dockerfile文件
  • 使用docker images 查看所有镜像

  • 使用docker inspect imageidxxxx可以查看到镜像的详细信息

  • 使用docker run -itd -p 80:80 --name mynginx mynginx:v1用刚才做的镜像启动一个容器,并命名为mynginx,端口映射为80

  • 使用docker container ls 查看所有启动的容器

  • 使用docker rm xxx 删除容器

  • 使用docker rmi xxx 删除镜像,必须先停止容器才可以删除

注意事项

  • docker build 默认找名字为Dockerfile的文件,忽略文件找.dockerignore
  • FROM的镜像选最小的
  • Dockerfile中每一个指令都会建立一层,在其上执行这些命令,执行结束后,commit这一层的修改
  • RUN执行多个命令用&&连接,应保证层级最少,把不经常变化的层级放到最前面,这样可以最大程度使用镜像缓存,因为当某一层改变后,之后的几层就需要重新在这层的基础上构建.
  • EXPOSE 只是声明使用哪些端口,具体使用不受这个影响,通过-p命令指定内外端口
  • RUN命令是在打包成镜像的时候就执行了

CMD和ENTRYPOINT区别

官方文档说每个Dockerfile必须有至少一个ENTRYPOINT或CMD,我这里没写,通过docker inspect可以看到,nginx镜像帮我写了ENTRYPOINT和CMD

  • exec 模式和 shell 模式,CMD 和 ENTRYPOINT 指令都支持 exec 模式和 shell 模式的写法,简单说就是exec模式执行完就退出了,此时销毁所有信息;shell模式执行完返回到当前shell,所以可以改变某些变量
  • CMD 指令的目的是:为容器提供默认的执行命令。
  • CMD 指令有三种使用方式
    • 其中的一种是为 ENTRYPOINT 提供默认的参数:CMD ["param1","param2"]
    • 另外两种使用方式分别是 exec 模式和 shell 模式:
      • CMD ["executable","param1","param2"] // 这是 exec 模式的写法,注意需要使用双引号。
      • CMD command param1 param2 // 这是 shell 模式的写法。
  • 命令行参数可以覆盖 CMD 指令的设置,但是只能是重写,却不能给 CMD 中的命令通过命令行传递参数。
    例如:
    用以下文件创建镜像
   CMD [ "top" ]

使用命令 docker run test1 ps aux启动容器
可以看到,命令行上指定的 ps aux 命令覆盖了 Dockerfile 中的 CMD [ "top" ]。实际上,命令行上的命令同样会覆盖 shell 模式的 CMD 指令。

  • ENTRYPOINT 指令
    • ENTRYPOINT 指令的目的也是为容器指定默认执行的任务。
    • ENTRYPOINT 指令有两种使用方式,就是我们前面介绍的 exec 模式和 shell 模式:
    • ENTRYPOINT ["executable", "param1", "param2"] // 这是 exec 模式的写法,注意需要使用双引号。
    • ENTRYPOINT command param1 param2 // 这是 shell 模式的写法。
  • 指定 ENTRYPOINT 指令为 exec 模式时,命令行上指定的参数会作为参数添加到 ENTRYPOINT 指定命令的参数列表中
    例如:
    用以下文件创建镜像
FROM ubuntu
ENTRYPOINT [ "top", "-b" ]

使用命令 docker run test1 -c启动容器
最终生效的结果是 top -b -c,即 在命令行上添加的参数被追加到了 top 命令的参数列表中。

用以下文件创建镜像

FROM ubuntu
ENTRYPOINT [ "top", "-b" ]
CMD [ "-c" ]

使用命令 docker run test2 不带参数启动,这时容器中运行的命令为:top -b -c
使用命令 docker run test2 -n 1 指定命令行参数,-n 1 会覆盖 通过 CMD [ "-c" ] 指定的参数,容器执行的命令为:top -b -n 1

  • 指定 ENTRYPOINT 指令为 shell 模式时,会完全忽略命令行参数,如果非要用命令行覆盖参数,需要显式的指定 --entrypoint 参数了才可以覆盖,例如docker run --entrypoint xxx test2

  • 同时使用 CMD 和 ENTRYPOINT 的情况

    • 如果 ENTRYPOINT 使用了 shell 模式,CMD 指令会被忽略。
    • 如果 ENTRYPOINT 使用了 exec 模式,CMD 指定的内容被追加为 ENTRYPOINT 指定命令的参数。
    • 如果 ENTRYPOINT 使用了 exec 模式,CMD 也应该使用 exec 模式。
posted @ 2021-01-19 18:09  rm-rf*  阅读(232)  评论(0编辑  收藏  举报