While writing the Industrial IoT series, I came up with this trick that may be of use to you as well.
Installing python can be a daunting task. If you are reading this from a web search, then you likely already know this. I will quickly cover how first then cover it again in detail to explain why.
TL;DR
2: Run this command:
docker run -it -v "${PWD}":/a -w /a python:3 python script.py
Adjust python:3 as needed to the version of Python you need from these options, but generally, you can use python:3 or python:2 and be good.
3: There is no step three
Detailed Step-by-Step
1. Install Docker
Follow the instructions at Docker.com for installing Docker on your OS. If you have it installed, but haven’t updated, now would be a good time to do so.
2. Run Docker
Note that containers, much like virtual machines (VMs), run in their own environment. We’ll describe that environment as internal and your computer’s shell, filesystem, and network as external. Said differently: When python is running, there will be two nested contexts that the python interpreter is running in: the internal one and the external one. The external one is your normal outside-of-Docker shell. The internal one is inside the Docker container and is the only environment that python can see directly.
Note that these examples use bash-like shell syntax. You will need to adjust the commands if you’re using PowerShell, for example.
Back to our example (slightly modified to ease description):
docker run -it -v "${PWD}":/local-data -w /local-data python:3 python script.py
Now to break this down into easily digested pieces and explain the options:
- docker run […] python:3 will download (if needed) the standard python 3.x docker container from Docker Hub.
- The part after the : is the “tag” and here you’ll see all of the options, and there are many, most of them for specific versions of python, including versions of python 2. Generally, you can use python:3 or python:2and be good.
- -it tells docker to make it interactive and use a tty (which basically also enables interactivity with your terminal, so you will normally see those two together).
- -v “${PWD}”:/local-data tells docker to make a read/write mount of the external working directory (“${PWD}”) to an internal path (/local-data). This “pushes” (loosely speaking) the local directory and all of its contents into the container at the path specified after the :. You can arbitrarily change /local-data as needed as long as it doesn’t cause trouble with one of the built-in Linux paths. You can use / or /tmp for example, but you should probably avoid /etc or /dev. If you make up a path (like /a that we used in the first example) it will make it. You can have multiple -v … options to mount multiple paths.
Note: What’s written to the mounted volume(s) will be changing files in the mounted real directory. What’s written to any path outside the mounted volume(s) will be lost.
- The -w /local-data portion tells it to set the initial working directory inside the container to /local-data which is where we mounted the external working directory. If you change -v … then you probably want to change -w … as well.
- python script.py is actually running your script. The python binary is built into the Docker image (that’s why we’re all here, right?). script.py is almost certainly something you’ll want to change, particularly if you change the -v … portion.
Additional notes
It bears repeating: The script can write to anywhere in the container, but only what’s in mounted volumes will be saved to the external filesystem. When python exits and the container stops running, everything else will be lost.
If your python script connects to external services, it should work without issue. If your python script listens for network connections you’ll need to publish or expose ports of the container to interact with them, much like you have to mount volumes to interact with the local (external) filesystem. If you need to run services in this manner or have docker containers speak to each other then it is worth looking into docker compose.
And if you really want to see the full power of Docker then a decent place to start is reading the documentation for the docker run command.