Running interactive commands in docker in Python subprocess

When I use docker run in interactive mode I am able to run the commands I want to test some python stuff.

root@pydock:~# docker run -i -t dockerfile/python /bin/bash
[ root@197306c1b256:/data ]$ python -c "print 'hi there'"
hi there
[ root@197306c1b256:/data ]$ exit
exit
root@pydock:~#

I want to automate this from python using the subprocess module so I wrote this:

  • Accessing docker container from iOS Simulator
  • How do I enter this dockerfile / nginx container?
  • First execution of Docker on a new EC2 Jenkins Slave does not work
  • Xdebug with PHPStorm and a Docker container
  • Dynamic mount point for Shared Volume Containers
  • AWS ECR image list
  • run_this = "print('hi')"
    random_name = ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(20))
    command = 'docker run -i -t --name="%s" dockerfile/python /bin/bash' % random_name
    subprocess.call([command],shell=True,stderr=subprocess.STDOUT)
    command = 'cat <<\'PYSTUFF\' | timeout 0.5 python | head -n 500000 \n%s\nPYSTUFF' % run_this
    output = subprocess.check_output([command],shell=True,stderr=subprocess.STDOUT)
    command = 'exit'
    subprocess.call([command],shell=True,stderr=subprocess.STDOUT)
    command = 'docker ps -a | grep "%s" | awk "{print $1}" | xargs --no-run-if-empty docker rm -f' % random_name
    subprocess.call([command],shell=True,stderr=subprocess.STDOUT)
    

    This is supposed to create the container, run the python command on the container and exit and remove the container. It does all this except the command is run on the host machine and not the docker container. I guess docker is switching shells or something like that. How do I run python subprocess from a new shell?

  • How can my docker stack automatically not reuse volumes on redeploy?
  • Are etcdctl client connections to etcd atomic?
  • How to get the name of a Docker container using JavaScript?
  • How to get Docker host IP on Travis CI?
  • Customize docker-java response to remove some logger like stream
  • Is there any definitive guide on how to pass all the arguments to Docker containers while starting a container through kubernetes?
  • 2 Solutions collect form web for “Running interactive commands in docker in Python subprocess”

    You actually need to spawn a new child on the new shell you are opening.So after docker creation run docker enter or try the same operation with pexpect instead of subprocess.`pexpect spawns a new child and that way you can send commands.

    It looks like you are expecting the second command cat <<... to send input to the first command. But the two subprocess commands have nothing to do with each other, so this doesn’t work.

    Python’s subprocess library, and the popen command that underlies it, offer a way to get a pipe to stdin of the process. This way, you can send in the commands you want directly from Python and don’t have to attempt to get another subprocess to talk to it.

    So, something like:

    from subprocess import Popen, PIPE
    
    p = Popen("docker run -i -t --name="%s" dockerfile/python /bin/bash", stdin=PIPE)
    p.communicate("timeout 0.5 python | head -n 500000 \n" % run_this) 
    

    (I’m not a Python expert; apologies for errors in string-forming. Adapted from this answer)

    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.