ata*_*xis 9 docker docker-compose
据我了解docker,docker-compose流程是这样的:
Dockerfile --build--> Docker Image --create--> Docker Container #1
--create--> Docker Container #2
--create--> ...
--create--> Docker Container #n
Run Code Online (Sandbox Code Playgroud)
所以Image是由 中的命令制作的,Dockerfile但纯粹是某种“离线”版本。您可以将其“联机”,然后作为容器使用。
我的理解docker-compose up是通过service里面的定义为我们做这个两步过程docker-compose.yml,除了一些其他的东西,比如安装卷,暴露端口等等。
我的第一个问题是:
如果我运行docker-compose exec some_command,那么我正在操纵 docker 容器 - 对吗?
据我了解的文档,docker-compose run some_command几乎是一样的,但是,它事先创建了一个新的“层”,所以…… 像这样:
Docker Container #n (layer 0) ----> Docker Container #n (layer 1)
Run Code Online (Sandbox Code Playgroud)
而some_command正确的-然后对层1中执行?此外,它似乎run正在传递some_command到入口点,而exec确实覆盖了定义的入口点。
我的第二个问题是:
run之后创建的新层会发生什么?有没有办法在不创建新层的情况下执行命令?我想知道,因为我添加了一个这样的入口点脚本:
#!/bin/sh
case "$@" in
"update")
pip3 install -r requirements.txt
;;
"start")
python manage.py runserver
;;
*)
echo "executing $@"
exec "$@"
;;
esac
Run Code Online (Sandbox Code Playgroud)
我这样做是为了能够通过运行像docker-compose run backend update. 问题是run如果我up之后运行,则不会使用创建的图层。
在大多数情况下,各种命令式docker-compose命令与其等效命令非常相似docker,只是它们知道如何使用文件查找容器docker-compose.yml,并且在某些情况下它们的默认值略有不同。
所以,docker-compose exec与 基本相同docker exec。它是一个调试工具,可以在正在运行的容器内运行附加命令。它与容器的主进程在相同的环境中运行,具有相同的容器私有文件系统。它不是主进程的子进程,如果主进程有一个设置环境变量的入口点包装脚本,它就不会看到这些。附加命令通常是调试 shell,并且docker-compose exec默认为docker exec -it选项。
# Get a debugging shell in a running container:
docker-compose exec app bash
# Basically equivalent to:
docker exec -it project_app_1 bash
Run Code Online (Sandbox Code Playgroud)
类似地,docker-compose run与 基本相同docker run:它根据docker-compose.yml文件中指定的映像启动一个新容器。与 不同的是docker run,它从文件中继承了大部分选项docker-compose.yml,包括网络设置、环境变量和已安装的卷(但不包括已发布的端口)。就像docker run,容器文件系统的内容在容器退出后基本上是孤立的(或者如果您使用该--rm选项则被删除)。
# Get a debugging shell to see how an image was built:
# (This will run via the image's entrypoint)
docker-compose run --rm app bash
# Basically equivalent to:
docker build -t project_app .
docker run -it --net project_default -v $PWD/logs:/app/logs \
--rm project_app bash
# (Picking up the Compose networks: and volumes:)
Run Code Online (Sandbox Code Playgroud)
您在建议的入口点包装器中显示的“更新”任务不是您在容器启动时执行的操作。如果您需要更新映像中的代码或库依赖项,请重建映像(可能使用docker-compose build)。
# If the Dockerfile has...
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip3 install -r requirements.txt
...
Run Code Online (Sandbox Code Playgroud)
# ...then you can get a container with updated library dependencies by
docker-compose up --build
Run Code Online (Sandbox Code Playgroud)
首先让我们澄清这里的基本术语。引用官方文档:
一个图像是用于创建一个码头工人容器指令的只读模板。
基本上,映像只是一个文件系统存档,其中包含文件和目录结构以及容器的一些附加元数据(如ENV或CMD)。因此,您也可以将其视为一个tar或zip存档。
甲容器是图像的可运行实例。
要从镜像启动一个新容器,需要解压镜像docker,设置各自的命名空间,并使用解压后的镜像作为文件系统根启动一个进程。
该层通常所说的层通过在生成过程中创建的图像中,并且被用于高速缓存和重用在多个图像中的公共文件/层。因此,您只需要在Dockerfile.
而不是为每个新容器提取/复制图像内容,docker只会在存储该容器更改的图像顶部添加一个薄的可写层。这的确切机制是一个实现细节,取决于使用的存储驱动程序!在大多数情况下,使用时docker您不需要关心这一点。
现在使用docker-compose:它在后台所做的基本上是构建和执行相应的docker命令*,以根据您的docker-compose.yml配置文件运行和管理您的服务所需的容器。因此,让我们看看docker-compose与相应docker命令的关系:
docker-compose build: 将docker build使用指定build选项为每个服务执行相应的命令docker-compose pull: docker pulls 所有服务的图像,带有image来自相应存储库的选项docker-compose up:
docker-compose build/docker-compose pull所有您的服务docker run命令来启动服务容器docker-compose exec: 将运行docker exec以在现有的运行容器中启动新进程/命令docker-compose run: 启动一个新的容器来交互执行指定的命令,即执行docker run* 请注意,docker-compose它实际上并没有调用docker命令,而是docker直接使用 API与守护程序对话。但为了更容易理解,你可以假装它确实如此。
如果我运行
docker-compose exec some_command,那么我正在操纵 docker 容器 - 对吗?据我了解的文档,
docker-compose run some_command几乎是一样的,但是,它事先创建了一个新的“层”,所以…… 像这样:
docker-compose exec将在您现有的、正在运行的服务容器中运行,同时docker-compose run将启动一个新的、独立的容器。
此外,它似乎
run正在传递some_command到入口点,而exec确实覆盖了定义的入口点。
正确,exec不使用入口点。
run之后创建的新层会发生什么?有没有办法在不创建新层的情况下执行命令?
这些更改是由其启动的容器的一部分,run并将持续到您删除该容器为止。但是,如果要将更改应用于服务容器(由 使用docker-compose up),则需要运行docker-compose exec!
我想知道,因为我添加了一个这样的入口点脚本:
我这样做是为了能够通过运行像
docker-compose run backend update.
由于docker-compose run将在新容器中执行该命令,因此您需要运行docker-compose exec而不是手动调用入口点:
docker-compose exec app /entrypoint.sh update
# and if you need to restart your app restart the service containers
docker-compose restart
Run Code Online (Sandbox Code Playgroud)
然而,这是错误的使用方式docker!因为容器是短暂的,在容器中执行的命令只会影响该特定容器。当您必须在该映像上运行新的容器实例(您停止容器、电源故障等)时,所有更改都将丢失。
相反,您应该将update命令作为(最后一个)命令添加到您Dockerfile的图像中并重建(最后一层)图像:
docker-compose up --build
Run Code Online (Sandbox Code Playgroud)
或者,如果您必须跳过构建缓存以强制进行新构建:
docker-compose build --no-cache
docker-compose up
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3464 次 |
| 最近记录: |