我有一个包含 4 个容器的 docker-compose.yml
文件:redis
、postgres
、api
和 worker
。
在 worker
容器的开发过程中,我经常需要重新启动它以应用更改。有没有什么好方法可以重新启动单个容器(例如 worker
)而不重新启动其他容器?
很简单:使用命令:
docker-compose restart worker
您可以设置在杀死容器之前等待停止的时间(以秒为单位)
docker-compose restart -t 30 worker
请注意,这将重新启动容器,但不会重建它。如果您想应用更改然后重新启动,请查看其他答案。
重新启动单个节点的其他答案在目标上,docker-compose restart worker
。这将反弹该容器,但不包括任何更改,即使您单独重建它也是如此。您可以手动 stop
、rm
、create
和 start
,但还有更简单的方法。
如果您更新了代码,则可以通过以下步骤一步完成构建和重新加载:
docker-compose up --detach --build
这将首先从任何更改的代码中重建您的图像,如果没有更改,因为缓存被重用,这会很快。然后它只替换更改的容器。如果您下载的图像已过时,您可以在上述命令之前添加:
docker-compose pull
首先下载任何更改的图像(在您运行类似于上述 up
的命令之前,容器不会重新启动)。不需要进行初始停止。
并且仅对单个服务执行此操作,请按照 up 或 pull 命令使用您要指定的服务,例如:
docker-compose up --detach --build worker
这是第一个选项的快速示例,Dockerfile 的结构旨在将代码中频繁更改的部分保持在末尾附近。事实上,要求是为 pip install
单独提取的,因为该文件很少更改。由于 nginx 和 redis 容器是最新的,因此它们没有重新启动。整个过程的总时间不到 6 秒:
$ time docker-compose -f docker-compose.nginx-proxy.yml up --detach --build
Building counter
Step 1 : FROM python:2.7-alpine
---> fc479af56697
Step 2 : WORKDIR /app
---> Using cache
---> d04d0d6d98f1
Step 3 : ADD requirements.txt /app/requirements.txt
---> Using cache
---> 9c4e311f3f0c
Step 4 : RUN pip install -r requirements.txt
---> Using cache
---> 85b878795479
Step 5 : ADD . /app
---> 63e3d4e6b539
Removing intermediate container 9af53c35d8fe
Step 6 : EXPOSE 80
---> Running in a5b3d3f80cd4
---> 4ce3750610a9
Removing intermediate container a5b3d3f80cd4
Step 7 : CMD gunicorn app:app -b 0.0.0.0:80 --log-file - --access-logfile - --workers 4 --keep-alive 0
---> Running in 0d69957bda4c
---> d41ff1635cb7
Removing intermediate container 0d69957bda4c
Successfully built d41ff1635cb7
counter_nginx_1 is up-to-date
counter_redis_1 is up-to-date
Recreating counter_counter_1
real 0m5.959s
user 0m0.508s
sys 0m0.076s
-no-cache
选项一起使用吗?假设我在 package.json
中添加了一些内容并需要重新RUN npm install
,但 Dockerfile
本身并没有改变
COPY
命令中,则会自动破坏缓存。
COPY
命令。 git pull
将更新 package.json 文件,并且当 docker 看到您在不同的文件中复制时,构建缓存将中断。
ADD
将在缓存中得到与 COPY
相同的结果,但是(如最佳实践链接中所建议的)大多数不需要额外的功能,所以我什至不费心提及它。
要重新启动具有更改的服务,这里是我执行的步骤:
docker-compose stop -t 1 worker
docker-compose build worker
docker-compose up --no-start worker
docker-compose start worker
docker-compose up -d --build
,它将重新构建所有内容并重新启动任何更改的容器。无需先停止、停机、单独的创建和启动命令。
up
只会重新创建已更改的容器,因此需要重新启动。
docker-compose up -d --build
也会经常重新编译项目。
跟随命令
docker-compose restart worker
只会停止并启动容器。即不从 docker-compose.xml 加载任何更改
STOP 类似于 PC 中的休眠。因此 stop/start 不会查找在配置文件中所做的任何更改。要从容器 (docker-compose.xml) 的配方中重新加载,我们需要删除并创建容器(类似于重启 PC)
所以命令将如下
docker-compose stop worker // go to hibernate
docker-compose rm worker // shutdown the PC
docker-compose create worker // create the container from image and put it in hibernate
docker-compose start worker //bring container to life from hibernation
rm
行选项 -f
很方便(无提示)并且与当前 docker create
和 start
合并为 up
(所以我们总共有 3 个命令而不是 4 个),对于 up
选项-d
很有用(在后台执行)。
由于其他一些答案包括有关重建的信息,并且我的用例也需要重建,因此我有一个更好的解决方案(与那些相比)。
仍然有一种方法可以轻松地仅针对一个单独的 worker
容器,该容器在一行中重建 + 重新启动它,尽管它实际上不是一个命令。对我来说最好的解决方案是只需重建并重新启动:
docker-compose build worker && docker-compose restart worker
这对我来说同时实现了两个主要目标:
以单个工作容器为目标在一行中重建并重新启动它
希望这可以帮助其他人到达这里。
使用 docker-compose 文件重启服务
docker-compose -f [COMPOSE_FILE_NAME].yml restart [SERVICE_NAME]
用例 #1: 如果 COMPOSE_FILE_NAME 是 docker-compose.yml
并且服务是工作者
docker-compose restart worker
用例 #2: 如果文件名是 sample.yml
并且服务是工作者
docker-compose -f sample.yml restart worker
默认情况下,如果我们运行 docker-compose
命令,docker-compose 会查找 docker-compose.yml
,否则我们有标志以使用 -f [FILE_NAME].yml
给出特定文件名
这里的答案是关于对 docker-compose.yml 文件的更改的反映。
但是如果我想将我所做的更改合并到我的代码中怎么办,我相信这只有通过重建图像才能实现,并且我可以使用以下命令
1. docker 容器停止
docker stop container-id
2. docker 容器移除
docker rm container-id
3. docker镜像移除
docker rmi image-id
4. 再次组合容器
docker-compose up container-name
docker-compose up [service key]
简单的“docker”命令对“worker”容器一无所知。使用这样的命令
docker-compose -f docker-compose.yml restart worker
重启容器
如果您只想重新启动容器:
docker-compose restart servicename
将此命令视为“只需按名称重新启动容器”,相当于 docker restart
命令。
注意事项:
如果您更改了 ENV 变量,它们将不会在容器中更新。您需要停止它并重新开始。或者,使用单个命令 docker-compose up 将检测更改并重新创建容器。正如许多其他人提到的,如果您更改了 docker-compose.yml 文件本身,简单的重启将不会应用这些更改。如果您在构建阶段将代码复制到容器中(在 Dockerfile 中使用 ADD 或 COPY 命令),则每次代码更改时,您都必须重新构建容器(docker-compose build)。
与您的代码的相关性
如果您的代码通过 docker-compose.yml
中的卷指令将路径映射到容器中,docker-compose restart
应该可以正常工作,如下所示:
services:
servicename:
volumes:
- .:/code
但我建议使用实时代码重新加载,这可能由您在调试模式下选择的框架提供(或者,您可以搜索您选择的语言的自动重新加载包)。添加它应该消除每次代码更改后重新启动容器的需要,而不是重新加载内部进程。
进行更改后,您需要将更改拉入服务器,然后重新创建容器。如 documentation 所示:
docker-compose pull worker && docker-compose up -d --no-deps worker
pull worker
只会将此项目拉入服务器,--no-deps
将阻止重新启动 worker
容器所依赖的容器。
不定期副业成功案例分享
docker-compose restart
命令不会应用任何更改。 “如果您对docker-compose.yml
配置进行更改,这些更改不会在运行此命令后反映出来。”因此使用docker-compose up -d --build
。 docs.docker.com/compose/reference/restartdocker ps -a
时看到的任何名称docker-compose build <container name>
,restart
也不会应用更改,这是一个无效/不正确的答案。