6.2.7 Lab - Build A Sample Web App in A Docker Container - ILM
6.2.7 Lab - Build A Sample Web App in A Docker Container - ILM
Version)
Instructor Note: Red font color or gray highlights indicate text that appears in the instructor copy only.
Background / Scenario
In this lab, you will review basic bash scripting techniques because bash scripting is a prerequisite for the rest
of the lab. You will then build and modify a Python script for a simple web application. Next, you will create a
bash script to automate the process for creating a Dockerfile, building the Docker container, and running the
Docker container. Finally, you will use docker commands to investigate the intricacies of the Docker
container instance.
Required Resources
1 PC with operating system of your choice
Virtual Box or VMWare
DEVASC Virtual Machine
Instructions
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 1 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
Step 7: Change the mode of the script to an executable file for all users.
Change the mode of the script to an executable using the chmod command. Set the options to a+x to make
the script executable (x) by all users (a). After using chmod, notice permissions have been modified for
users, groups, and others to include the "x" (executable).
devasc@labvm:~/labs/devnet-src/sample-app$ ls -l user-input.sh
-rw-rw-r-- 1 devasc devasc 84 Jun 7 16:43 user-input.sh
devasc@labvm:~/labs/devnet-src/sample-app$ ls -l user-input.sh
-rwxrwxr-x 1 devasc devasc 84 Jun 7 16:43 user-input.sh
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 2 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 3 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
Notice the @sample.route("/") Flask statement. Frameworks such as Flask use a routing technique (.route) to
refer to an application URL (this not to be confused with network routing). Here the "/" (root directory) is bound
to the main() function. So, when the user goes to http://localhost:8080/ (root directory) URL, the output of the
return statement will be displayed in the browser.
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 4 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
devasc@labvm:~/labs/devnet-src/sample-app$
Step 1: Explore the directories that will be used by the web app.
The directories templates and static are already in the sample-app directory. Open the index.html and
style.css to view their contents. If you are familiar with HTML and CSS, feel free to customize these
directories and files as much as you like. However, be sure you keep the embedded
{{request.remote_addr}} Python code in the index.html file as this is the dynamic aspect of the sample web
app.
devasc@labvm:~/labs/devnet-src/sample-app$ cat templates/index.html
<html>
<head>
<title>Sample app</title>
<link rel="stylesheet" href="/static/style.css" />
</head>
<body>
<h1>You are calling me from {{request.remote_addr}}</h1>
</body>
</html>
devasc@labvm:~/labs/devnet-src/sample-app$ cat static/style.css
body {background: lightsteelblue;}
devasc@labvm:~/labs/devnet-src/sample-app$
Step 2: Update the Python code for the sample web app.
Now that you have explored the basic website files, you need to update the sample_app.py file so that it
renders the index.html file instead of just returning data. Generating HTML content using Python code can
be cumbersome, especially when using conditional statements or repeating structures. The HTML file can be
rendered in Flask automatically using the render_template function. This requires importing the
render_template method from the flask library and editing to the return function. Make the highlighted edits
to your script.
from flask import Flask
from flask import request
from flask import render_template
sample = Flask(__name__)
@sample.route("/")
def main():
return render_template("index.html")
if __name__ == "__main__":
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 5 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
sample.run(host="0.0.0.0", port=8080)
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 6 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
Build a Dockerfile.
Build the Docker container.
Start the container and verify it is running.
mkdir tempdir
mkdir tempdir/templates
mkdir tempdir/static
Step 2: Copy the website directories and sample_app.py to the temporary directory.
in the sample-app.sh file, add the commands to copy the website directory and script to tempdir.
cp sample_app.py tempdir/.
cp -r templates/* tempdir/templates/.
cp -r static/* tempdir/static/.
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 7 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 8 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 9 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
Step 2: Investigate the running Docker container and the web app.
a. The creation of the tempdir directories is not shown in the output for the script. You could add echo
commands to print out messages when they are successfully created. You can also verify they are there
with the ls command. Remember, this directory has the files and folders used to build the container and
launch the web app. It is not the container that was built.
devasc@labvm:~/labs/devnet-src/sample-app$ ls tempdir/
Dockerfile sample_app.py static templates
devasc@labvm:~/labs/devnet-src/sample-app$
b. Notice the Dockerfile created by your bash script. Open this file to see how it looks in its final form without
the echo commands.
devasc@labvm:~/labs/devnet-src/sample-app$ cat tempdir/Dockerfile
FROM python
RUN pip install flask
COPY ./static /home/myapp/static/
COPY ./templates /home/myapp/templates/
COPY sample_app.py /home/myapp/
EXPOSE 8080
CMD python3 /home/myapp/sample_app.py
c. The output for the docker ps -a command may be hard to read depending on the width of your terminal
display. You can redirect it to a text file where you can view it better without word wrapping.
devasc@labvm:~/labs/devnet-src/sample-app$ docker ps -a >> running.txt
devasc@labvm:~/labs/devnet-src/sample-app$
d. The Docker container creates its own IP address from a private network address space. Verify the web
app is running and reporting the IP address. In a web browser at http://localhost:8080, you should see
the message You are calling me from 172.17.0.1 formatted as H1 on a light steel blue background. You
can also use the curl command, if you like.
devasc@labvm:~/labs/devnet-src/sample-app$ curl http://172.17.0.1:8080
<html>
<head>
<title>Sample app</title>
<link rel="stylesheet" href="/static/style.css" />
</head>
<body>
<h1>You are calling me from 172.17.0.1</h1>
</body>
</html>devasc@labvm:~/labs/devnet-src/sample-app$
devasc@labvm:~/labs/devnet-src/sample-app$
e. By default, Docker uses the IPv4 172.17.0.0/16 subnet for container networking. (This address can be
changed if necessary.) Enter the command ip address to display all the IP addresses used by your
instance of the DEVASC VM. You should see the loopback address 127.0.0.1 that the web app used
earlier in the lab and the new Docker interface with the IP address 172.17.0.1.
devasc@labvm:~/labs/devnet-src/sample-app$ ip address
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 10 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen
1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
<output omitted>
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group
default
link/ether 02:42:c2:d1:8a:2d brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::42:c2ff:fed1:8a2d/64 scope link
valid_lft forever preferred_lft forever
<output omitted>
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 11 of 12 www.netacad.com
Lab - Build a Sample Web App in a Docker Container
2020 - 2021 Cisco and/or its affiliates. All rights reserved. Cisco Public Page 12 of 12 www.netacad.com