I want my dockerized process to handle termination signals correctly, so I am using init:true
. I am using the following code in my docker-compose.yml
file:
version: '3.7'
services:
foo:
build:
context: ./foo
init: true
However, the signal is not being received by my process.
When I run my process outside of docker and hit Ctrl-C, I can see that the signal is being handled (my program prints a message in the signal handler), but inside of docker, the signal is not handled (my program doesn't print the message)
EDIT:
Here is 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"]
Here is foo/foo.go (just prints "waiting" messages in a loop until it receives a signal):
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")
}
}
When I build and run foo.go
without Docker, when I hit Ctrl-C, the program exits gracefully (prints "interrupt", "got done" and "exiting"). When I run with Docker, none of these messages are printed.... it just exits. In both cases, the pid printed is > 1.