GNU/make和docker,终止正在运行的进程
我正在使用GNU/make(linux)包装一些docker命令,我不是每天都使用docker,所以我很快就会忘记它的用法,其中一个包装器是GNU/make和docker,终止正在运行的进程,docker,signals,gnu-make,Docker,Signals,Gnu Make,我正在使用GNU/make(linux)包装一些docker命令,我不是每天都使用docker,所以我很快就会忘记它的用法,其中一个包装器是makeserve,它运行docker run,使用php-S(内置服务器)作为命令,它启动并侦听连接 要停止它,我应该使用^C,我相信(但我不确定)问题在于make拦截信号,make的目标失败,但php进程(和docker实例)仍在运行,我必须手动停止它 我尝试传递--sig proxy=true和false,但没有效果,但我正在使用伪终端(-t)运行实例
makeserve
,它运行docker run
,使用php-S
(内置服务器)作为命令,它启动并侦听连接
要停止它,我应该使用^C,我相信(但我不确定)问题在于make
拦截信号,make的目标失败,但php进程(和docker实例)仍在运行,我必须手动停止它
我尝试传递--sig proxy=true
和false
,但没有效果,但我正在使用伪终端(-t
)运行实例,因此这是意料之中的
我编写了一个bash包装器,当某个信号被捕获(EXIT TERM SIGTERM SIGQUIT KILL SIGKILL
)和exec php-S
时,它会回显一些消息,但我没有看到任何消息
我不确定在运行的make上按下^C时会发生什么,如果信号(以及什么)仅传播到分叉的sh-C
,以及为什么在docker run
中不起作用
我想知道是否有其他人有这个问题并解决了,或者是否有人能想出其他解决方案
编辑
Makefile
:
all:
.PHONY: docker-build serve
docker-build:
docker build -f Dockerfile -t sigtest:v1 .
serve:
docker run -t --rm sigtest:v1 gosu ubuntu:ubuntu php7.0 -S 0.0.0.0:8081 -t /home/ubuntu
FROM ubuntu:16.04
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends php7.0-cli gosu
RUN useradd -ms /bin/bash ubuntu
all:
.PHONY: docker-build serve
build:
docker-compose build
up:
docker-compose up
down:
docker-compose down
FROM ubuntu:16.04
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends php7.0-cli gosu
RUN useradd -ms /bin/bash ubuntu
RUN mkdir -p /home/ubuntu
RUN php7.0 --version
ENTRYPOINT php7.0 -S 0.0.0.0:8080
Dockerfile
:
all:
.PHONY: docker-build serve
docker-build:
docker build -f Dockerfile -t sigtest:v1 .
serve:
docker run -t --rm sigtest:v1 gosu ubuntu:ubuntu php7.0 -S 0.0.0.0:8081 -t /home/ubuntu
FROM ubuntu:16.04
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends php7.0-cli gosu
RUN useradd -ms /bin/bash ubuntu
all:
.PHONY: docker-build serve
build:
docker-compose build
up:
docker-compose up
down:
docker-compose down
FROM ubuntu:16.04
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends php7.0-cli gosu
RUN useradd -ms /bin/bash ubuntu
RUN mkdir -p /home/ubuntu
RUN php7.0 --version
ENTRYPOINT php7.0 -S 0.0.0.0:8080
使用make docker build
进行测试,然后使用make service
第二次编辑
我设法用一个shell脚本包装了docker run
(我不确定posix shell中的陷阱语法,最终我会看一看)
make
似乎第一次发送INT
,然后退出
#!/bin/sh
pid=$$
trap 'trap - INT EXIT; echo " signal received, wait..."; docker stop -t 0 sig${pid}; exit' INT EXIT
docker run --name=sig${pid} "$@"
然后在Makefile
serve:
-./docker-run.sh -t --rm sigtest:v1 gosu ubuntu:ubuntu php7.0 -S 0.0.0.0:8081 -t /home/ubuntu
我希望不必命名实例,但这是我能想到的最简单的方法。问题不在于使用make
,而在于信号处理。下面是一个描述它的例子
正如我之前所说,docker compose管理您服务的整个生命周期
下面是一个使用docker compose
的应用程序的基本示例。通过make
和make down
(包括^C
),您可以启动和停止服务。
Makefile
:
all:
.PHONY: docker-build serve
docker-build:
docker build -f Dockerfile -t sigtest:v1 .
serve:
docker run -t --rm sigtest:v1 gosu ubuntu:ubuntu php7.0 -S 0.0.0.0:8081 -t /home/ubuntu
FROM ubuntu:16.04
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends php7.0-cli gosu
RUN useradd -ms /bin/bash ubuntu
all:
.PHONY: docker-build serve
build:
docker-compose build
up:
docker-compose up
down:
docker-compose down
FROM ubuntu:16.04
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends php7.0-cli gosu
RUN useradd -ms /bin/bash ubuntu
RUN mkdir -p /home/ubuntu
RUN php7.0 --version
ENTRYPOINT php7.0 -S 0.0.0.0:8080
docker compose.yml
:
version: '3.3'
services:
my_service:
build: .
ports:
- "8080:8080"
Dockerfile
:
all:
.PHONY: docker-build serve
docker-build:
docker build -f Dockerfile -t sigtest:v1 .
serve:
docker run -t --rm sigtest:v1 gosu ubuntu:ubuntu php7.0 -S 0.0.0.0:8081 -t /home/ubuntu
FROM ubuntu:16.04
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends php7.0-cli gosu
RUN useradd -ms /bin/bash ubuntu
all:
.PHONY: docker-build serve
build:
docker-compose build
up:
docker-compose up
down:
docker-compose down
FROM ubuntu:16.04
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends php7.0-cli gosu
RUN useradd -ms /bin/bash ubuntu
RUN mkdir -p /home/ubuntu
RUN php7.0 --version
ENTRYPOINT php7.0 -S 0.0.0.0:8080
你能发布一个简化版的Makefile
吗?Hello@DanilaKiver,请看编辑,感谢之前类似的问题并切换到。它有管理整个生命周期的命令,包括启动和停止服务。Alex,当然,也许几乎任何解决方案都可以消除这个问题,但这就是重点,我已经使用make多年了,我想继续。但是你给了我一个主意,也许在docker之外用脚本包装docker运行,而不是在里面包装php。。。我会尝试一下,谢谢。这很好,但我在makefile中还有一些其他目标,例如从某个源代码构建并退出(无需侦听),使用不同的配置(至少是dev和prod),docker compose可以处理该场景吗?docker compose build
只构建服务,docker compose up
将通过执行Dockerfile
中的ENTRYPOINT php7.0-S 0.0.0.0:8080
行启动php
服务器。还有更复杂的例子