New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Requests that return HttpDuplex (eg docker exec start) hang when using named pipe on windows. #83

Open
pirog opened this Issue Jul 22, 2017 · 1 comment

Comments

Projects
None yet
2 participants
@pirog

pirog commented Jul 22, 2017

Found an interesting situation that i was able to track down a bit. I am unsure if this is a bug with docker-modem or potentially how Docker for Windows sets up the named pipe to begin with.

Here is a file to reproduce (uses latest node-docker-api but upgraded to docker-modem 1.0.0), the same thing happens if you use analogous code for dockerode

'use strict'
const Docker = require('node-docker-api').Docker

const promisifyStream = (stream) => new Promise((resolve, reject) => {
  stream.on('data', (d) => console.log(d.toString()))
  stream.on('end', () => {
      if (process.stdin.setRawMode) {
        process.stdin.setRawMode(false);
      }
      process.stdin.pause();
      resolve()
  })
  stream.on('error', reject)
})

var thing
const docker = new Docker({ socketPath: '//./pipe/docker_engine' })
//const docker = new Docker({host: '127.0.0.1', port: 2375})
let _container

  docker.container.create({
    Image: 'debian:jessie',
    Cmd: [ '/bin/bash', '-c', 'tail -f /var/log/dmesg' ]
  })
  .then((container) => container.start())
  .then((container) => {
    _container = container
    return container.exec.create({
	    AttachStdin: true,
	    AttachStdout: true, 
	    AttachStderr: true,
	    Cmd: ['echo', 'thing'],
	    Tty: true
    })
  })
  .then((exec) => {
    return exec.start({ 
      hijack: false,
      Detach: false,
      Tty: true,
      stdin: true,
    })
  })
  .then((stream) => {
  	thing = stream
  })
  .then(() => {
  	thing.pipe(process.stdout);    

  	// Restart stdin with correct encoding
  	process.stdin.resume();
  	process.stdin.setEncoding('utf8');

  	// Make sure rawMode matches up
  	if (process.stdin.setRawMode) {
  	  process.stdin.setRawMode(true);
  	}        

  	// Send our processes stdin into the container
  	process.stdin.pipe(thing);

  })
  .then(() => promisifyStream(thing))
  .then(() => _container.delete({force: true}))
  .catch((error) => console.log(error))

If you connect over tcp (need to allow insecure connections in the docker for windows app first), it works as expected but if you switch over to the named pipe it will hang after "thing" is written to stdout. What is extremely interesting is after this happens you can get the stream to close and the process to resume by pressing any key three times.

Another interesting data point here is it looks like docker-compose itself avoids using the API for this on Windows, deciding to just delegate directly to a shell call to docker exec.
see: https://github.com/docker/compose/blob/master/compose/cli/main.py#L411

My best guesses at this point are:

  1. there is is some additional buffer with named pipes that is not being correctly flushed and its causing things to hang up
  2. writes are not happening or getting lost duringish reads

Any thoughts about why this could be happening?

@JoonasVali

This comment has been minimized.

JoonasVali commented Dec 13, 2018

Hi, I'm most likely running in to the same problem with Dockerode 2.5.4 which relies on Docker-modem 1.0.4 . Anything with exec.start gets stuck and won't terminate properly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment