So here I am with a full month of Docker under my belt, wondering what I can do to show myself my progress. To decide what to write about this week, let me start from scratch: what do I know?
I know that to run a docker container, I need a docker image. And to build a docker image, I need a Dockerfile, which contains the files plus metadata necessary to run a self-contained environment. The environment includes an operating system and the application I wish to run. For example, if I want to run a Python3 shell inside a container as if I were running it on my local machine's terminal, then I'm going to need, at a minimum, the following environment:
- an operating system on which to run Python3
- the Python3 programming language installed on the OS
- a command line interface to interact with Python3 in shell mode
In other words, I need to be able to run the Python3 shell inside a terminal inside a Linux Docker container.
First up is the operating system.
Python is a pretty lightweight language that just about any operating system can handle. So I want to use a super lightweight Linux distribution to serve as my operating system for this exercise. In lieu of Ubuntu, let's go with Alpine, which is 1/10th the size.
If I run the following command from my Docker CLI, though, I'll run into trouble right away:
docker run alpine
I won't want to run just this command, because if I do, then this happens:
- my Docker client calls the docker daemon via the Docker API
- it tells the daemon that I want to run an alpine container (totally is true)
- the daemon will dutifully do all this stuff:
- pull the alpine image from Docker Hub 💪🏾
- run the alpine image on my Docker server 💪🏾
- run an alpine container from this image 💪🏾
- immediately exit said container 😤
This is because the Dockerfile for an alpine image has but one command that runs as default:
So when I tell Docker to pull or run alpine, it does that, and the base image runs, and it does what it's supposed to, but then the shell a) doesn't receive any additional instructions, b) determines that there is nothing for it to do, and consequently c) stops running, which leaves the container without a process to run, causing the container to be terminated (exited). No process, no container. I get it.
Side Note 1: This can be confirmed with the
docker ps -acommand, which will show that an alpine container did indeed momentarily run but was then exited.
This is of course no good to me if what I want to do is run Python3 inside a container.
So it's time to break out the useful -ti flag.
For all the above reasons, I run the following instead:
docker run -ti alpine
There we go. Now the docker daemon will do its thing again, but this time, the alpine container won't exit. The combo of the two Docker flags
i will instruct Docker to please allocate me a terminal and patiently listen for my input.
I'll now be able to use the built-in shell to move on to my next step: installing Python3 inside this container.
Alpine Linux doesn't come with Python3 pre-installed. You have to install it manually. It's very simple to do with the alpine package manager,
apk. A quick check of the Alpine Linux APK website shows that python3 is indeed one of the packages.
Since I'm now running an Alpine Linux docker container with an interactive terminal waiting for me to provide further instruction, I can proceed:
apk add python3
This will install python3 on my alpine operating system inside the Docker container. I can confirm the installation afterwards by typing
python3 --version into the alpine terminal, which outputs
/ # python3 --version Python 3.7.5
We're in business! On to the final step: launching Python3 in shell mode.
Side Note 2: By the way, the presence of
/ #indicates that I'm in the interactive shell terminal within my alpine container.
At last, I can run Python3. Since I just installed python3, I can simply run it by typing
/ # python3 Python 3.7.5 (default, Oct 17 2019, 12:25:15) [GCC 8.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
The presence of
>>> indicates that I'm in Python3's shell mode. That is, I am now actually running the Python3 application. Now for the fun stuff! 😎
Now that I have Python running in shell mode inside an interactive shell terminal inside an Alpine Docker container, I can take on a fun challenge. For example, my Educative team recently wrote a blog post with six fun Python challenges.
Let's try two of them right now :).
Here was my team's prompt to readers:
Challenge accepted. In my Docker container, I type this:
>>> print("Hello World\nLet's Learn Python\nSincerely, Alex")
And the Python shell prints the following:
Hello World Let's Learn Python Sincerely, Alex
Here was my team's prompt to readers:
They also provided the following values:
G = 6.67 x 10^-11
MSun = 2.0 x 1030
mEarth = 6.0 x 1024
r = 1.5 x 1011
So in my Docker container, I created variables
r and stored their respective values in each, using Python-friendly scientific notation. Then I created the variable
grav_force as instructed, though converting it into the Python-friendly notation. Finally, I instructed Python to print the variable I just created, outputting the result of Newton's beautiful gravitational force equation.
Putting this all together, it was like so:
>>> G = 6.67e-11 >>> M = 2.0e30 >>> m = 6.0e24 >>> r = 1.5e11 >>> grav_force = (G*M*m)/(r*r) >>> print(grav_force) 3.5573333333333336e+22
Close enough, and not bad for this all running inside a Docker container! :)
I then type
(exit) to exit the Python3 shell, and then
exit to exit the alpine container I've been using. To confirm that the daemon terminated the container, I use
docker ps -a -l, and it shows me that the last container that ran indeed was exited, seconds ago.
I've once again run out of time to write all the other cool stuff I learned this week or am excited about with respect to Docker. But I'm really happy that I got to "test" myself by starting from what I've learned so far and then moving towards a tangible demonstration of my learnings—even crossing over into Python-land.
And did I mention how sweet it is that we just saw how easy and cool it is to run Python-in-Linux-in-Docker?
Very cool indeed. Till next time!
Alex OrtizI tested my knowledge of @Docker with a mini-project to install and run #Python INSIDE an interactive shell terminal INSIDE an Alpine Linux container, and doing a few simple, fun @EducativeInc exercises for added fun. And my week is complete now. ❤️💪🏾🐋 dev.to/alexoeducative…05:22 AM - 16 Nov 2019