child_process didn't receive SIGTERM inside docker container

1.9k views Asked by At

I'm writing test for electron application in typescript.

Inside application there are register listener for SIGTERM

    process.on('SIGTERM', async () => {
      console.log('before exit');
      await this.exit(); //some inner function can't reach this statement anyway
    });

Locally everything fine, but on CI when app running inside docker container looks like it didn't receive SIGTERM.

For starting application I'm using child_process.spawn

import type { ChildProcess } from 'child_process';
let yarnStart: ChildProcess = spawn('yarn', 'start', { shell: true });

// 'start' is just script in package.json

I try to kill application three different way and none of them works. Application didn't receive SIGTERM no before exit and after manually stopping ci-build in final-step ps aux showing my process.

// 1-way
yarnStart.kill('SIGTERM');

// 2-way
process.kill(yarnStart.pid, 'SIGTERM');

// 3-way
import { execSync } from 'child_process';
execSync(`kill -15 ${yarnStart.pid}`);

Why nodejs can't properly send SIGTERM inside docker container?


Only difference - locally I have debian-9(stretch) and image based on debian-10(buster). Same nodejs version 12.14.1. I will try to build container with stretch to see how it will behave, but skeptical about that this will help.


UPD There is kind of difference in processes initiation(due to running scripts on CI in container, any instruction runs with /bin/sh -c)

when you execute ps aux you will see

//locally
myuser   101457  1.3  0.1 883544 58968 pts/8    Sl+  10:32   0:00 /usr/bin/node /usr/share/yarn/bin/yarn.js start
myuser   101468  1.6  0.2 829316 69456 pts/8    Sl+  10:32   0:00 /usr/bin/node /usr/share/yarn/lib/cli.js start
myuser   101479  1.6  0.2 829576 69296 pts/8    Sl+  10:32   0:00 /usr/bin/node /usr/share/yarn/lib/cli.js start:debug
myuser   101490  0.2  0.0 564292 31140 pts/8    Sl+  10:32   0:00 /usr/bin/node /home/myuser/myrepo/electron-app/node_modules/.bin/electron -r ts-node/register ./src/main.ts
myuser   101497  143  1.4 9215596 485132 pts/8  Sl+  10:32   0:35 /home/myuser/myrepo/node_modules/electron/dist/electron -r ts-node/register ./src/main.ts
//container
root       495  0.0  0.0   2392   776 ?        S    09:05   0:00 /bin/sh -c yarn start
root       496  1.0  0.2 893240 74336 ?        Sl   09:05   0:00 /usr/local/bin/node /opt/yarn-v1.22.5/bin/yarn.js start
root       507  1.7  0.2 885588 68652 ?        Sl   09:05   0:00 /usr/local/bin/node /opt/yarn-v1.22.5/lib/cli.js start
root       518  0.0  0.0   2396   712 ?        S    09:05   0:00 /bin/sh -c yarn start:debug
root       519  1.7  0.2 885336 68608 ?        Sl   09:05   0:00 /usr/local/bin/node /opt/yarn-v1.22.5/lib/cli.js start:debug
root       530  0.0  0.0   2396   780 ?        S    09:05   0:00 /bin/sh -c electron -r ts-node/register ./src/main.ts
root       531  0.3  0.0 554764 32080 ?        Sl   09:05   0:00 /usr/local/bin/node /opt/ci/jobfolder/job_id_423/electron-app/node_modules/.bin/electron -r ts-node/register ./src/main.ts
root       538  140  1.5 9072388 520824 ?      Sl   09:05   0:26 /opt/ci/jobfolder/job_id_423/node_modules/electron/dist/electron -r ts-node/register ./src/main.ts

And actually killing process with

// 1-way
yarnStart.kill('SIGTERM');

works but it kills only /bin/sh -c yarn start and his child_process /usr/local/bin/node /opt/yarn-v1.22.5/bin/yarn.js start that actually spawn application still hanging

1

There are 1 answers

0
Tymur Kubai aka SirDiR On

/bin/sh -c which comes with a load of problems, one of them notably that you’ll never see a signal in your application. And descendant processes create they own /bin/sh -c

I find a solution in https://stackoverflow.com/a/33556110/4577788


Also find alternative solution(but it didn't work for me, maybe becaus of specifics of nodejs execution). You can kill all the processes belonging to the same process tree using the Process Group ID. More datailed info can be found here https://stackoverflow.com/a/15139734/4577788

When I try to execute execSync('kill -- -942'); or execSync('kill -- "-942"');

Error occure kill: illegal number -, didn't find why it occure and hove to fix it.