Docker

What is Docker?

Platform for developers and sysadmins to develop, deploy, and run applications with containers.

Packages up applications along with their necessary operating system dependencies for easier deployment across environments.

The abstraction layer that easily manages containers running on top of any type of server, regardless of whether that server is on Amazon Web Services, Google Compute Engine, Linode, Rackspace or elsewhere.

Containers vs Virtual Machines

Containers

  • Run natively on Linux

  • Share the kernel of the host machine with other containers

  • Lightweight: run a discrete process, taking no more memory than any other executable.

Virtual machine (VM)

  • Runs a full-blown “guest” operating system with virtual access to host resources through a hypervisor.

  • Provide an environment with more resources than most applications need.

Containers / Containerization

The use of Linux containers to deploy applications.

Increasingly popular because containers are:

  • Flexible: even the most complex applications can be containerized.

  • Lightweight: containers leverage and share the host kernel.

  • Interchangeable: deploy updates and upgrades on-the-fly.

  • Portable: build locally, deploy to the cloud, and run anywhere.

  • Scalable: increase and automatically distribute container replicas.

  • Stackable: stack services vertically and on-the-fly.

Containerization makes CI/CD seamless:

  • applications have no system dependencies

  • updates can be pushed to any part of a distributed application

  • resource density can be optimized.

Scaling your app is a matter of spinning up new executables, not running heavy VM hosts

Images and Containers

A container is launched by running an image.

Image

An executable package that includes everything needed to run an application--the code, a runtime, libraries, environment variables, and configuration files.

Container

A runtime instance of an image--what the image becomes in memory when executed (that is, an image with state, or a user process). List of your running containers with: docker ps.

Dockerfile

Defines what goes on in the environment inside your container.

Access to resources like networking interfaces and disk drives is virtualized inside this environment, which is isolated from the rest of your system, so you need to map ports to the outside world, and be specific about what files you want to “copy in” to that environment.

You can expect that the build of your app defined in thisDockerfile behaves exactly the same wherever it runs.

Example:

Dockerfile
# Use an official Python runtime as a parent image
FROM python:2.7-slim

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "app.py"]

Build the app

Run the build command: creates a Docker image, which we’re going to name using the --tag option (-t )

docker build --tag=friendlyhello .

The built image is in your machine’s local Docker image registry:

$ docker image ls

REPOSITORY            TAG                 IMAGE ID
friendlyhello         latest              326387cea398

Run the app

Run the app, mapping your machine’s port 4000 to the container’s published port 80 using -p:

docker run -p 4000:80 friendlyhello

You should see a message that Python is serving your app at http://0.0.0.0:80. But that message is coming from inside the container, which doesn’t know you mapped port 80 of that container to 4000, making the correct URL http://localhost:4000.

Go to that URL in a web browser to see the display content served up on a web page.

Quit

CTRL+C in your terminal to quit.

Run the app in the background (detached mode)

docker run -d -p 4000:80 friendlyhello

You get the long container ID for your app and then are kicked back to your terminal. Your container is running in the background. You can also see the abbreviated container ID with docker container ls (and both work interchangeably when running commands):

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED
1fa4ab2cf395        friendlyhello       "python app.py"     28 seconds ago

Notice that CONTAINER ID matches what’s on http://localhost:4000.

End the background process

docker container stop to end the process, using the CONTAINER ID, like so:

docker container stop 1fa4ab2cf395

Share your image

Upload our built image and run it somewhere else, to demonstrate the portability of what we just created.

You need to know how to push to registries when you want to deploy containers to production.

Registry

A collection of repositories.

Repository

A collection of images. Like a GitHub repository, except the code is already built.

Log in with your Docker ID

If you don’t have a Docker account, sign up for one at hub.docker.com. Make note of your username.

Log in to the Docker public registry

On your local machine:

$ docker login

Tag the image

Notation for associating a local image with a repository on a registry isusername/repository:tag.

Tag is optional, but recommended. It is the mechanism that registries use to give Docker images a version. Give the repository and tag meaningful names for the context, such as get-started:part2. This puts the image in the get-started repository and tag it as part2.

Run docker tag image with your username, repository, and tag names so that the image uploads to your desired destination. The syntax of the command is:

docker tag image username/repository:tag

Example:

docker tag friendlyhello gordon/get-started:part2

Run docker image ls to see your newly tagged image.

$ docker image ls

REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
friendlyhello            latest              d9e555c53008        3 minutes ago       195MB
gordon/get-started         part2               d9e555c53008        3 minutes ago       195MB
python                   2.7-slim            1c7128a655f6        5 days ago          183MB
...

Publish the image

Upload your tagged image to the repository:

docker push username/repository:tag

Once complete, the results of this upload are publicly available. If you log in to Docker Hub, you see the new image there, with its pull command.

Pull and run the image from the remote repository

Now, you can use docker run and run your app on any machine with this command:

docker run -p 4000:80 username/repository:tag

If the image isn’t available locally on the machine, Docker pulls it from the repository.

$ docker run -p 4000:80 gordon/get-started:part2
Unable to find image 'gordon/get-started:part2' locally
part2: Pulling from gordon/get-started
10a267c67f42: Already exists
f68a39a6a5e4: Already exists
9beaffc0cf19: Already exists
3c1fe835fb6b: Already exists
4c9f1fa8fcb8: Already exists
ee7d8f576a14: Already exists
fbccdcced46e: Already exists
Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068
Status: Downloaded newer image for gordon/get-started:part2
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

No matter where docker run executes, it pulls your image, along with Python and all the dependencies from requirements.txt, and runs your code. You don’t need to install anything on the host machine for Docker to run it.

Last updated