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:

  • Keeping PostgreSQL data in docker and OSX
  • Docker: RUN pip install boto succeeds but is missing from the resulting image
  • Why doesn't Webpack-Dev-Server (inside docker container) detect file changes when used with a new Vue.js CLI Webpack Template Project?
  • SSH into a DC/OS created public agent node to deploy a Docker container?
  • docker-machine create breaks at `DBG | Filling zeroes`
  • How do I specify a node for a docker stack container?
  • 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?

  • Error Docker deployment in Amazon Elastic Beanstalk - Docker container quit unexpectedly
  • Does docker stack deploy work with local images
  • Something missing in configuration for publishing from VS to Docker on Ubuntu?
  • Importing a MySQL database with a Python script fails when the same command works on the command line, what gives?
  • Docker: how to fix “Layer already being pulled by another client. Waiting”
  • Docker Entrypoint for Postgres 9.3
  • 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.