The distant sound of seagulls, maritime bells, and ship horns echoed through the wharves of ports; and suddenly out of the fog, a monolithic shadow makes its way from the horizon into the pier. Ahhh, yes, the illusive Moby Dock, Pulling, Communicating, Building and Publishing... A creature that would entertain even the likes of Captain Ahab; who would be all so very intrigued, and envious to finally have spotted, found and understood it. Even Captain Ahab would not stand a chance to uncover all of what exists in the digital ocean. So it is up to us to uncover the stuff of legends within our realm of possibilities.
What is Docker?
To go back, Docker is a computer program that can perform virtualization at the operating-system level. It was first released in 2013 by dotCloud, which started as an Open Source project, but who are now known to be Docker, Inc. At its essence, Docker can be more easily known as a light-weight alternative to virtual machines. Which are known as Containers, and have very significant differences between virtual machines. On one hand, in the past, virtual machines may run separate instances of an operating system, with each having its own dedicated resource, etc. Where as Docker can have multiple containers run on the same operating system, and share resources to keep each container running, completely separate, and even containers not knowing those other containers are running. However, containers are not Virtual Machines, and comparing them to Virtual Machines don\'t do them justice.
Some other ideas about Docker and things to take away from this are:
- [X] Docker containers, or containers, allow you to package your apps and keep them consistent anywhere, and everywhere.
- [X] Reduction in infrastructure and hardware requirements, without the need for too much cost, and investment.
- [X] Docker boosts IT, developer productivity and innovation within organizations.
What are Containers?
Without going too far into depth on what containers actually are. In Layman\'s Terms Containers really just are a process running on the host Operating System. I want to keep this conversation to a minimum, as many times it is found that Docker containers are confused with Virtual Machines. Where as a virtual machine is a full-on instance of an operating system, Docker simply borrows parts of an operating system, for an easier understanding, have a look at the illustration below.
As the architecture above describes. Our app runs within a container, that sits above the Docker Engine. With enough creativity, you can run a number of applications at once, and have them all communicate in harmony with each other. LEMP stack, or LEMPP, or hell, any stack that you put enough time and effort in.
Using a Dockerfile may actually make things a little easier to understand. To put it into more simple terms, this is the equivalent of running various shell commands for a system at setup and create, but a few more levels up, instead of simply just installing applications, libraries, binaries, and running our own apps. We add images of operating systems, whether that is Ubuntu, or Kali, or even just running a simple python application you have built, is up to to you and the task at hand. A Dockerfile gives you the flexibility to create and reuse without repetition, and from any software developer or coders perspective, Don\'t Repeat Yourself is always the best way to go.
FROM - An image that exists within the docker registry, such as ubuntu or python. You should be very careful what images you use, it is known that many images are uploaded with malicious intent, so be very aware of what images you are using. COPY - Equivalent of the cp command, copies files from a local path into your docker image ADD - Similar to ADD but really not as stable, it\'s better to just use COPY. ENV - Allows you to set environment variables that your container will need, things like passwords, usernames... or even PATHS for certain applications and libraries. CUDA anyone? RUN - Run various commands that are part of a base image, say FROM ubuntu. apt-get update && apt-get upgrade anyone? VOLUME - Allows you specify a virtual mounting point... say you would like to just mount a file or directory locally, you can do this. USER - Many times, docker runs on root by default... We\'ll figure out how to get around this eventually. WORKDIR - Allows you to set a default working directory when you enter your docker container, or even that the docker container will use EXPOSE - Lets you expose various ports, useful for things like Nginx, SQL, or just about anything you need a port for ONBUILD - I\'ve never had a use for this.
All of the above commands are the most common and used within a Dockerfile. To build a good image, is to understand what the purpose of your image is, and I want to give you the tools that will help you understand and create efficient Docker images. Our program will be a simple python script that will run after we build the image and run it with the docker command. Before doing anything, let\'s open up a terminal and navigate to your user home.
cd ~/ mkdir -p myProject/ && cd myProject/ touch requirements.txt && echo requests==2.9.1 >> requirements.txt touch helloWorld.py vim helloWorld.py
Once you have completed that, let\'s get started on our python script! If you want to exit vim, press the esc key, then type
:q! (the ! is for any unsaved edits) and
:w is to write any changes to the file...
:w! is to forcibly write those changes... but we will learn more about that later on. Feel free to copy this code into your terminal, but be aware, python is very sensitive about spacing issues, so make sure that you only use four spaces, no tabs, when you\'re lining up your code.
Your Python Script
#!/usr/bin/python3 import requests import os my_environment = os.environ.get('my_api_token') def main(): print(Hello World from my Docker container image!\n) print(my_environment) print('My environment variable printed as a string: %s' % (my_environment)) if __name__ == '__main__': main()
Once you have finished writing your code, save it inside of vim by typing
:wq! which will save your code to
helloWorld.py after that, let\'s get started with your Docker image by running the command
touch Dockerfile inside of your
~/myProject/ directory, which will create your Dockerfile on the fly. Once you\'ve completed that step, feel free to run
vim Dockerfile and we will run the same
:wq! when finishing up. The cool thing about this is that a Dockerfile does not have the same spacing rules as python, so you can copy and paste at your leisure.
Your First Image
# Base image FROM ubuntu:16.04 # Set our working directory WORKDIR /myProject # Download any necessary dependencies, I included pip for both python 2.7 and python 3.5 just so you can get a feel for PyPi or pip RUN apt-get update \ && apt-get install -y \ build-essential python-dev python3-dev python-pip python3-pip # Add all of our files from our pre-built program, we could also do the same thing with the COPY command ADD * /myProject/ # Copy an additional file COPY requirements.txt /myProject/requirements.txt # run another command RUN pip3 install -r requirements.txt # Optional # Set any environment variables, say like an API token; this is purely used as an example, so that you can get some ideas on how # you can use your newly formed docker image, and the power that lie underneath ENV my_api_token=just-using-this-as-an-example # tell your image to do something right away, in this case, launch our helloWorld script CMD [ python3, /myProject/helloWorld.py ]
Once you\'ve saved your changes in your Dockerfile it\'s time to build our image. Execute the following command
docker build -t myproject:v1 .while inside of
~/myProject/ directory and observe the output results. If everything has successful run, you will see that your latest image has been built and can be seen.
Towards thee I roll, thou all-destroying but unconquering whale; to the last I grapple with thee; from hell\'s heart I stab at thee; for hate\'s sake I spit my last breath at thee.
~ on 🐳 v18.09.2 took 30s ➜ docker images Installing collected packages: requests Successfully installed requests-2.9.1 You are using pip version 8.1.1, however version 19.1.1 is available. You should consider upgrading via the 'pip install --upgrade pip' command. Removing intermediate container 23a4d9d22664 ---> d33fb2370ee Step 7/8 : ENV SLACK_BOT_TOKEN="xoxb-426270598675-432707799525-iHfEkiCAPcbwwNxIu G7d4X17" ---> Running in 6f20e843dc1c Removing intermediate container 6f20e843dc1c ---> 8ef6dfa348fa Step 8/8 : CMD [ "python3", "/myProject/helloWorld.py" ] ---> Runing in 4f8b18470a02 Removing intermediate container 4f8b18470a02 ---> 619868168fba Successfully built 619868168fba Successfully tagged myproject:v1
You should see some output like in the above illustration. Ok! Now what? You image was built, let's check it out and see what is available. Run the command
docker image ls you should see some information with the name of your image that was built, as well as an Image ID that was generated, like shown in the illustration below
~ on 🐳 v18.09.2 took 2s ➜ docker images REPOSITORY TAG IMAGE ID CREATED SIZE myproject v1 e08564cf538f 5 weeks ago 523MB <none> <none> 619868168fba 5 weeks ago 523MB myproject latest 86b111eff898 5 weeks ago 523MB ubuntu 16.04 13c9f1285025 5 weeks ago 119MB hello-world latest fce289e99eb9 7 months ago 1.84kB
Long Stretch Home
I\'m sure at this point you\'re dying to test it out! Almost like how Captain Ahab died trying to get revenge on Moby Dock! So without further ado, run either of the two commands
docker run <image id> or
docker container run <image id> if everything was built and coded successfully, you should see the following output as shown in the illustration below
~ on 🐳 v18.09.2 took 2s Hello World from my Docker container image! just-using-this-as-an-example My environment variable printed as a string: just-using-this-as-an-example
Congratulations! You\'ve successfully built a Docker image with a **Dockerfile**, you\'ve also executed your container image and saw how your application did somethings and quit just as expected. Captain Ahab would be proud of you. He is long gone, but his legacy can be continued as the search for the illusive Moby Dock has only begun! I hope that this article has provided some insight into how powerful Docker can be when used in the proper context. If you enjoyed it leave a reaction and a comment, and keep your eye open for the next post!