Docker is an open platform for developing, shipping, and running applications in containers. Docker helps you build, test, and deploy code faster, and it shortens the cycle between developing and running code. Docker does this by combining kernel containerization features with workflows and tooling that helps you manage and deploy your applications.
Docker lets you express the application build process by using a script, called a Dockerfile. Dockerfiles provide a low-level approach that offers flexibility at the cost of complexity. The Dockerfile is a manifest that details how to turn your source code into a container image.
Docker containers can be directly used in Cloud Run and Kubernetes, which allows them to be run on these platforms with ease. After learning the essentials of Docker, you will have the skill set to start developing containerized applications.
Objectives
In this lab, you learn how to:
Build, run, and debug Docker containers.
Push Docker images to Artifact Registry, Google Cloud's container image repository.
Pull Docker images from Artifact Registry.
Setup
For each lab, you get a new Google Cloud project and set of resources for a fixed time at no cost.
Sign in to Qwiklabs using an incognito window.
Note the lab's access time (for example, 1:15:00), and make sure you can finish within that time.
There is no pause feature. You can restart if needed, but you have to start at the beginning.
When ready, click Start lab.
Note your lab credentials (Username and Password). You will use them to sign in to the Google Cloud Console.
Click Open Google Console.
Click Use another account and copy/paste credentials for this lab into the prompts.
If you use other credentials, you'll receive errors or incur charges.
Accept the terms and skip the recovery resource page.
Activate Google Cloud Shell
Google Cloud Shell is a virtual machine that is loaded with development tools. It offers a persistent 5GB home directory and runs on the Google Cloud.
Google Cloud Shell provides command-line access to your Google Cloud resources.
In Cloud console, on the top right toolbar, click the Open Cloud Shell button.
Click Continue.
It takes a few moments to provision and connect to the environment. When you are connected, you are already authenticated, and the project is set to your PROJECT_ID. For example:
gcloud is the command-line tool for Google Cloud. It comes pre-installed on Cloud Shell and supports tab-completion.
You can list the active account name with this command:
Grant permissions to the student user on the socket used by Docker:
sudo chmod 666 /var/run/docker.sock
To set your Project ID and region environment variables, run the following commands:
PROJECT_ID={{{project_0.project_id| Project}}}
REGION={{{project_0.default_region| Region}}}
Ensure that you run all the lab commands in the tasks below in the SSH session in Cloud Shell.
Task 2. Build a container image
In this task, you create a Docker container image by using a Dockerfile.
Create a Dockerfile
Create a test directory and change to it:
mkdir test && cd test
Create the Dockerfile:
cat > Dockerfile <<EOF
# Use an official Node runtime as the parent image
FROM node:lts
# Set the working directory in the container to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
# Make the container's port 80 available to the outside world
EXPOSE 80
# Run app.js using node when the container launches
CMD ["node", "app.js"]
EOF
Note: In this step, you assemble the container image by first selecting a parent or base image.
This is specified with the FROM instruction and the official Docker image for Node version lts (long term support).
The WORKDIR instruction sets the working directory in the container for any additional instructions that follow in the Dockerfile. For this lab, we use the /app directory as the container's working directory.
The COPY instruction copies directories or files from the source location to the destination path of the container image file system. Here, we copy files from the current directory to /app.
The EXPOSE instruction exposes the container's port so that it accepts connections on that port, which in this lab is port 80.
Finally, the CMD instruction provides the node command to execute the application in the running container.
Develop your application
Next, you write the code for your Node.js application. This application is a simple HTTP server that listens for requests on port 80, and responds with a static message.
Create the app.js file with your application source code:
cat > app.js <<EOF
const http = require('http');
const hostname = '0.0.0.0';
const port = 80;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Welcome to your first Docker container!\n');
});
server.listen(port, hostname, () => {
console.log('Server running at http://%s:%s/', hostname, port);
});
process.on('SIGINT', function() {
console.log('Caught interrupt signal and will exit');
process.exit();
});
EOF
Note: The application also implements the SIGINT handler function to log a message and exit gracefully when the container is stopped.
Verify the contents of the application source file:
cat app.js
Build the container image
In this subtask, you build the container image from the Dockerfile by using the docker build command.
Run the docker build command:
docker build -t my-app:0.1 .
A partial command output is below:
=> [internal] load dockerignore
=> => transferring context: 2B
=> [internal] load build definition from Dockerfile
=> => transferring dockerfile: 394B
=> [internal] load metadata for docker.io/library/node:lts
=> [1/3] FROM docker.io/library/node:lts@sha256:586cdef48f920dea2f47a954b8717601933aa1daa0a08264abf9144789abf8ae
=> => resolve docker.io/library/node:lts@sha256:586cdef48f920dea2f47a954b8717601933aa1daa0a08264abf9144789abf8ae
=> => sha256:b7483c70b94e9fbb68e91d64456ee147d120488f876d69efeae815ba164e8b54 2.21kB / 2.21kB
...
...
=> [internal] load build context
=> => transferring context: 912B
=> [2/3] WORKDIR /app
=> [3/3] COPY . /app
=> exporting to image
=> => exporting layers
=> => writing image sha256:8cf51a1aba351cf505cd6d8eefa966b
=> => naming to docker.io/library/my-app:0.1
Note: This command builds the container image from the instructions in the Dockerfile in the current directory and tags the resulting image with the specified name and version. Google recommends to specify a tag to distinguish newer image versions from older ones.
View the list of images that were built:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app 0.1 8cf51a1aba35 10 minutes ago 997MB
Note: The command lists the base node image and the my-app image that you built. The size of the image is relatively small compared to other virtual machine images.
To verify the objective, click Check my progress.
Build a container image
Task 3. Run and test the application
After the container image is successfully built, you can run your application and test it to ensure that it behaves as expected.
Run the container
To run the container, execute the command:
docker run -p 8080:80 --name my-app -d my-app:0.1
Note: The docker run command starts the container with the specified name. The -p argument maps the host's port 8080 to the container's port 80, enabling requests to reach the server at http://localhost:8080. The -d argument runs the container in the background.
To view a list of running containers, execute the command:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
46c209a1fd87 my-app:0.1 "docker-entrypoint.s…" 19 seconds ago Up 17 seconds 0.0.0.0:8080->80/tcp my-app
Test the application
To test the application, send it a HTTP request by using the curl command:
curl http://localhost:8080
Verify the application response:
Welcome to your first Docker container!
Stop the container by executing the docker stop command:
docker stop [CONTAINER ID]
Replace [CONTAINER ID] with the value of the CONTAINER ID from the output of the command that was executed in the previous subtask.
Task 4. Modify the container
You can have multiple versions of your containerized applications that share common layers in the image. In this task, you create another version of the containerized application and test both versions.
Modify the application code
In the test directory, update the content of the app.js file:
cat > app.js <<EOF
const http = require('http');
const url = require('url');
const hostname = '0.0.0.0';
const port = 80;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
console.log('Received request with URL: ?%s', req.url);
var q = url.parse(req.url, true).query;
res.end(q.user + ', Welcome to your first Docker container!\n');
});
server.listen(port, hostname, () => {
console.log('Server running at http://%s:%s/', hostname, port);
});
process.on('SIGINT', function() {
console.log('Caught interrupt signal and will exit');
process.exit();
});
EOF
Note: The modified application code adds the value of a user query parameter that is passed in the HTTP request in the application response.
Verify the contents of the modified application source file with the cat command:
As seen in the output, in the new container image only layers from Step 3 and below are modified because changes were made in the app.js source file.
Run the new container
To run the new container, execute the command:
docker run -p 8080:80 --name my-app-2 -d my-app:0.2
To view a list of running containers, execute the command:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7071749fe0f6 my-app:0.2 "docker-entrypoint.s…" 10 seconds ago Up 10 seconds 0.0.0.0:8081->80/tcp my-app-2
Test the application
To test the application, send it a HTTP request by using curl:
curl http://localhost:8080?user=Learner
Verify the application response:
Learner, Welcome to your first Docker container!
Note: The response contains the value of the user argument that was passed in the request to the container that is running the image version 0.2 of the application.
Click Check my progress to verify the objective.
Modify the container and rebuild the container image.
Task 5. Troubleshooting
There are some easy techniques to troubleshoot your containerized applications. We review some of these methods in this task.
View container logs
First, retrieve the ID of the container whose logs you need to view:
docker ps
To view the container logs, run the docker logs command:
docker logs [CONTAINER ID]
Replace the CONTAINER ID with the initial characters of the container ID that uniquely identifies it from the output of the previous command. To tail the log's output as the container is running, use the -f option with the logs command.
Server running at http://0.0.0.0:80/
Received request with URL: ?/?user=Learner
Start a shell inside the container
You can start an interactive shell inside a running container to troubleshoot it.
From within this shell, to troubleshoot issues, you can inspect the container file system and other data files that your application might use.
ls
Exit the Bash shell:
exit
Examine container metadata
To view a container's metadata, run:
docker inspect [CONTAINER ID]
Here's a partial output from the command:
[
{
"Id": "7071749fe0f66b8b1953bbb6f28f159bd5dbeae079595675e2591d32d87ae5dc",
"Created": "2023-02-23T18:08:34.286519913Z",
"Path": "docker-entrypoint.sh",
"Args": [
"node",
"app.js"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 1099,
"ExitCode": 0,
"Error": "",
"StartedAt": "2023-02-23T18:08:34.785098365Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:5fc2d7a43c4678da17daf204ef4b071f2da869ead758864622d90d880a40c24b",
"ResolvConfPath": "/var/lib/docker/containers/7071749fe0f66b8b1953bbb6f28f159bd5dbeae079595675e2591d32d87ae5dc/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/
...
...
}
]
Note: By default, the inspect command provides detailed metadata information in a JSON array. You can filter the results with the --format argument to inspect specific fields in the output.
Task 6. Publishing a container image
Artifact Registry is a Google Cloud service that is used to store and manage software artifacts in private repositories, including container images, and software packages.
In this task, you push your container images to Artifact Registry making them available for deployment to other environments such as staging, and production, which make up your software delivery lifecycle.
Create an image repository
Before you can push any container images to Artifact Registry, you must first create a repository.
In the Google Cloud console, in the Navigation menu (), click View all products. Then, under CI/CD Categories, navigate to Artifact Registry > Repositories.
In the Create repository page, provide the following information, and leave the remaining settings as their defaults:
Property
Value (type or select)
Name
my-repo
Format
Docker
Location type
Region
Region
Click Create.
Authenticate Docker to use the repository
Before you can push or pull images to or from the repository, you must configure Docker to authenticate requests to the repository in Artifact Registry.
To set up authentication to Docker repositories in the region , in the VM shell, run the following command:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-app 0.2 9b1ef4854d32 4 minutes ago 997MB
us-east1-docker.pkg.dev/qwiklabs-gcp-02-7c092125ce3a/my-repo/my-app 0.2 9b1ef4854d32 4 minutes ago 997MB
my-app 0.1 8cf51a1aba35 5 minutes ago 997MB
To push the image to Artifact Registry, run the following command:
After the command completes, in the Google Cloud console, in the Navigation menu (), click View all products. Then, under the CI/CD Categories, navigate to Artifact Registry > Repositories.
Click the my-repo repository to display the my-app Docker container image.
Click Check my progress to verify the objective.
Publish a container image.
Task 7. Pull and test the container image
In this task, you start with a fresh environment and then pull the container image from Artifact Registry to test it. To simulate another environment, you stop and remove all containers and images from your shell environment that were created in the previous tasks in this lab.
Stop and remove containers
To stop all running containers, execute the following command:
docker stop $(docker ps -q)
To remove all containers, execute the following command:
docker rm $(docker ps -aq)
Remove all container images
To remove the registry-tagged container image, execute the following command:
docker rmi ${REGION}-docker.pkg.dev/$PROJECT_ID/my-repo/my-app:0.2
Note: This command does not remove the container image from the registry.
To remove all other images, execute the following command:
docker rmi -f $(docker images -aq)
Verify that no container images exist in your VM environment:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
You should now have a fresh host environment without any local images.
Test the image
Test the image by pulling it from Artifact Registry.
To pull the image from Artifact Registry, execute the following command:
To run the container, execute the following command:
docker run -p 8080:80 -d ${REGION}-docker.pkg.dev/${PROJECT_ID}/my-repo/my-app:0.2
To test the application, run:
curl http://localhost:8080?user=Learner
Note: This task demonstrates container portability where you can run containerized applications on other VMs or environments with Docker, and without the need to install any application dependencies on the host machine. The container images can be hosted on public or private registries which should be accessible by Docker.
Congratulations!
Congratulations on completing this lab on the fundamentals of creating containers with Docker. In this lab, you:
Built container images with Docker and ran Docker containers.
Pushed Docker images to Artifact Registry, Google Cloud's container image repository.
Pulled Docker images from Artifact Registry and ran them in a fresh environment to verify container portability.
Next Steps / Learn More
For more information about Docker, and Artifact Registry, view the documentation:
Copyright 2022 Google LLC All rights reserved. Google and the Google logo are trademarks of Google LLC. All other company and product names may be trademarks of the respective companies with which they are associated.
Les ateliers créent un projet Google Cloud et des ressources pour une durée déterminée.
Les ateliers doivent être effectués dans le délai imparti et ne peuvent pas être mis en pause. Si vous quittez l'atelier, vous devrez le recommencer depuis le début.
En haut à gauche de l'écran, cliquez sur Démarrer l'atelier pour commencer.
Utilisez la navigation privée
Copiez le nom d'utilisateur et le mot de passe fournis pour l'atelier
Cliquez sur Ouvrir la console en navigation privée
Connectez-vous à la console
Connectez-vous à l'aide des identifiants qui vous ont été attribués pour l'atelier. L'utilisation d'autres identifiants peut entraîner des erreurs ou des frais.
Acceptez les conditions d'utilisation et ignorez la page concernant les ressources de récupération des données.
Ne cliquez pas sur Terminer l'atelier, à moins que vous n'ayez terminé l'atelier ou que vous ne vouliez le recommencer, car cela effacera votre travail et supprimera le projet.
Ce contenu n'est pas disponible pour le moment
Nous vous préviendrons par e-mail lorsqu'il sera disponible
Parfait !
Nous vous contacterons par e-mail s'il devient disponible
Un atelier à la fois
Confirmez pour mettre fin à tous les ateliers existants et démarrer celui-ci
Utilisez la navigation privée pour effectuer l'atelier
Ouvrez une fenêtre de navigateur en mode navigation privée pour effectuer cet atelier. Vous éviterez ainsi les conflits entre votre compte personnel et le compte temporaire de participant, qui pourraient entraîner des frais supplémentaires facturés sur votre compte personnel.
In this lab, you create Docker containers and run them locally in Cloud Shell. You also publish a container image to Artifact Registry.
Durée :
1 min de configuration
·
Accessible pendant 60 min
·
Terminé après 60 min