Docker in the Cloud

Different ways to launch Docker containers in Cloud providers.

Introduction

The key benefit of Docker is that it allows users to package an application with all of its dependencies into a standardized unit for software development. Unlike virtual machines, containers do not have the high overhead and hence enable more efficient usage of the underlying system and resources. We are to use virtual machines (VMs) to run software applications. VMs run applications inside a guest Operating System, which runs on virtual hardware powered by the server’s host OS. Containers take a different approach by leveraging the low level mechanics of the host operating system, containers provide most of the isolation of virtual machines at a fraction of the computing power. Please refer to https://www.docker.com/get-started

Terminology

Let´s clarify some terminology that is used in the Docker ecosystem:

  • Images - The blueprints of our application which form the basis of containers. In the demo below, we use the docker build command to create an image.
  • Containers - Created from Docker images and run the actual application. You create a container usually using docker run command. In the demo below, we are using Cloud Run for this.
  • Docker Daemon - The background service running on the host that manages building, running and distributing Docker containers. The daemon is the process that runs in the operating system to which clients talk to.
  • Docker Client - The command line tool that allows the user to interact with the daemon.
  • Docker Hub - A registry of Docker images. You can think of the registry as a directory of all available Docker images. https://hub.docker.com
  • Docker registry - A Docker registry allows you to share your custom base images within your organization, keeping a consistent, private, and centralized source of truth for the building blocks of your architecture. For this post, I use the Google Cloud container registry.

Dockerfile

A Dockerfile is a simple text-file that contains a list of commands that the Docker client calls while creating an image. It is a simple way to automate the image creation process. To start, create a new blank file in your text editor and save it in your working directory. Let’s use the Dockerfile from the demo below.

We start with specifying our base image. Use the FROM keyword to do that. In this case, the Node.js version 10 base image.

FROM node:10

The next step usually is to write the commands of copying the files and installing the dependencies.

# Create and change to the app directory.
WORKDIR /usr/src/app

# Copy application dependency manifests to the container image.
# A wildcard is used to ensure both package.json AND package-lock.json are copied.
# Copying this separately prevents re-running npm install on every code change.
COPY package*.json ./

# Install production dependencies.
RUN npm install --only=production

# Copy local code to the container image.
COPY . .

The last step is to write the command for running the application. We use the CMD command to do that: 
# Run the web service on container startup.
CMD [ "npm", "start" ]

The primary purpose of CMD is to tell the container which command it should run when it is started. With that, our Dockerfile is now ready.

Google Cloud container registry

Before you can push or pull images, you must configure Docker to use the gcloud command-line tool to authenticate requests to Container Registry. To do so, run the following command (you are only required to do this once):

gcloud auth configure-docker

Build a docker image

Create a directory to store your docker image files.

mkdir helloworld-nodejs && cd helloworkd-nodejs

To containerize the sample app, create a new file named Dockerfile in the same directory as the source files, and copy the following content:

  • The dockerignore file contains files which are not build in order to avoid interfering the image.
  • The package.json file contains Nodejs specifications.
  • The index.js code creates a basic web server which listens on port defined by PORT environment variable.

Let’s build the image: docker build -t quickstart-image .

Before you push the Docker image to Container Registry, you need to tag it with its registry name. Tagging the Docker image with a registry name configures the docker push command to push the image to a specific location. For this quickstart, the host location is gcr.io. To tag the Docker image, run the following command:

docker tag quickstart-image gcr.io/[PROJECT-ID]/quickstart-image:tag

where:

  • [PROJECT-ID] is your Google Cloud Platform Console project ID, which you need to add to your command.
  • gcr.io is the hostname
  • quickstart-image is the name of the Docker image
  • tag is a tag you’re adding to the Docker image. If you didn’t specify a tag, Docker will apply the default tag latest.

You are now ready to push the image to Container Registry.

Push Docker images

Once docker has been configured to use gcloud as a credential helper, and the local image is tagged with the registry name, you can push it to Container Registry.

To push the Docker image, run the following command: docker push gcr.io/[PROJECT-ID]/quickstart-image:tag

The image is added to your Container Registry.

Pull Docker images

To pull the image from Container Registry onto your local machine, run the following command: docker pull gcr.io/[PROJECT-ID]/quickstart-image:tag

Running Docker containers on Cloud Run

Google Cloud Run provides a platform to quickly run and test your containers without much concern about configuring the infrastructure.

Go to Cloud Run console and click on Create Service:

Choose the container image you have just created above and select a service name and location (at the moment of writing, only us-central1 is supported). Click on Create.

In few seconds, your service is ready and the public access URL is available.

Click on the URL and check that the application is working fine.

Delete Docker images

To avoid incurring charges to your GCP account for the resources used, run the following command to delete the Docker image from Container Registry. gcloud container images delete gcr.io/[PROJECT-ID]/quickstart-image:tag --force-delete-tags

You can delete your images from the docker cli locally. First, list your images: docker image ls --all

Choose an image and remove it performing the command below specifying the image id: docker image rm 575518a94ae7 --force

Docker images vulnerability scanning

Google Cloud provides a mechanism for scanning your images when they are pushed to the registry. Please check the GCP Console for further details.

Docker on AWS

There are several ways to run Docker containers on AWS such as EKS, ECS and AWS Elasticbeanstalk. In this post, I will be focussing on AWS Elasticbeanstalk.

Docker Hub

Dockerhub is a public Docker images repository: https://hub.docker.com You can create your own registry and start sharing Docker images.

Before start using docker, you have to login entering your credentials.

Now, you can build your images as usual.

NOTE: You can also tag your image before pushing: docker tag IMAGE_NAME YOUR_DOCKERHUB_NAME/IMAGE_NAME

Pushing images to Dockerhub follows the same procedure completed for Google Cloud Container Registry.

Your image is pushed to the repository.

Now that your image is online, anyone who has docker installed can play with your app by typing just a single command.

AWS Elasticbeanstalk

AWS Elastic Beanstalk is a PaaS (Platform as a Service) offered by AWS. It is similar to Heroku and Google App Engine. We are going to deploy a new application using our Hello World Docker image.

Click on Create New Application and choose a name. In the New Environment screen, create a new environment and choose the Web Server Environment. Fill in the environment information by choosing a domain. Under base configuration section, choose Docker from the predefined platform.

You have to tell Elasticbeanstalk where your application code is stored. In this case, we are creating a file which points to the Docker Hub repository image:

Upload the file described above. Click on Create environment. It takes some time to set up your application. Once the application is OK, you can click on the URL and browse your app.

The “Hello World” message is displayed.

It is time to terminate the environment to avoid incurring on extra cost. Click on Actions > Terminate Environment

Written on May 13, 2019