How to search, pull, list and run a docker container
Containers enable you to package an application with all the components it needs, such as libraries and other dependencies and ship it as one package. Docker containers have revolutionized the software supply chain in both small and large enterprises. In this post, we will exercise all of the basic Docker functionality to search, retrieve, and use Docker images.
1. Search Docker images from the Docker Hub
Docker images can be searched in much the same way you search any collection. Run the following command to learn about one of the images that we will be using in this lab:
$ docker search fedora/apache
You should see something like this:
$ docker search fedora/apache
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
fedora/apache 26 [OK]
fedora/systemd-apache 5 [OK]
...
The first part of the name is the namespace (in this case Fedora project) and the second part is the package, which usually is descriptive of the OS or the image’s purpose. As for the other fields:
- Stars: Docker images can be rated by users, the more stars a container has, the more popular it is.
- **Official: **The folks at Docker maintain a number of “official” images, as denoted by this field.
- Automated: Docker supports automated builds; any images that are produced by the automated build process are flagged with this.
2. Pull a Docker Image from the Docker Hub
Docker images are actually comprised of layered file systems. When you perform a docker pull, you initiate the parallel download of all of the file system components that make up your requested Docker image. Try it now by running the following:
$ docker pull fedora/apache:latest
When it is done, you should see output similar to this:
$ docker pull fedora/apache:latest
Pulling repository fedora/apache
2e11d8fd18b3: Download complete
511136ea3c5a: Download complete
ff75b0852d47: Download complete
0dae8c30a0b2: Download complete
84f33df93401: Download complete
24b116bb2956: Download complete
a7f290a6f21d: Download complete
eb86e2be11d4: Download complete
c06d2cba0d4a: Download complete
f0b140ef8cdd: Download complete
b05601b61180: Download complete
In the case of this particular Docker image, each of these filesystems represents a different tagged version of the image. Most Docker images are composed of multiple filesystem layers.
3. List Downloaded Images
This command shows you all of your locally available Docker images:
$ docker images
You should see something like this:
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
fedora/apache latest 2e11d8fd18b3 9 days ago 554.1 MB
....
Since we pre-installed other Docker images on the EC2 machine you will see all the other images on your machine as well.
4. Running a Container
To start this exercise, first familiarize yourself with docker ps:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Nothing is running right now, so the list is empty. Now kick off a simple container with docker run:
$ docker run -i -t fedora/apache /bin/echo 'hello world'
hello world
Here’s a breakdown of what just happened:
- -i: Make an interactive connection to the container by grabbing STDIN
- -t: Assign a pseudo-terminal in the container
- fedora/apache: the image to run as a container
- /bin/echo ‘hello world’: A command passed to the container’s pseudo terminal via STDIN
Notice that we still haven’t explicitly identified which tagged version of the image we want to run. In this situation, Docker defaults to using the version tagged with latest. Now run docker ps again:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Still nothing! This is because the Docker container that we ran isn’t running anymore. It stopped as soon as its primary process exited. Try running docker ps with the -l argument to see the result of the last container invocation:
$ docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5e05cd28f29c fedora/apache:latest /bin/echo 'hello wor About a minute ago Exited (0) About a minute ago silly_kowalevski
Notice that docker assigned a random id and name to our container when it spun it up. We will revist the name piece later in the exercises.
5. Running a container as a “daemon”
While having an image spin up and run command is “neat”, now it’s time to do some more useful tasks. Let’s get our image to start up and serve HTML content through Apache Web Server. Enter the following command:
$ docker run -d -P fedora/apache 798a3749cd7e0721a59af2879ecfebfd1096cb1c925ab73549102c06b788a4e5
Here is a breakdown of the flags:
- -d means run the container in the background ( which means don’t run and exit)
- -P means map any required network ports inside our container to ports on the host (basically automatically do port-mapping)
If you remember back to when you did the docker history command, one of the changes was to have the image spin up Apache when it is spun up as a container. The end result is that by running the command above we now have Apache running and serving up index.html. Now let’s find out what port we should use to get to Apache. Time to use the trusty docker ps command:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
798a3749cd7e fedora/apache:latest /run-apache.sh 5 seconds ago Up 5 seconds 0.0.0.0:49153->80/tcp elegant_pare
docker ps shows something even without the -l because we used the -d flag when calling docker run. What is also different is you can see that there is an entry for ports:
0.0.0.0:49153->80/tcp
This line indicates that port 49153 on the host machine points to port 80 on the container. It also is only exposing TCP traffic. Based on this we can execute the following command on our host machine:
$ curl -v 0.0.0.0:49153
* About to connect() to 0.0.0.0 port 49153 (#0)
* Trying 0.0.0.0... connected
* Connected to 0.0.0.0 (0.0.0.0) port 49153 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu)
libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Host: 0.0.0.0:49153
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Thu, 09 Oct 2014 18:35:13 GMT
< Server: Apache/2.4.10 (Fedora)
< Last-Modified: Mon, 29 Sep 2014 12:28:50 GMT
< ETag: "7-5043368b3a480"
< Accept-Ranges: bytes
< Content-Length: 7
< Content-Type: text/html; charset=UTF-8
<
Apache
* Connection #0 to host 0.0.0.0 left intact
* Closing connection #0
Voila, you have successfully spun up a Docker image and have it serving content. If you want to stop this Docker image from running just enter:
$ docker kill elegant_pare
You could have also used the container ID in place of the name. Time for us to start modifying Docker images.