Convox Community

Graceful process shutdown for overridden commands

I have a ruby app where we have several services all built off a single Docker image - my convox.yml has under each non-default service, such as a background worker, an entry like:

build: . 
command: bundle exec resque-pool

When it gets terminated (eg during a deploy), it does not seem to be gracefully shutting down (ECS/docker should be sending a SIGTERM), here’s the process tree:

  PID TTY      STAT   TIME COMMAND
    1 ?        Ss     0:06 /dev/init -- /convox-env sh -c bundle exec resque-pool
    6 ?        S      0:00 sh -c bundle exec resque-pool
   12 ?        Sl     0:53  \_ resque-pool-master[app]: managing [14]
   14 ?        Sl     2:34      \_ resque-1.25.2: Waiting for *

If a convox service does not have a command in convox.yml, as in something that uses the default CMD from the Dockerfile, it will set that process as PID 1, allowing it to get the signal as expected and gracefully shutdown. I’ve also tried using the docker init process, but that didn’t change how the command was run.

Any tricks for being able to trap & handle the signal or otherwise be able for these to gracefully terminate? I suppose I could make a separate Dockerfile for each service, but that would be a bit of duplication.

I’ve found something that can work for what I want - using the exec shell built in as part of the convox command override works. For example, for a service in convox.yml

command: exec bundle exec puma

Will result in a docker container like this with the command as PID 1 as I want it. This also works when using docker init.

# ps axf
  PID TTY      STAT   TIME COMMAND
  353 pts/0    Ss     0:00 sh -c bash
  365 pts/0    S      0:00  \_ bash
  393 pts/0    R+     0:00      \_ ps axf
    1 ?        Ssl    0:04 puma 3.12.1 (tcp://0.0.0.0:9292) [app]