制作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 模式。