Я хочу, чтобы мой докеризованный процесс правильно обрабатывал сигналы завершения, поэтому я использую init:true
.Я использую следующий код в моем docker-compose.yml
файле:
version: '3.7'
services:
foo:
build:
context: ./foo
init: true
Однако мой процесс не получает сигнал.
Когда я запускаю свой процесс за пределами докера и нажмите Ctrl-C, я вижу, что сигнал обрабатывается (моя программа печатает сообщение в обработчике сигнала), но внутри докера, сигнал не обрабатывается (моя программане печатает сообщение)
РЕДАКТИРОВАТЬ :
Вот foo/Dockerfile
:
FROM golang:1.11.4-alpine3.8 AS build
WORKDIR /go/src/foo
COPY ./ ./
RUN go build -a -tags netgo .
FROM alpine:3.8
WORKDIR /app
COPY --from=build /go/src/foo .
CMD ["./foo"]
Вот foo / foo.go (просто печатает «ожидающие» сообщения в цикле, пока не получит сигнал):
package main
import (
"fmt"
"os"
"os/signal"
"time"
"syscall"
)
var done chan bool
var dur time.Duration
func main() {
sigs := make(chan os.Signal)
done = make(chan bool)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
pid := os.Getpid()
fmt.Println("pid:", pid)
go func() {
sig := <-sigs
fmt.Println(sig)
done <- true
}()
fmt.Println("waiting")
dur, _ = time.ParseDuration("2s")
waitLoop()
fmt.Println("exiting")
}
func waitLoop() {
for {
select {
case _ = <-done:
fmt.Println("got done")
return
case <- time.After(dur):
}
fmt.Println("still waiting")
}
}
Когда я собираю и запускаю foo.go
без Docker, когда я нажимаю Ctrl-C, программа корректно завершает работу (печатает)прерывание "," сделано "и" выход ").Когда я запускаю с Docker, ни одно из этих сообщений не печатается .... оно просто выходит.В обоих случаях напечатанный pid> 1.