GNU/make和docker,终止运行进程

GNU/make and docker, terminate the running process

我正在使用 GNU/make (linux) 来包装一些 docker 命令,我不是每天都使用 docker 所以我很快就会忘记用法,其中一个包装器是 make serve,它 运行 docker runphp -S(内置服务器)作为命令,它启动并侦听连接。

要停止它我应该使用 ^C ,我相信(但我不确定)问题是 make 拦截信号,make 的目标失败但 php 进程(和 docker 实例)保持 运行ning,我必须手动停止它。

我尝试传递 --sig-proxy=truefalse 但没有效果,但我 运行 使用伪终端 (-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 upmake 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