GNU/make和docker,终止运行进程
GNU/make and docker, terminate the running process
我正在使用 GNU/make (linux) 来包装一些 docker 命令,我不是每天都使用 docker 所以我很快就会忘记用法,其中一个包装器是 make serve
,它 运行 docker run
以 php -S
(内置服务器)作为命令,它启动并侦听连接。
要停止它我应该使用 ^C ,我相信(但我不确定)问题是 make
拦截信号,make 的目标失败但 php 进程(和 docker 实例)保持 运行ning,我必须手动停止它。
我尝试传递 --sig-proxy=true
和 false
但没有效果,但我 运行 使用伪终端 (-t
) 连接实例所以这是预期。
我写了一个 bash 包装器来在某些信号被捕获时回显某些消息 (EXIT TERM SIGTERM SIGQUIT KILL SIGKILL
) 和 exec php -S
,但我没有看到任何消息。
我不确定在 运行ning 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
Dockerfile
:
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
用 make docker-build
测试,然后 make serve
第二次编辑
我设法用 shell 脚本包装了 docker run
(我不确定 posix shell 中的陷阱语法,最终我去看看)
make
似乎第一次发送 INT
然后 EXIT
#!/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
,而在于信号处理。这是一个article描述它。
正如我之前所说,docker-compose
管理您服务的整个生命周期。
这是您的应用使用 docker-compose
的基本示例。通过 make up
和 make down
(包括 ^C
),因此您可以启动和停止您的服务。
Makefile
:
all:
.PHONY: docker-build serve
build:
docker-compose build
up:
docker-compose up
down:
docker-compose down
docker-compose.yml
:
version: '3.3'
services:
my_service:
build: .
ports:
- "8080:8080"
Dockerfile
:
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
我正在使用 GNU/make (linux) 来包装一些 docker 命令,我不是每天都使用 docker 所以我很快就会忘记用法,其中一个包装器是 make serve
,它 运行 docker run
以 php -S
(内置服务器)作为命令,它启动并侦听连接。
要停止它我应该使用 ^C ,我相信(但我不确定)问题是 make
拦截信号,make 的目标失败但 php 进程(和 docker 实例)保持 运行ning,我必须手动停止它。
我尝试传递 --sig-proxy=true
和 false
但没有效果,但我 运行 使用伪终端 (-t
) 连接实例所以这是预期。
我写了一个 bash 包装器来在某些信号被捕获时回显某些消息 (EXIT TERM SIGTERM SIGQUIT KILL SIGKILL
) 和 exec php -S
,但我没有看到任何消息。
我不确定在 运行ning 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
Dockerfile
:
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
用 make docker-build
测试,然后 make serve
第二次编辑
我设法用 shell 脚本包装了 docker run
(我不确定 posix shell 中的陷阱语法,最终我去看看)
make
似乎第一次发送 INT
然后 EXIT
#!/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
,而在于信号处理。这是一个article描述它。
正如我之前所说,docker-compose
管理您服务的整个生命周期。
这是您的应用使用 docker-compose
的基本示例。通过 make up
和 make down
(包括 ^C
),因此您可以启动和停止您的服务。
Makefile
:
all:
.PHONY: docker-build serve
build:
docker-compose build
up:
docker-compose up
down:
docker-compose down
docker-compose.yml
:
version: '3.3'
services:
my_service:
build: .
ports:
- "8080:8080"
Dockerfile
:
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