Skip to content
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 · 2 comments

Comments

@pirog
Copy link

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
Copy link
Contributor

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.

@nicks
Copy link

nicks commented Sep 1, 2022

docker desktop 4.12 has a compatibility shim that should fix this.
https://docs.docker.com/desktop/release-notes/#bug-fixes-and-minor-changes
see my comments about it here: apocas/dockerode#534

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants