从Node.js中的docker容器获取stdout和stderr流

时间:2017-06-29 15:32:12

标签: node.js docker

我正在使用dockerode库,我想创建一个容器,在其中执行一个(单个)命令,然后(单独)返回该命令的标准输出和标准错误。

到目前为止,我能够获得 stdout ,但我没有运气 stderr 。我在 Github 问题中找到了很多方法,但这些都没有奏效。

我的代码是(我使用promises和coroutines来避免回调):

const Promise = require('bluebird');
const coroutine = Promise.coroutine;
const Docker = require('dockerode');

const docker = coroutine.promisifyAll(new Docker());

const foo = coroutine(function*(){

    let container = Promise.promisifyAll(yield docker.createContainerAsync(/*...*/));

    yield container.startAsync(/*...*/);

    const execOpts = {Cmd: /*...*/, AttachStdout: true, AttachStderr: true, Tty: true};
    const exec = Promise.promisifyAll(yield container.execAsync(execOpts));                      
    const stream = yield exec.startAsync();


    let data = [];
    stream.on('data', chunk => {
            data.push(chunk);
    }); 

    stream.on('end', () => {
        stdoutData = Buffer.concat(data).toString()
    });


    let executionData = yield exec.inspectAsync();
    while (executionData.Running) { executionData = yield exec.inspectAsync(); }                                                         

    return {
        stdout: stdoutData,
        stderr: 
    }

});

注意:在dockerode's npm documentation中有一个实现我想要的示例,但我无法找到全局对象process以及如何在我的代码中使用它:

//tty:true 
docker.createContainer({ /*...*/ Tty: true /*...*/ }, function(err, container) {

/* ... */

container.attach({stream: true, stdout: true, stderr: true}, function (err, stream) {
  stream.pipe(process.stdout);
});

/* ... */
}

//tty:false 
docker.createContainer({ /*...*/ Tty: false /*...*/ }, function(err, container) {

/* ... */

container.attach({stream: true, stdout: true, stderr: true}, function (err, stream) {
  //dockerode may demultiplex attach streams for you :) 
  container.modem.demuxStream(stream, process.stdout, process.stderr);
});

/* ... */
}

docker.createImage({fromImage: 'ubuntu'}, function (err, stream) {
stream.pipe(process.stdout);
});

1 个答案:

答案 0 :(得分:1)

只需使用.demuxStream

demuxStream - demux stdout and stderr
//demuxStream(stream, stdout, stderr) 
container.attach({
  stream: true,
  stdout: true,
  stderr: true
}, function handler(err, stream) {
  //... 
  container.modem.demuxStream(stream, process.stdout, process.stderr);
  //... 
});

process对象是表示当前进程的全局变量:

  

流程对象是一个全局,提供有关当前Node.js流程的信息并对其进行控制。

process.stderrprocess.stdoutWriteable Streams代表当前进程STDOUT和STDERR:

  

process.stderr属性返回连接到stderr(fd 2)的流。它是一个net.Socket(它是一个Duplex流),除非fd 2引用一个文件,在这种情况下它是一个可写的流。

     

process.stdout属性返回连接到stdout(fd 1)的流。它是一个net.Socket(它是一个Duplex流),除非fd 1引用一个文件,在这种情况下它是一个可写的流。

即。上面的例子只是将容器的流重定向到当前进程的STDERR和STDOUT。但您可以自由使用任何其他可写流。