目录
前言
比起君子讷于言而敏于行,我更喜欢君子善于言且敏于行。
一、docker是什么?
docker是一个进程级 轻量级的VM
https://docs.docker.com/engine/install/ubuntu/#install-using-the-convenience-script 官方安装手册
https://yeasy.gitbook.io/docker_practice/install/ubuntu 另一个安装手册
二、docker的中容器和镜像的关系是什么?
docker的整个生命周期有三部分组成:镜像(image)+容器(container)+仓库(repository)。
镜像是文件,容器是进程。镜像运行起来就是容器。docker 容器=镜像+可读层
三、一些术语和要求
标签(tag)
Tag是用户为ImageID指定的说明文字。Tag中的字符只能是大小写字母、数字、短线、下划线和点,即[a-zA-Z0-9_.-],首个字符不能是.或-。Tag不能超过127个字符。
镜像名(Repository)
这里的Repository
是指镜像全名在冒号:
之前的部分,冒号:
之后的部分是镜像的标签(tag),用来区分镜像的版本。镜像名可以包含小写字符,数字和分隔符。 分隔符是句点.
,一个或两个下划线_
,或一个或多个短横线-
,镜像名 不允许 以分隔符开头或结尾。
四、Dockerfile
镜像可以基于dockerfile构建,dockerfile是一个描述文件,里面包含了一些命令,每条命令都会对基础文件系统创建新的层次结构,层层叠加。通过优化Dockerfile中的指令,可以减少镜像的大小,按照一些规范来制作Dockerfile,可以增加Dockerfile的可读性与可维护性。
基本原则
- 尽量使用干净的目录去制作精细,避免不必要的性能损耗。
- 只安装需要的包。为了减少镜像的体积和编译时间,应避免安装额外的、不需要的包。
- 每个容器只运行一个进程。
- 减少镜像层。Dockerfile中的指令会生成新的镜像层,一个镜像最多127层。
- 把多个参数排在不同的行中,提高可读性。
(1) FROM
定制的镜像都是基于 FROM 的镜像。镜像从哪儿来 必须是第一条指令。例如:
FROM ubuntu:16.04
(2) RUN
执行RUN后面跟着的命令。例如:
RUN apt-get install -y nginx \
&& apt-get clean
(3) WORKDIR
指定工作路径,此处尽可能的使用绝对路径。相当于cd 的意思。例如:
WORKDIR /workspace/test
(4) ADD和COPY
ADD 与 COPY 都是将外部文件拷贝到镜像内部的指令, 相比之下可能 ADD 的功能更加强大一下, 建议如下:
- 尽量不要拷贝远程文件, 这样也就用不着 ADD 的功能, 用 COPY 就可以了。
- 如果压缩包拷贝进镜像后, 不希望这个压缩包被自动解压缩, 用 COPY 就对了. 反之如果希望拷贝进镜像之后就自动解压做, 那就用 ADD 拷贝进去。
如果涉及到远程文件, 建议使用 RUN curl
或 RUN wget
命令替代 ADD。
COPY runserver.sh /workspace/
(5) CMD
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
- CMD 在docker run 时运行。
- RUN 是在 docker build
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:Dockerfile中如果存在多个CMD命令,只生效最后一个。
格式如下:
CMD <shell 命令>
CMD ["<可执行文件或命令>","<param1>","<param2>",...]
CMD ["<param1>","<param2>",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
(6) ENTRYPOINT
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 ENTRYPOINT 指令指定的程序。
优点:在执行 docker run 的时候可以指定 ENTRYPOINT 运行所需的参数。
注意:如果 Dockerfile 中如果存在多个 ENTRYPOINT 指令,仅最后一个生效。格式如下:
ENTRYPOINT ["<executeable>","<param1>","<param2>",...]
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参
FROM nginx
ENTRYPOINT ["nginx", "-c"] # 定参
CMD ["/etc/nginx/nginx.conf"] # 变参
$ docker run nginx:test -c /etc/nginx/new.conf
(7) ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...
ENV NODE_VERSION 7.2.0
(8) ARG
构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效(docker run的时候是无法使用的,传参支持不到那个时候的),构建好的镜像内不存在此环境变量。
构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。
ARG MODEL_NAME
使用了7+8进行定义,build和run的时候进行传参
ARG EXE_NAME
ARG MODEL_NAME
ENV EXE_NAME ${EXE_NAME}
ENV MODEL_NAMEA ${MODEL_NAME}
CMD ["/bin/bash","-lc","/workspace/runserver.sh","${EXE_NAME}","${MODEL_NAME}"]
docker build -t namexxxxx --build-arg EXE_NAME="xxxxx" --build-arg MODEL_NAME="xxxx.model" .
(9) USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
(10) EXPOSE
EXPORT 端口号。声明容器的服务端口(仅仅是个声明)只有在遇到run -P随机映射端口时,才会映射到这个声明的端口
(11) LABEL
用来给镜像添加一些标签。以键值对的形式,语法格式如下:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
可以添加作者
LABEL authors="xxxxxx"
五、Docker命令
(1)docker images 查看镜像
(2)docker ps -a 查看运行中的容器
(3)docker build -t xxx . 当前目录下构建名字为xxx镜像
(4)docker run -it xxx /bin/bash 运行xxx镜像后进入
-p:指定端口映射 主机(宿主)端口:容器端口
-v:绑定一个卷
-d:后台运行容器,并返回容器id
-i:交互式运行
-t:分配bash伪终端
(5)docker exec -it 容器id bash
i:以交互的形式运行容器 直接显示在屏幕上
t:为容器重新分配一个伪输入终端,通常与-i同时使用
(6)docker run起来进行改动后存成新的镜像?
docker commit 当前运行的容器名 新镜像名:版本号
总结
零零碎碎的docker学习内容,总是没有好好的整理一下,东一块儿,西一块儿。现在进行一下整合,防止日后遗忘。暂时能想到的就这些了,后续有想到的将会继续补充。