Skip to content

Instantly share code, notes, and snippets.

@eighteyes
Created January 12, 2017 19:12
Show Gist options
  • Save eighteyes/04c43b6e7c18d8591f2060d75f5aa68f to your computer and use it in GitHub Desktop.
Save eighteyes/04c43b6e7c18d8591f2060d75f5aa68f to your computer and use it in GitHub Desktop.
NodeJS : Spawn STDIN / STDOUT messaging to node process inside a Docker container
// This is the outside in approach, where the parent process is not within Docker, but the child lives in a docker image.
var externalNodeProcess = require('child_process').spawn('docker', [
'run',
'-a', 'stdin', '-a', 'stdout', '-a','stderr',
'-i',
'image/name:tag',
'node','index.js'
], {
stdio: ['pipe', 'pipe', 'pipe']
});
// to make it compatible with `fork` syntax
// provide send to stdin
externalNodeProcess.send = function(msg){
app.process.stdin.write(JSON.stringify(msg)+'\n');
}
// provide on('message') events from stdout - this will also fire on console.log commands, so you need to wrap those if you want to do any other sort of messaging
externalNodeProcess.stdout.on('data', function writeOutDockerLog(data) {
let msgs = [];
try {
data.toString().split('\n').map((m) => { if ( !_.isEmpty(m) ) msgs.push(JSON.parse(m + '\n')); })
} catch (e) {
console.error('Docker STDOUT Error:', e, data.toString())
} finally {
msgs.forEach((m)=>{
externalNodeProcess.emit('message', m);
})
}
});
// INSIDE the external index.js which is Dockerized
//---------- index.js -------------
// fork provides process.send() . no fork means it's been spawned
if ( !_.isFunction(process.send)){
console.log('Docker Detected');
process.send = function(obj){
try {
var send = JSON.stringify(obj);
} catch (e) {
console.error('App Data Error', e, obj);
} finally {
process.stdout.write(`${send}\n`);
}
}
process.stdin.on('readable', function(){
const msg = process.stdin.read();
// multiple msgs might be sent in one event
let msgs = _.compact(msg.toString().split('\n'));
let msgObjs = [];
if ( !_.isNull(msg)){
try {
// parse each one independently! - woot working
msgObjs = msgs.map((m) => { return JSON.parse(m) });
} catch (e){
console.error('App Data In Error:', e, msgs)
} finally {
// emit one event for each msg found
if (msgObjs.length > 0) {
msgObjs.forEach((m) => {
process.emit('message', m);
});
}
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment