Created
January 12, 2017 19:12
-
-
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 file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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