Using Docker Images
I discussed essential commands in my docker essentials article, I will apply the essential commands to work with the nginx docker image.
Just knowing commands help introduce the concept, but using them puts the concept and application together.
I have written everything below in a manner so one can follow along.
Getting Started
Get docker installed on your system to get started, instructions. The version I am using at the time of this writing is:
$ docker -v
Docker version 17.09.0-ce, build afdb6d4
Getting a Docker Image
I will work with the nginx docker image, hosted on docker hub here.
With docker installed, one does not need to open the web page to
download the image separately. Just use docker’s commands to get the
image: docker pull <image_name>
The nginx image size is 108M.
$ docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
e7bb522d92ff: Pull complete
6edc05228666: Pull complete
cd866a17e81f: Pull complete
Digest: sha256:285b49d42c703fdf257d1e2422765c4ba9d3e37768d6ea83d7fe2043dad6e63d
Status: Downloaded newer image for nginx:latest
Docker manages image files, there is no need to touch the file in the computer’s file system.
Listing Docker Images
With the image downloaded, how does one know it exists at all? Using
the docker images
command to list images on the system. After
pulling the nginx image, one would probably see this list of docker
images on their system:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest 3f8a4339aadd 4 weeks ago 108MB
Images on Disk
If you really want to find out where docker pull
put the image
files, they are probably in a location depending on the operating
system:
Just in case you’re really curious. :-)
Running Image in a Container
Now that the image is present on the system, let’s use it!
To run a docker image, use the docker command: docker run <image_id>
:
$ docker run nginx
Hmmm.. the prompt just stopped, what’s going on?
In another terminal window, run the: docker ps
command, to list
active docker processes:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2df0bba15bc6 nginx "nginx -g 'daemon ..." 47 seconds ago Up 46 seconds 80/tcp sharp_boyd
So, the container is running, let’s see if the web server is accessible by going to: http://localhost.
Oh, it looks like the nginx image is running… when I look at the
PORTS column, it only lists: 80/tcp
, so that means the container has
port 80 open, but it is not connected to any other port. Let’s connect
this port to the host system by exposing it. We need to stop the
container and restart it with different options.
Stopping Container
To stop the container running previously, use the: docker stop <container_id>
command. For the container running, the command would be:
$ docker stop 2df0
In this case, the container_id
can be either:
- 2df0 from: CONTAINER ID
- sharp_boyd from: NAMES
Both of these details are in the output of the docker ps
command.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2df0bba15bc6 nginx "nginx -g 'daemon ..." 47 seconds ago Up 46 seconds 80/tcp sharp_boyd
Exposing Container Ports
Let’s restart the nginx image in a container exposing port 80 to the
guest system using the ports
option in the docker run
command:
$ docker run -p 80:80
Let’s run docker ps
to see the container running:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
00b7da958ed3 nginx "nginx -g 'daemon ..." 6 seconds ago Up 5 seconds 0.0.0.0:80->80/tcp sad_saha
Perfect, let’s open a web browser to: http://localhost.
Connecting a Web Browser
In a web browser, with everything working, the default nginx message would appear:
So things are working between the container and our web browser.
nginx Output
On the terminal that started the docker container for nginx, there is some output:
$ docker run -p 80:80 nginx
172.17.0.1 - - [24/Jan/2018:13:45:22 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8" "-"
Now that we can connect the web brower to the container, let’s change the content the nginx server is delivering.
Serving Different Content
To serve different content, we have to mount the container with an option to share the folder into the folder nginx expects the files.
Let’s start by creating a new index.html
file:
$ echo "hello world" > index.html
And start the container with the mount
option:
docker run --mount type={bind | volume |tmpfs},source=<host directory>,target=<guest directory> <image_id>
$ docker run -p 80:80 --mount type=bind,source="$(pwd)",target=/usr/share/nginx/html nginx
172.17.0.1 - - [24/Jan/2018:23:31:01 +0000] "GET / HTTP/1.1" 200 12 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/603.3.8 (KHTML, like Gecko) Version/10.1.2 Safari/603.3.8" "-"
Let’s open the web browser to the same address again: http://localhost.
Now the web page has content:
Logging In
The last command covered in the Docker Essentials article is logging in to the container. I have found this useful when I want to figure out the configuration of the system.
Let’s first run the image, then find the container_id
to run the
docker command: docker exec -it <container_id> <shell>
The commands:
$ docker run nginx
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d7a6faacc1da nginx "nginx -g 'daemon ..." 7 seconds ago Up 6 seconds 80/tcp condescending_goodall
$ docker exec -it d7a6 bash
root@d7a6faacc1da:/#
At this point, the whole system is accessible, so one can access any
file, even the nginx configuration file, nginx.conf
:
root@6f7577b19281:/# cat /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /dev/stdout info;
daemon off;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /dev/stdout;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
I have found this useful when images do not have documentation on the images.
Conclusion
I have learned the nuances of Docker better by applying essential commands to a running image, like nginx. I hope you did as well, getting a better feel for how images, containers, ports, mounts, and logging in work.