Article Video
Dockerizing Your First Application
Project created for Joyent
At Joyent I led a series of webinars guiding those new to Docker, containers and Triton, how to dockerize a simple application, deploy it to the cloud, and share it. In April 2017, the webinar used the game 2048 as the example application. Additionally, I published a blog post with the recorded webinar and written instructions.
Read an excerpt from the original blog post
For the full blog post, you can read it on Joyent’s website.
Dockerize our application
We’ll be working to dockerize the 2048, which was created as a web application. First thing’s first: download a copy of this repository or fork it via git. To dockerize this application, all we need to do is create a Dockerfile within the directory containing the application.
In your terminal cd
into the directory where you’ve installed the application. To create your Dockerfile, run the following command:
touch Dockerfile
The command ‘touch’ creates an empty Dockerfile which you can now open in your text editor of choice (mine is Sublime Text) or your favorite Unix editor (such as vi
or pico
). In our Dockerfile we are going to lay out a specific set of instructions for how to build our container which will have all of the resources needed to run our application.
It’s important to choose a base image to pull in order for Docker to know where to start. This base image can be FROM scratch
, which is Docker’s minimal image that indicates the build process will begin at the next command in the Dockerfile. We’ll be using Nginx as our base image, so that our application has a web server to run on. Lucky for us, there is an official Nginx repository that already exists. Running Nginx is going to be our first task within the Dockerfile:
#FROM is the base image for which we will run our application
FROM nginx:latest
Note: Docker uses the # as an indicator a line is a comment and not actionable code. I’ll be using it quite a bit, as I believe it’s important to comment your work to understand it in the future.
By adding the tag :latest
to the image, we’ll ensure we have the most up-to-date version of Nginx running, and there will be no need in the future to update a version number. That said, if future versions of Nginx could break your application, you will want to indicate a specific version number. That will ensure your application builds with the same base image version each time, but it means you’ll have to update the tag to get a new version of Nginx.
Our next step will be to copy the contents of our application into the Nginx environment. There are numerous files and folders within the 2048, and it’s important that they are copied into the appropriate folders.
COPY syntax is as follows:
COPY <src directory or file> <destination directory or file>
For copying this application, add the following to your Dockerfile:
# Copy files and directories from the application
COPY index.html /usr/share/nginx/html
COPY favicon.ico /usr/share/nginx/html
COPY Rakefile /usr/share/nginx/html
COPY style/ /usr/share/nginx/html/style/
COPY meta/ /usr/share/nginx/html/meta/
COPY js/ /usr/share/nginx/html/js/
Finally, we’ll be telling Docker what port to use for our application. Insert this final line into your Dockerfile:
# Tell Docker we are going to use this port
EXPOSE 80
Congratulations. You have a complete Dockerfile which looks like this:
#FROM is the base image for which we will run our application
FROM nginx:latest
# Copy files and directories from the application
COPY index.html /usr/share/nginx/html
COPY favicon.ico /usr/share/nginx/html
COPY Rakefile /usr/share/nginx/html
COPY style/ /usr/share/nginx/html/style/
COPY meta/ /usr/share/nginx/html/meta/
COPY js/ /usr/share/nginx/html/js/
# Tell Docker we are going to use this port
EXPOSE 80
Adding a Dockerfile is not enough to build and run the application, it’s just the instructions for how to build it. You’ll need to create the Docker image with docker build
first and then use docker run
to start the container.
VMs and running your application
For Mac and PC users, when you installed Docker, you’ll automatically have set up a virtual machine.
Set Up a Virtual Machine
Let’s list our machines again to make sure that they exist by running docker-machine ls
:
NAME ACTIVE DRIVER STATE URL DOCKER
default * virtualbox Running tcp://192.168.99.100:2376 v1.12.0
If the state
of your machine is stopped
, you must get it up and running before you continue:
docker-machine start default
You’ll need to connect your shell to the VM environment so that you’ll be able to run other Docker commands and set up your application. This is done by running the following command in your terminal:
eval $(docker-machine env default)
Extra: Technically, the above command opens a sub-shell to run docker-machine env default
, then the output of that command is run in your main shell using eval
. You can see all the environment variables that were set by running the command this way:
docker-machine env default
Your Docker host VM is now up and running and you’re ready to build your application.
Building and running your application
Make sure you’re in the directory of your application (and if not,cd
back into it) and run the following command:
docker build -t twentyfortyeight .
Eventually, you’ll want to upload that image to Docker Hub, so you’ll need to tag the image with your Docker Hub username:
docker tag twentyfortyeight <username>/twentyfortyeight:<tag>
Replace <username>
with your Docker Hub username.
This command will build a container called twentyfortyeight
. You can see a list of your running containers again with docker ps
. It should look like this:
CONTAINER ID IMAGE COMMAND STATUS NAMES
70d80bfbd593 twentyfortyeight "httpd-foreground" 6 hours ago Upadoring_dijkstra
You’ve successfully created a container, so it’s time to run your application. Enter the following command into your terminal:
docker run -d -p 80:80 twentyfortyeight
Let’s break down this command. docker run
is going to tell your application to start running. -d
detaches from the container, meaning your application runs in the background rather than the foreground. p 80:80
tells the app to run on port 80. twentyfortyeight
is the name of the container that you’re choosing to run (the same one you just built).
It’s possible that you’ll receive an error related to your choice of port. If that happens, another application or container is using that port. You have two choices: stop the other application running on port 80 to replace it with 2048 or use a different port. To stop the other application, run docker kill $(docker ps -a -q)
to kill all running containers. Go back and docker run
2048 again and you should be all set.
If you don’t want to do kill the other containers, run the following command:
docker run -d -p 80twentyfortyeight
Instead of assigning twentyfortyeight
to port 80 specifically, a randomized port will be generated.
Your application is now running! But how do you see it in action? You’ll need the IP address of your VM. You can get this information by running the following command:
docker-machine ip default
This will give you the IP address of the VM default
on your localhost. If you’re on Linux and therefore aren’t using Docker machine, you can get the IP address by running ip addr
. If you’re not on port 80, you’ll need to refer to the specific port at the end of your IP address, starting with a colon.
Congratulations. You have successfully dockerized your first app and run it on your local machine.
Pushing your application to Docker Hub
Now that you’ve dockerized your app, let’s push this image to Docker Hub so that other users can download it play the game on their local machines. The official documentation is on the Docker website, but we’ll walk through the basics of getting this image up. If you haven’t already, you’ll need to create a Docker Hub account and login in your terminal:
docker login
Enter the username and password you’ve created. If everything worked correctly you should receive a “login succeeded” message.
Create a repository of the same name as your image on Docker Hub. You’ll notice something about the set up: your username is a part of the image name, the second part of the pull request Docker argument.
You’re ready to push this app to Docker Hub. Once again, replace the string <username>
with your actual username and run the following command:
docker push <username>/twentyfortyeight:<tag>
That’s it. Your image is now ready to be pulled and run by anyone. You can get my image on Docker Hub docker pull heyawhite/twentyfortyeight
.