如何通过Makefile从容器内部退出运行中的Docker容器
问题原因
你写的stop目标里的exit不生效,核心逻辑是:make执行目标下的每一行命令时,都会单独fork一个shell子进程来运行,你写的exit只会退出这个临时创建的子shell,根本影响不到你当前正在交互的容器主shell进程,所以执行完只会打印一行exit文本,仍然停留在容器终端里。
可行实现
有两种无额外依赖的方式可以实现容器内执行make stop直接退出当前容器:
方案1:终止容器PID 1进程
Docker容器启动后,第一个运行的进程(也就是你进入容器时的交互shell)PID固定为1,只要向这个进程发送终止信号,容器就会因为主进程退出自动停止(配合你启动时加的--rm参数会自动清理)。修改后的Makefile如下:
start: $(info Make: Starting container.) docker run -it --rm -v $(shell pwd):/mnt -w /mnt build:focal stop: $(info Make: Stopping container.) kill -s SIGTERM 1
这个方案不需要给容器加额外权限、不需要预装额外工具,是最轻量的实现方式,本地开发场景直接用就行。
方案2:挂载docker.sock从内部调用docker命令停容器
如果不想直接操作PID 1,可以在启动时给容器固定名称,同时把宿主机的docker套接字挂载进容器,让容器内可以直接操作宿主机docker服务,stop目标直接调用docker命令终止自身:
CONTAINER_NAME = build-focal-demo start: $(info Make: Starting container.) docker run -it --rm --name $(CONTAINER_NAME) -v /var/run/docker.sock:/var/run/docker.sock -v $(shell pwd):/mnt -w /mnt build:focal stop: $(info Make: Stopping container.) docker stop $(CONTAINER_NAME)
- 这个方案需要提前在构建镜像时安装docker客户端,否则会找不到docker命令
- 挂载docker.sock相当于给了容器宿主机docker的完全控制权限,仅限本地开发使用,不要在生产环境这么配置
内容的提问来源于stack exchange,提问作者goodman
相关产品推荐
相关产品推荐

