What is it?
Docker is a tool that wrap your code in a defined environment. It ensure that your code will run the same way regardless of the machine. No more “but it worked on my machine…” 😉.
With Docker, you’ll make your app easily deployable and portable. In a team, it allows your teammates and you to work on the exact and same environment. Super useful.
For instance, you wanna write a Ruby app. With Docker, you can define an environment from the Ruby base image with ruby already installed. Then you write your code, copy it onto this environment and execute it. Even if Ruby isn’t installed on your system, it’s embedded on your defined environment and it will run on your machine #magic.
Now think of a large and complex system that you want to deploy on a new server. Deploying using Docker makes it very easy!
Now lets see how we can use Docker. Docker use containers to run. A container is an instance of Docker that execute processes on a defined environment. To define an environment, you need to start from a base image. Docker provide you with some base image such as an nginx server, an Ubuntu system, a Ruby environment and so on.
Running your first container
docker run -it ubuntu bash
There you are, you are now on a Ubuntu system like, on your machine. Some of the basic commands are missing but you can install them using
docker run is used to create and start a new container. The
-it option allows you to keep focus on the container and use it as a shell. Then,
ubuntu is the name of the base image that we are going to use.
bash is the command we run on this container. Here we are running a shell instance.
You can redirect the traffic from a given host port to your container port using the
-p option. For instance, lets say that my app is running on port 9000 of my container. I want to bind the port 9000 of my host machine to the port 80 of my container. I just use
# On your host machine docker run -p 9000:80 nginx
And then open your favorite web browser and go to http://localhost:9000/. You should see the nginx default page.
Demonize the container
We ran a nginx container in foreground in the previous example. Most of the time, we like that our web server run as a daemon. To do so, you can start containers as daemon using the
-d option. Now, you can run
# On your host machine docker run -d -p 9000:80 nginx
Docker answer with a long id. It’s the unique id of your container. Now lets go into the system. We are going to execute a bash process onto our nginx container. Then we will create a simple web page directly onto the container. But how do we access our container while it’s already running?
# On your host machine docker exec -it <CONTAINER_ID> bash
We now have access to a shell running on our nginx container. Lets go in the
/usr/share/nginx/html repertory. Install your favorite shell text editor and create a small html page in test.html.
Then go to http://localhost:9000/test.html you should see your awesome web page.
Sharing files between Host and Container
Most of the time, to deploy your website, you won’t start an nginx container and then write your pages on it as we just did! You can either copy files onto the container (explained below) or you can share files between the host machine and your container.
To do so, just use the
-v option as follow :
For instance, go to your home dir on your host machine and run the following :
# On your host machine docker run -it -v $PWD:/host ubuntu bash
And then run
ls. You should see a
host repertory. Now run
# On your container ls /host
you should see every files that are in your home directory of your host machine. You are now sharing files between your host machine and your ubuntu container. Be careful, you can add modify or remove file on your container, it will also change your host directory, these are the same files, this is not a copy!!!
Lets say you want to run a container for your website, just use the following :
# On your host machine cd /to/your/project/folder docker run -d -p 9000:80 -v $PWD:/usr/share/nginx/html/ nginx
And you can access your website at http://localhost:9000/.
Manage your containers
You can see all your running containers on your host machine using :
Kill or stop your containers using:
docker stop <CONTAINER_ID> # Or docker kill <CONTAINER_ID>
When you kill or stop a container, it will go in the “stop” state. You can see all containers (running and stopped) using the
-a option. You can bring back a stopped container using:
docker start <CONTAINER_ID>
Or you can delete a container using:
docker rm <CONTAINER_ID>
You can write a script in order to define your container environment. This script is called
Dockerfile. For instance, you saw that on the Ubuntu official image, some basic commands are missing and you have to install it using
Lets create a file, call it “Dockerfile”. And write the following into it:
FROM ubuntu MAINTAINER your_name VERSION 1.0 # Execute a command on the new container RUN apt-get update # When using apt-get install don't forget the -y option otherwise it times out RUN apt-get install netcat -y RUN apt-get install nano -y RUN apt-get install vim -y RUN apt-get install iputils-ping -y #The command we are going to execute when running our container CMD bash
And then, we are going to build an image named “my_ubuntu” from your Dockerfile:
docker build -t my_ubuntu .
Now, check that you have an image called “my_ubuntu”:
docker images | grep ubuntu
You should see at least two lines. One image called “ubuntu” which is the official image that we use previously and your new image “my_ubuntu”. Now create and run a container using my_ubuntu:
docker run -it my_ubuntu
You don’t need to add a “bash” since we mentioned it in our Dockerfile. You are now running a shell instance on a Ubuntu with
vim installed 😊.
Create an image for your website
Dockerfile in your website path.
FROM nginx MAINTAINER your_name VERSION 1.0 # Copy your website resources from your host COPY ./ /usr/share/nginx/html/ # Open the container port on which your app is running EXPOSE 80
docker build -t my_website .
docker run -d -p 8080:80 my_website
And go to http://localhost:8080/ to see your website.
Where to go from here
You know how to manipulate containers and how to create custom images using Dockerfile. A lot of images have already been created. You can find them there. You can deploy simple application with that, but how do we deploy an app that use a database and a REST API and make those two instance communicate? We have to use
docker-compose to do so. I will write an article on this topic A.S.A.P.