Tag Archives: interactive

Running Docker Compose Interactively

I’ve recently been doing a fair bit of investigation into docker. My latest post was investigating the idea of setting up a sidercar pattern just using docker compose. In this post, I’m exploring the concept of launching an interactive shell using docker compose.

Why is this so hard?

Docker, and by extension, docker compose, are not really designed to run interactive tasks: they fare best left with ephemeral background tasks. However, in my particular use case, I needed to run a console app which accepted a keyboard input.

The system will let you create the console app as far as actually running, but once you issue a docker compose up, you’ll get something like the following error:

Unhandled exception. System.InvalidOperationException: Cannot read keys when either application does not have a console or when console input has been redirected. Try Console.Read.

How to run Interactively

In fact, there’s a few issues here, the first (as pointed out by this post) is that you need to tell docker compose to pass through the interactive mode to the container:

    build: .\My.App
    stdin_open: true
    tty: true    
      - "some-api"

stdin_open and tty translate to passing -it to the container. However, that doesn’t solve the problem entirely; if you issue a docker compose up you’ll still see the same issue.

The reason here is that there are (or can be) multiple containers, and so there’s no sensible way of knowing how to deal with that. In fact the solution is to simply tell docker compose which one to run; for example:

docker compose build --no-cache
docker compose run my-app

In the example above, that will also run the api some-api because we’ve declared a dependency. Note that build is optional; although while developing and debugging, I find it useful to execute both.

Beginner’s Guide to Docker – Part 1 – Creating and Running a Python Script

Disclaimer – This is pretty much my first time playing around with Python – there’s a good chance that what I’m doing here is wrong. All I can attest to is that it works.

I recently had cause to create a small python script. Instead of installing the Python libraries, it occurred to me that an easier way to do this might be to use docker to run the script: it worked, and so I thought I’d turn the whole thing into an introduction to Docker.


There are three main concepts in docker; and they closely mirror the concepts of any programming language: you have a script (or source code), an image (or compiled file), and a container (or running process).

In the case of docker, the script in question is called dockerfile.

Download Docker and Setup

The first step is to download docker and install the docker desktop:

If you haven’t, you may need to install WSL, too.

Create the Python Program, and a Dockerfile

The easiest way to do this is to find an empty directory on your machine. Use your favourite text editor to create a file called helloworld.py, with the following code:

print('Hello world python')

Now, in the same directory, create a file called Dockerfile, and add the following code to it:

FROM python
ADD helloworld.py .
CMD [ "python", "./helloworld.py" ]

We can now build that using the command:

docker build . --tag pcm-test

This command builds the image that we mentioned earlier. You can see this by issuing a command to see all the images:

docker images

For example:

We can now run this:

docker run pcm-test

This will run the script inside the container, and you should see the output.

Playing with the script

Let’s enhance our Python program (in exactly the same way as you enhance any “hello world” app):

import sys
print('Hello ' + sys.argv[1])

sys.argv is a zero based array of arguments – argument 0 is the name of the program running (hence 1 is the first real argument). If you try this with an argument that hasn’t been passed, you’ll get an array out of bounds exception.

We can change our Dockerfile to pass in the parameter:

FROM python
ADD helloworld.py .
CMD [ "python", "./helloworld.py", "wibble" ]

CMD essentially chains the array of commands together; the above is the equivalent of typing:

python ./helloworld.py wibble

Okay – well, obviously that’s pretty much the zenith of an hello world program… except, what if we want to ask the user for their name? Let’s try asking in our script:

import sys
print('Hello ' + sys.argv[1])
name = input("Yes, but what's your REAL name?")
print('Hello ' + name)

Unfortunately, if we build and run that, it’ll run, but will skip the input. To fix this, we’ll need to run the container in interactive mode:

docker run -it pcm-test


Well, that was a pleasant Saturday afternoon spent playing with Python and Docker. I’m not completely new to Docker, but I’d like to improve my knowledge, so my intention if to create several more of these, and explore some new features as I build these posts.