目录
1、docker命令
2、镜像和容器的关系
3、Dockfile中特殊语法
(1)CMD 和 ENTRYPOINT
① 普通案例
② 特殊案例
a、dockfile中的命令 和 命令行中的命令有冲突
b、使用exec执行PID=1的命令
③【cmd、entrypoint】和 exec 的关系
(2)ADD
4、镜像命令
(1)镜像生成
【方案一】: 指定dockerfile,生成镜像
【方案二】:容器备份,生成镜像
(2)镜像拉取
(3)镜像查看
(4)删除所有未被任何容器引用的镜像 【危险!不建议】
(5)push镜像到docker hug
Docker学不会?不妨看看这篇文章 (qq.com)
Docker批量删除REPOSITORY、TAG为none的镜像_shenzhen_zsw的专栏-CSDN博客_docker删除repository
docker删除镜像的时候报错--image has dependent child images - 清风软件测试 - 博客园
镜像是一个静态的只读模板,它包含了运行一个应用程序所需要的所有东西,包括代码、运行时环境、库、环境变量和配置文件。
容器是镜像nginx的一个运行实例(如果把镜像看做类,容器就是类的实例对象)。
ENTRYPOINT 和 CMD 都是 Dockerfile 的语法.
(1) CMD 用于提供默认的容器启动命令。如果在启动容器时没有提供命令,那么将使用 CMD 指定的命令。如果在启动容器时提供了额外命令,那么 CMD 指定的命令将被忽略。
(2) ENTRYPOINT 用于将容器当作一个可执行程序。ENTRYPOINT 指定的命令将总是在容器启动时执行,而且不会被忽略。如果在启动容器时提供了命令,那么这个命令将作为 ENTRYPOINT 命令的参数。
假设你有一个 Dockerfile,其中包含以下指令:
ENTRYPOINT ["echo"]
CMD ["Hello, Docker!"]
当你基于这个 Dockerfile 构建镜像,并用这个镜像启动容器时,如果你没有提供命令,那么容器将输出 “Hello, Docker!”。这是因为 ENTRYPOINT 指定的 echo 命令将使用 CMD 指定的 “Hello, Docker!” 作为参数。
如果你在启动容器时提供了命令,例如 docker exec -it <容器ID或names> “Hello, World!”,那么容器将输出 “Hello, World!”。这是因为你提供的命令将作为 ENTRYPOINT 指定的 echo 命令的参数,而 CMD 指定的 “Hello, Docker!” 将被忽略。
如果Dockerfile中指定 ENTRYPOINT ["sh", "xx.sh"], 但是又运行了 “docker run --name 容器名 -idt
如果你想在容器启动时运行 /bin/bash 而不是 sh xx.sh,你需要在 docker run 命令中使用 --entrypoint 参数来覆盖 Dockerfile 中的 ENTRYPOINT 指令,如下所示:
docker run --name 容器名 -idt --entrypoint /bin/bash
在 Dockerfile 中,可以使用 exec 形式的 ENTRYPOINT 或 CMD,例如:
ENTRYPOINT ["exec", "python", "app.py"]
或
CMD ["exec", "python", "app.py"]
这里的 exec 实际上并不是指 exec 命令,而是表示 Docker 应该使用 exec 形式来执行指定的命令,而不是使用 shell 形式。
在 exec 形式中,Docker 会直接执行指定的命令,而不是通过 /bin/sh -c(command) 或其他 shell 来执行。这样做的一个好处是,执行的命令会成为容器的 PID 1 进程,这样它就可以接收到系统的各种信号,例如 SIGTERM。
即无exec时,docker默认会转化为 /bin/sh -c [cmd或entrypoint] python app.py;有exec时docker会直接执行 [cmd或entrypoint] python app.py,不再借助shell执行。
所以两者是独立的,只是可以组合一起用罢了。所以 cmd exec python app.py 并不能保障PID=1的命令就是python app.py,因为cmd的命令会被 “docker run xx 命令”中的命令取代,而exec只保障后续执行的命令一定是PID=1,至于具体的命令是什么还要受cmd、entrypoint、docker run xx 的指令限制。
ADD命令用于将主机中的文件或目录复制到镜像中,所以基于同一个镜像启动的所有容器都会有相同的工作目录。复制完成后,主机目录和镜像目录是完全独立的,后续操作都不会互相影响。
例如 ADD ./pythonwork/test01 /test会将主机上的./pythonwork/test01目录下的所有内容复制到镜像下的/test
docker build -t <镜像名:镜像tag> -f= .
注意:这个目录会影响Dockerfile中的ADD、COPY指令,因为这两个指令中对应的本地文件系统目录就是以该目录为父目录的。举例:
如果 Dockerfile 和 app.py 在不同的文件夹下,那么你需要在执行 docker build 命令时,指定的构建上下文路径应包含这两个文件。
例如,你的文件结构如下:
/myproject/
|-- Dockerfile
/otherdir/
|-- app.py
你可以将 app.py 复制或者移动到 myproject 目录下,这样 Dockerfile 和 app.py 就在同一个目录中了,然后你在 myproject 目录下执行 docker build 命令。
如果你不想移动 app.py 文件,那么你就需要选择一个包含 Dockerfile 和 app.py 的公共父目录作为构建上下文。这里的公共目录就是 / 目录,再在该公共目录下执行 docker build 命令,并使用 -f 参数指定 Dockerfile 的路径,如下:
docker build -t my-python-app:1.0 -f /myproject/Dockerfile .
然后在 Dockerfile 中,你可以使用以下命令将 app.py 文件添加到镜像中:
ADD /otherdir/app.py /app/
注意:这样会将 / 目录下的所有文件和子目录都包含到构建上下文中,这可能会使构建过程变得非常慢,并且可能会包含你不想添加到镜像中的文件。因此,通常建议将 Dockerfile 和所有需要添加到镜像的文件都放在同一个目录中。
所以常看到把Dockerfile和需要添加到镜像的文件都放在同一个目录下,然后再cd 到这个公共目录,执行docker build xx操作。
docker commit -p <容器ID> 备份命名
docker image pull : 或者 docker pull :
其中:
PEPOSITORY-镜像的仓库源;TAG-镜像的标签。未指定TAG,默认是最新tag。
docker images
或
docker images -a
多人协同下不建议使用!!!!
docker image prune -a
如果是要同时删除所有已经停止的容器以及所有未被任何容器引用的镜像,包括那些你可能希望保留的镜像:【同样危险!不建议!】
docker system prune -a