This blog is part of my Docker series. In this blog, I will cover some Hands-on stuff that I tried with Docker.
I installed Docker in my Ubuntu 12.04 that is running on Virtualbox using the procedure here. I have also installed Docker in Ubuntu 14.04 using the procedure here. To install a specific version of Docker and not the latest, use the procedure here.
Following is the docker version that got installed. I have seen recently that 1.4.1 is the default version that gets installed.
$ docker --version Docker version 1.3.1, build 4e9bbfa $ sudo docker version Client version: 1.3.1 Client API version: 1.15 Go version (client): go1.3.3 Git commit (client): 4e9bbfa OS/Arch (client): linux/amd64 Server version: 1.3.1 Server API version: 1.15 Go version (server): go1.3.3 Git commit (server): 4e9bbfa
To test the basic container functionality, try the following:
$ sudo docker run -t -i ubuntu:14.04 /bin/bash root@ce1b5eff4e71:/#
This will pull the Ubuntu 14.04 image from Docker repository and run a bash shell inside the container. Now try the following commands:
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu 14.04 5506de2b643b 8 weeks ago 199.3 MB
The above command shows the docker images present in localhost.
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ce1b5eff4e71 ubuntu:14.04 "/bin/bash" 3 hours ago Up 3 hours agitated_darwin
The above command shows the running containers. Now, lets try to create a docker image/container with running apache web service and export the image to Dockerhub.
Lets take the Ubuntu 14.04 base image and install necessary components for apache.
$ sudo docker run -t -i ubuntu:14.04 /bin/bash root@27eba3e5a18a:/# apt-get update root@27eba3e5a18a:/# apt-get install -y apache2
Since Docker uses a multi-layer filesystem, we can look at the filesystem differences using the docker diff command.
$ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 27eba3e5a18a ubuntu:14.04 "/bin/bash" 3 minutes ago Up 3 minutes naughty_wozniak $ sudo docker diff 27eba3e5a18a A /.wh..wh.plnk/100.81255 A /.wh..wh.plnk/377.81253 A /.wh..wh.plnk/389.81507 C /etc A /etc/apache2 A /etc/apache2/apache2.conf A /etc/apache2/conf-available . .
Lets commit the changes made to the container to create a new Docker image.
$ sudo docker commit -m="installed apache" -a="Sreenivas" 27eba3e5a18a smakam/apache $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE smakam/apache latest eff78d940e51 9 seconds ago 234.8 MB
We can see the new image above. Lets start the container using the new image that we created above.
$ sudo docker run -d -p 81:80 smakam/apache /usr/sbin/apache2ctl -D FOREGROUND 5ff2485b686475cb12b2bef5c57b74ae3f6488f59e63be59b9c98d48be0ec8ec $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5ff2485b6864 smakam/apache:latest "/usr/sbin/apache2ct 6 seconds ago Up 6 seconds 0.0.0.0:81->80/tcp nostalgic_sinoussi $ sudo docker port 5ff2485b6864 80/tcp -> 0.0.0.0:81
In the above command, we have run the container as a daemon using “-d” option. We have run the apache2ctl in foreground so that the container does not exit after starting the apache service. The service is started in port 80 and is exposed to host using port 81. If we go to the browser in localhost and do “localhost:81”, we will see the apache2 default webpage.
Next, lets push the new Docker image to Dockerhub. For that, we need to first create account in Dockerhub. It is free to create and host public images. Dockerhub is a repository to share Docker images.
$ sudo docker login $ sudo docker push smakam/apache $ sudo docker search smakam NAME DESCRIPTION STARS OFFICIAL AUTOMATED smakam/apache 0
Above, we have pushed the apache image to the Dockerhub repository and also we can see the image when we did a search by username in Dockerhub.
Manually creating a docker image is little painful. There is another approach to create a Docker image using Dockerfile. Following is a sample Dockerfile for creating Ubuntu 14.04 image with apache service.
FROM ubuntu:14.04 MAINTAINER Sreenivas Makam <smakam@yahoo.com> RUN apt-get update # Install apache2 RUN apt-get install -y apache2 EXPOSE 80 ENTRYPOINT ["/usr/sbin/apache2ctl"] CMD ["-D", "FOREGROUND"]
First line “FROM” defines the source image from where this new image needs to be built. The second line “MAINTAINER” defines the author. The next set of commands with “RUN” clause defines the commands that installs additional applications on the base image. “EXPOSE” command defines the ports that this container needs to expose. “ENTRYPOINT” defines the command that needs to be executed when the container is run and the “CMD” defines options for the “ENTRYPOINT”. Here, we start the apache service when the container is started. Following command creates the image using the DockerFile. Run the command on the same directory where Dockerfile is present. The created image can be pushed to docker hub using similar commands mentioned above.
$ sudo docker build -t smakam/apache1 . $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE smakam/apache1 latest 65cc372ce42a 7 minutes ago 234.8 MB smakam/apache latest b16acd121751 18 minutes ago 234.8 MB
Following command removes the containers and images.
$ sudo docker stop 4d4f0c1f15fa $ sudo docker rmi smakam/apache1 $ sudo docker rmi smakam/apache
Sometimes, containers fail to get cleaned up because of which image deletion fails. Following command will delete all existing containers.
sudo docker ps -a -q | xargs -n 1 -I {} sudo docker rm {}
When we push the Docker images to Dockerhub, Dockerfile does not get pushed. To push the Dockerfile, we need to link with repository management tool like github or bitbucket. The steps needed are:
- Get account in github or bitbucket.
- From dockerhub, link the accounts from here to either github or bitbucket. I have github account.
- Push the Dockerfile to github.
- From dockerhub, when we create repository, select automated build and select location from github where Dockerfile is present. This will build the image automatically. Also, when there are changes to Dockerfile committed to github, automatic builds are triggered.
- My example Dockerfile at github is here, corresponding docker image is here.
Few other notes:
- Docker images are stored in /var/lib/docker/
- Using “docker inspect <contid>”, we can get detailed information about the containers.
- Using “docker logs <contid>”, we can find out any errors happening during container creation or execution.
- To get a shell for a running container, we can use “docker attach <contid>”, this works only when the container was started with a bash shell originally. If the container was started as a daemon and we need to get the shell, use “docker exec -t -i <contid> /bin/bash”. “docker exec” got introduced in docker 1.4.1.
- Before creating a new Docker image, its better to do a quick search in Dockerhub. Most likely, we will find the image we need or we can use that as a base to create a new image.
For details on how to manage data inside container and how to share data between host machine and container and between containers, please refer here.
References:
- Docker documentation
- Docker hub
- Dockerfile reference
- Dockerfile best practices
- Docker tutorials – 1, 2
Although this content was created in 2014, most the content is fresh and very useful. Continue good work and write good articles.
Thanks Srinivas for the feedback – Sreenivas
you are amazing…continue with this type of work. If more advanced topics out there, post your research. kudosssss
Thanks Luis!