dockerdocker-rundocker-exec

Write to stdin of running docker container


Say I run a docker container as a daemon:

docker run -d foo

is there a way to write to the stdin of that container? Something like:

docker exec -i foo echo 'hi'

last time I checked the -i and -d flags were mutually exclusive when used with the docker run command.


Solution

  • In principle you can docker attach to it. CTRL+C will stop the container (by sending SIGINT to the process); CTRL+P, CTRL+Q will detach from it and leave it running (if you started the container with docker run -it).

    The one trick here is that docker attach expects to be running in a terminal of some sort; you can do something like run it under script to meet this requirement. Here's an example:

    # Create a new empty directory
    mkdir x
    
    # Run a container, in the background, that copies its stdin
    # to a file in that directory
    docker run -itd -v $PWD/x:/x --name cat busybox sh -c 'cat >/x/y'
    
    # Send a string in
    echo foo | script -q /dev/null docker attach cat
    # Note, EOF here stops the container, probably because /bin/cat
    # exits normally
    
    # Clean up
    docker rm cat
    
    # See what we got out
    cat x/y
    

    In practice, if the main way a program communicates is via text on its standard input and standard output, Docker isn't a great packaging mechanism for it. In higher-level environments like Docker Compose or Kubernetes, it becomes progressively harder to send content this way, and there's frequently an assumption that a container can run completely autonomously. Just invoking the program gets complicated quickly (as this question hints at). If you have something like, say, the create-react-app setup tool that asks a bunch of interactive questions then writes things to the host filesystem, it will be vastly easier to run it directly on the host and not in Docker.