Learning Outcomes
- distinguish between a container and a virtual machine
- create a container
- mount a volume
- map a port
- list and remove containers
- create an image
- remove an image
Resources
- Containerization Explained (video)
- What is a Container? (video)
- A Beginner-Friendly Introduction to Containers, VMs, and Docker
- slides
- narated slides (video)
Lab
Video walkthrough of this lab.
Creating a Container
Start the Google Cloud Shell.
In the terminal, run the following command:
docker
is the Docker client program.
run
is the subcommand used create a new container.
--rm
is the option to remove the container when it exits.
-i
or --interactive
keeps STDIN open even if not attached.
-t
or --tty
allocates a pseudo-TTY. -i
and -t
are used together to create a container that we can interact with directly from the terminal.
alpine
is the name of image upon which the new container is based.
If everything works, you should see a #
shell prompt and should be able to use most basic shell commands such as cd
, ls
, cat
, cp
, touch
, echo
, rm
, mv
and rmdir
.
Try the following:
Getting Information About Running Containers
Create a new terminal on the host.
Start another container:
Is first-file.txt
present in the /root
directory in this container?
Create yet another terminal on the host. Run the following command (ON THE HOST – not on the containers) to list the running containers:
Run the following command to get streaming information on the running containers:
You will have to hit Ctrl-C
to stop docker stats
.
Stop one of the contianers by entering Ctrl-D
or exit
on its terminal.
Confirm that the container has stopped by using docker ps
or docker stats
.
Stop the other container.
Where is first-file.txt
now?
Working with Images
You can get a list of locally available images using the following command:
If you are running out of disk space on your host, you can remove images that you are no longer using as follows:
Here, cc0abc535e36
is the image ID for the particular image we want to remove.
Mounting Volumes
Frequently we will have a directory of preexisting files that we would like to access inside the container or we end up creating files inside the container that we want to persist beyond the lifetime of the container. In this case, we can use the -v
option to docker run
to make a directory on the host available inside the container. The value of the -v
option has the following form: /path/on/host:/path/inside/container
. For example, run following commands on the host:
Inside the container do the following:
and then exit the container. What is contained in the current directory on the host now?
Mapping Ports
As with volumes, we often want to make network services running inside the container accessible outside the container. In this case, we use the -p
option to docker run
to map a port on the host to a port inside the container. For example:
Notice the use of the -d
flag instead of -it
. -d
stands for daemon. This container runs in the background and we do not interact with it directly with the terminal.
The -p
flag is used to forward ports on the host to a port inside the container. In this case we are forwarding port 8080 on the host to port 80 insided the container. The Google Cloud Shell allows as to view the app running on port 8080 by clicking on the “Web Preview” icon at the top right of the Cloud Shell window. if you do this, you should see the index.html
page you created above. If you edit the address to https://{your domain}/page2.html
, you should see page2.html
.
Because this container is running in the background, in order to stop it you would need to use the docker stop xxx
command where xxx
is either the name or ID of the container which you could get from the docker ps
command.
Creating Images
Up until this point, we’ve used existing images from the Docker hub registry. There are situations in which we would like to define our own images. For example, what if we wanted to make the simple two page website above a standalone container instead of having to mount the directory with the website files inside the container?
Inside the site1
directory, create a Dockerfile
with the following contents:
The FROM
clause identifies the base image, in this case the base Alpine image with Nginx installed.
The COPY
clause copies everything from the current directory (‘.’) (index.html
and page2.html
) into the /usr/share/nginx/html
directory.
To build the image, run the following command from inside the site1
directory:
The -t
option identifies the tag for the image. The ‘.’ argument identifies the directory containing the Dockerfile
to build from. In this case, the current directory. We now have self-contained container image that has all the files for the website.
Start up the container as follows:
Clicking on the “Web Preview” button should show the website. Visit the index.html
page and page2.html
to confirm that everything is working.
Stop the container using the docker stop xxx
command.
Pushing Images to a Container registry
In the Google Cloud Shell environment, we will lose any images we have built when we exit the shell. If we want a persistent copy of an image, we can push it to a container registry.
The first thing we have to do is tag the image identifying the registry:
You will have to replace PROJECT-ID
with your actual project ID.
Use the docker images
command to verify that the image that the image got tagged correctly.
Before you can push to the Google Container Registry, you have to enable the container registry API. In the Google Cloud console dashboard, go to “TOOLS | Container Registry”. If the API is not already enabled, there should be a button to enable the API that you can click.
You can then push your image to the container registry as follows:
Pulling Images from a Container Registry
You can pull images from a container registry to use local.
To convince yourself that this will work, first delete the local copies of your images as follows:
Then pull a copy from the container registry as follows:
You can use the docker images
command to verify that a local copy is available.
You can test it out as follows:
and then preview the web pages as before.
Stop the container when you are finishd using the docker stop xxx
command.
Deploying a Container to Compute Engine
Running the container in the Cloud Shell environment is fine for development but only you can access it and only while the shell is running. To make your web application available to the public, it has to be deployed somewhere. We can deploy a container to a Compute Engine VM
In the myapp
directory, create a Dockerfile
so we can package up the application as a container image:
Create a .dockerignore
file to exclude files from your container image:
Build and tag the image:
You can run the image in a container and test it using “Web Preview”:
When you are satisfied the app is working, you can stop it using CTRL-C.
Push the image to the container registry:
You can deploy the container image to Compute Engine as follows:
- Go to “COMPUTE | Compute Engine | VM Instances”
- Click on the button to create a new instance.
- For “Name”, enter “myapp-container”.
- Set region and machine configuration as usual (1 vCPU / 1 GB).
- For “Container”, check “Deploy a container image to this VM instance”.
- For “Container image”, enter “gcr.io/PROJECT-ID/myapp”.
- Expand “Advanced container options”.
- Under “Environment variables”, add “PORT” “8080”.
- Expand “Management, security, disk, networking, sole tenanacy”.
- Click on the “Networking” tab.
- For “Network tags”, enter “http-server-8080”.
- Click on the “Create” button.
- Test the application in a new browser tab.
Assignment
Stage, commit, and push your changes to your “myapp” GitLab project. It will be cloned by your instructor.