From its humble beginnings in 2010 as a startup in Y combinator, Docker today is a powerhouse. Docker can be found in codebases big and small and helps developers everyday.
So why has its adoption been so rapid?
Lets start with how engineers typically begin creating code.
To run applications you typically need to download a run time for your specific OS (i.e. downloading NodeJS for OS X) and then doing some setup. Then sometimes this will have some debugging. Setting up some PATH aliases. Making sure the computer can find the location of the run time, etc.
Now, its time to deploy.
All this will need to be redone for a server if you don’t use any other tools. Imagine doing this for every single server your app is deployed to.
Traditionally, software engineers have tried to solve this problem through the use of Virtual Machines (note: I’ll be using VM for short). You create a VM, add in the specified OS and you are good to go.
That was a great solution. But…
VMs have some disadvantages. The space they take will also include the OS which can be upwards of several gigabytes. There is also sometimes issues with running many VMs on a single computer.
And that’s where Docker comes in.
Docker is a tool used to also solve this problem. Its solution approach used is based on a concept called containerization. Containerization is basically just a way of running code on new computers without the need to install a new OS, VM, etc. Just install the Docker software (available for Windows, Macs, and many Linux Os’s) make a Dockerfile for your code. Run one Docker command and you are ready.
Now that we know the why — let’s delve into the how. For this article, I’ll be mainly dockerizing Go (Golang) apps, but Docker works for almost any language.
So here is how to quickly get up and running with Docker
Part One – Setup & The Basics
Docker’s documentation is fantastic for getting setup quickly and picking up the basics. So go through their docs (just Parts 1 & 2) and then come back. If you get stuck, go ahead and read my notes below the link.
https://docs.docker.com/get-started/#docker-concepts (do just Parts 1 & 2)
If you are interested in seeing an example of a demo docker repository feel free to check this out: https://hub.docker.com/r/steven4354/get-started/
Basic Terminology Notes
- a docker image is the wrapper that wraps your app with everything it needs to run (in drive and not running yet)
- a docker container is a running image (in memory actually executing)
- along the same lines, remember when you used to build a go app, you needed to add in a go run time (that installation from the go website remember?)
- now — just add it to docker image and you can run that app on any computer without tricky set up issues — you specify these needed “setup” items on the Dockerfile
- kubernetes/docker swarm — both are software tools that help manage many docker containers running at the same time
Docker Hub Notes
Docker has its own version of “github” but for holding docker images it’s called the docker hub. You can access docker hub via this link: https://hub.docker.com/
Some Docker Hub lingo:
- a docker registry is your docker “place” — it holds all your docker repositories
- a docker repository holds a number of docker images
So why isn’t a docker repository just an image like github? — its because you may have images for dif components of your app i.e. an image for each server, an image for a database, and so on
Part Two – Common Docker Commands
Here’s an example of a typical Dockerfile.
FROM golang:1.11 EXPOSE 8100 WORKDIR /go/src/github.com/steven4354/project COPY . . RUN go get RUN go install ENV PROJ_ENV "/usr/local/go" ENTRYPOINT ["/bin/bash", "-c", "go get; go build; cd cli; go get; go build; ./cli -cmd serve; cd ..; rm *"]
Now lets go over the basic docker commands used:
- FROM – downloads the run time needed (in this case it is go)
- EXPOSE – tells docker which port inside the container it should expose to the outside for you to access
- ENTRYPOINT – runs the commands you would typically run in terminal `/bin/bash` & `-c` tells docker to run using bash and then the third item is the command you would run
- RUN - similar to ENTRYPOINT, you can actually put this inside the ENTRYPOINT as well but I just put it there to separate it `go get` gets dependencies and `go install` installs the go run time
- ENV – sets up any environment variables your project needs
- COPY – copies the items from your app folder into the docker container
- WORKDIR – sets up the folder structure for your docker container
Part Three – Reducing Docker Image Sizes
One of the benefits of using Golang is its ability to easily create binary (real machine code!) that can be run on a linux system without the need for any Go run-time.
This makes the language fantastic for Docker. You can make the file sizes much smaller by doing this because then you wouldn’t need Docker to download the Go run time before running the app. Just set up the binary with Docker and run!
Here are some resources on how to do this. If you get stuck on them, again feel free to read my notes:
- In the codeship.com article you see that there is this code in Part 3:
Typically in Dockerfile you would put:
The FROM specifies the run time to use (in the second it is golang). When you use scratch it means you are not using any run time. Docker will just download and use an empty run time (because the compiled version is machine code and doesn’t need a run time)
- Here is some comments on what the items in Dockerfile.scratch means
FROM scratch ADD main / CMD ["/main"]
- The command codeship uses to compile the go file into the binary (machine code) is really interesting – it actually takes any go files you are using in the current files and turns All of them to the binary & takes any dependencies you need and adds them into the binary. Its a fantastic command – thank you Nick (the author) for finding it out!
Docker has come a long way since its initial beginnings. Today thousands of developers use Docker to help out their deployment process. Let me know your thoughts in the comments, I will continue improving this article as Docker changes!
Please join the conversation…
What do you think? Would love to hear your thoughts, feedback, suggestions for improvement, ideas, compliments, and critiques in the comments. I will be reading it and updating my article to improve this resource to others!