Welcome!

Launching Containers

Difficulty:Beginner

Estimated Time:10 minutes

In this first scenario, we'll explore how you can start and connect to your first container using Docker. The environment has been configured with the latest version of the Docker Engine and client which can be accessed via the command line.

The machine name Docker is running on is called docker. If you want to access any of the services, then use docker instead of localhost or 0.0.0.0.

What Is Docker?

Docker describes themselves as "an open platform for developers and sysadmins to build, ship, and run distributed applications".

Docker allows you to run containers. A container is a sandboxed process running an application and its dependencies on the host operating system. The application inside the container considers itself to be the only process running on the machine while the machine can run multiple containers independently. As they're sandboxed, you avoid the possibility of conflicts between dependencies and simplify deployment as all installation and configuration are done ahead of time.

Docker has three key components. First is the Docker Engine, which provides a way to start containers on multiple different operating system platforms. Second is the Docker client, which allows you to communicate with the Engine. Third is the public Docker Registry that hosts Docker Images. These images can be launched or extended to match your requirements and application deployment.

Congratulations!

You've completed the scenario!

Scenario Rating

Here we've demonstrated how to start containers in the foreground and background, bind ports and map directories. These commands are the cornerstone of running Docker in both development and production environments.

We'll be using these commands as we learn more about what Docker has to offer in the coming scenarios.

In the next scenario, we'll look into how you can build your own Docker image.

Steps

Launching Containers

Step 1 - Running A Container

With Docker, all containers are started based on a Docker Image. These images contain everything required to launch the process; the host doesn't require any configuration or dependencies.

To start a container, you can either build your Docker image or, as in this scenario, use an existing image created by Docker and the community. Existing images can be found at registry.hub.docker.com/ or by using the command docker search <image-name>. For example, to find an image for Redis, an object-relational database system, you would use docker search --filter=stars=3 redis.

The --filter=stars=3 option indicates that only images with at least three stars should be displayed. People give projects they recommend a star rating on the Docker Registry. It's recommended you either go with the "Official" docker image which has been verified by Docker, or the one with the most stars.

Task

To complete this step, launch a container in the background running an instance of Redis based on the official image.

After identifying the image name using search, you can launch it using docker run <options> <image-name>. By default, Docker will run a command in the foreground. To run in the background, you need to specify the option -d.

At this stage, you will not have a local copy of the image so that it will be downloaded from the Docker registry. If you launch a second container, the local image will be used.

Protip

All containers are given a name and id for use in other Docker commands. You can set the friendly name by providing the option --name <new-name> when launching a container such as --name redis

docker run -d redis:latest

Step 2 - Listing Running Containers

While the launched container is running in the background, the docker ps command lists all running containers, the image used to start the container and uptime.

This command also displays the friendly name and ID that can be used to find out information about individual containers.

The command docker inspect <friendly-name|container-id> provides more details about a running container, such as IP address, volumes mounted and their locations and its current execution state.

The command docker logs <friendly-name|container-id> will display messages the container has written to standard error or standard out.

Step 3 - Binding Ports

As described in the introduction, each container is sandboxed from other containers. If a service needs to be accessible externally, then you need to expose a port to be mapped to the host. Once mapped, you will then be able to access the service as if the process was running on the host OS itself instead of in a container.

When starting the container, you define which ports you want to bind using the -p <host-port>:<container-port> option. The Redis container exposes the service on port 6379. If you wanted to map this port directly on the host, we'd use the option -p 6379:6379.

Task

Start a new Redis container in the background with the name redis and bind the host port 6379 to the container port 6379.

Protip

By default, the port on the host is mapped to 0.0.0.0, which means all IP addresses. You can specify a particular IP address when you define the port mapping, for example, -p 127.0.0.1:6379:6379

docker run -d --name redisHostPort -p 6379:6379 redis:latest

Step 4 - Binding Ports

We've seen how to bind a port to a known port on the host. This makes it easier to access the service from other applications but has the disadvantage of only allowing a single instance of the service to be running. One of the advantages of running containers is that you can separate the application configuration (for example, which port to run on) from the deployment configuration (for example, which port to bind on the host).

Like binding a known port on the host, if you simply use -p 6379 to expose the port, then Docker will assign a random available port. This allows you to run multiple instances of the same service on the same host without changing any of the application configuration.

Task

Start an instance of Redis as in the previous task but allow Docker to assign an available port.

You can use the command docker port redis 6379 to find out the mapped port.

Listing the containers using docker ps also displays the port mapping information.

docker run -d --name redisDynamic -p 6379 redis:latest

docker port redisDynamic 6379

Step 5 - Binding Directories

So far, we've started containers and made them accessible by mounting ports. The next step is handling data.

Containers are designed to be stateless. Any data we want to be persisted after a container is stopped should be saved to the host machine. This is done by mounting/binding host directories into the container.

Binding directories (also known as volumes) in Docker is similar to binding ports using the option -v <host-dir>:<container-dir>. When a directory is mounted, the files which exist in that directory on the host can be accessed by the container and any data changed/written to the directory inside the container will be stored on the host. This allows you to upgrade or change containers without losing your data.

Task

The official Redis image stores logs and data into a /data directory. Start the container and mount the container's /data directory to the host /home/scrapbook/tutorial/data.

Protip

Docker allows you to use $PWD as a placeholder for the current directory. For example, the directory above could be replaced with "$PWD/data".

docker run -d --name redisMapped -v "$PWD/data":/data redis

Step 6 - Running A Container In The Foreground

Certain containers, such as databases, are best run in the background. However, Docker is not limited to just running background services. Containers can run any application in the same way they would run on a regular host. Previously, we used the -d to execute the container in a detached, background, state. Without specifying this, the container would run in the foreground. If we wanted to interact with the container (for example, to access a command shell) instead of just seeing the output, we'd include the options -ti.

As well as defining whether the container runs in the background or foreground, certain images allow you to override the command used to launch the image. Being able to replace the default command makes it possible to have a single image that can be re-purposed in multiple ways. For example, the Ubuntu image can either run OS commands or run an interactive bash prompt using /bin/bash

Example

The command docker run ubuntu ps launches an Ubuntu container and executes the command ps to view all the processes running in a container.

As we described at the start, from the container's point of view, the only process running is the one we launched.

Debugging Scenarios

Help

Katacoda offerings an Interactive Learning Environment for Developers. This course uses a command line and a pre-configured sandboxed environment for you to use. Below are useful commands when working with the environment.

cd <directory>

Change directory

ls

List directory

echo 'contents' > <file>

Write contents to a file

cat <file>

Output contents of file

Vim

In the case of certain exercises you will be required to edit files or text. The best approach is with Vim. Vim has two different modes, one for entering commands (Command Mode) and the other for entering text (Insert Mode). You need to switch between these two modes based on what you want to do. The basic commands are: