Getting into Docker
What is this Docker thing, anyway?
For the best answer, check out What is Docker? on Docker’s web site. Briefly, Docker is a way to deliver applications. A container holds one or more applications. Docker provides a way to deploy, share, and update those containers. Docker containers are similar to virtual machines, in so far as they host an operating system. However, they rely solely on the host’s RAM, CPU, and networking.
Advantages of Docker vs. traditional deployment
You are not shipping code; you are shipping a binary. This binary is an image of the application. It is published to a Docker registry — either the public registry at Docker Hub or an internal registry in your organization. To get the latest version of a container, simply use docker pull
.
Except for the Docker engine, you do not have to install anything on your production machines. You do not have to install web servers, databases, cache engines, scripting runtimes (like NodeJS, Python, or Ruby) or any of your production servers.
Every application runs inside its own Docker container. You can have multiple versions of your application’s toolset without version interference issues.
Authoring a Client-Side Web Application
Here is our application directory structure.
my-app/
src/
scripts/
main.js
index.html
The application itself lives under /my-app/src
. In this app, we only have an index.html
and a single JavaScript file. Deployment scripts are under /my-app/deploy
.
Here is the my-app/src/index.html
file.
<!DOCTYPE html>
<html>
<head>
<title>Getting into Docker</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.min.js"></script>
</head>
<body>
<h1>Hello World!</h1>
<p>The current time is <span id="timestamp"></span></p>
</body>
<script type="text/javascript" src="/scripts/main.js"></script>
</html>
Here is our my-app/src/scripts/main.js
file.
(function() {
function updateTimestamp() {
var timestamp = new Date().toLocaleString();
$("#timestamp").text(timestamp);
}
updateTimestamp();
})();
Deploying our application
First, let’s start with the nginx Docker container. It is available in the public Docker registry. This container is configured to forward requests from port 80 to /usr/share/nginx/html
. (Port 443 is ready to go for SSL, as well, but we will not be using that in this demo.) To do this, we are going to add three new files to the my-app/
directory.
my-app/
build.sh
Dockerfile
run.sh
Let’s take a look at the Dockerfile
.
FROM nginx:1.7.12
COPY ./src /usr/share/nginx/html
There is nothing too difficult here. We are starting with the nginx:1.7.12
image. To that image, we are going to copy the contents from the src
directory to the /usr/share/nginx/html
folder.
You might be tempted to move the Dockerfile
to a build folder. This will not work. The Dockerfile
must be in or above the the src/
directory. This is because Docker sets us a context from the location of the Dockerfile
, and it cannot access anything outside of that context.
Our build script will take care of this build process for us.
#!/usr/bin/env bash
sudo docker build -t my_app .
Build, using the Dockerfile
located in the current directory. Additionally, tag (-t
) this container as my-app
. We can now see this Docker image on our server.
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
my_app latest 04caf9e7a04e 6 minutes ago 93.44 MB
nginx 1.7.12 637d3b2f5fb5 7 days ago 93.44 MB
Finally, let’s create a script to run our application.
#!/usr/bin/env bash
sudo docker run --name my_app_run -d -p 8080:80 my_app
Run the application in the background (-d
), using the container named my_app
. Forward requests on host port 8080 to container port 80. Also, name the running container to let us easily access it by name later (--name my_app_run
).
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9f729419e7ca my_app:latest "nginx -g 'daemon of 4 seconds ago Up 3 seconds 443/tcp, 0.0.0.0:8080->80/tcp my_app_run
Conclusion
A copy of this source code is available on Github.