Commit 052ac271 authored by Daniele Santoro's avatar Daniele Santoro
Browse files

Release lab lesson 4

parent e8ba4bac
......@@ -39,4 +39,10 @@ by us distributing a =Vagrantfile= and a =provisioning script=.
- [[file:e09][Exercise 9 - Install and Verify Docker]]
- [[file:e10][Exercise 10 - Hello World with Docker]]
- [[file:e11][Exercise 11 - Build a custom Docker image]]
* Lab04_20220419
- [[file:e12][Exercise 12 - Build a Docker image using a Dockerfile]]
- [[file:e13][Exercise 13 - Make two containers talking each others]]
- [[file:e14][Exercise 14 – Run a Service with Docker]]
- [[file:e15][Exercise 15 - Run a custom Service with Docker]]
- [[file:e16][Exercise 16 - Run a custom Docker Service with persistency]]
......@@ -36,4 +36,3 @@ Forward a guest port on the host to expose apache in the host
vagrant ssh -- -L 8888:localhost:80
#+end_src
As soon as the above channel stays open, apache2 will be available from the browser
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FROM ubuntu
MAINTAINER Daniele Santoro <dsantoro@fbk.eu>
RUN apt-get update
RUN apt-get install figlet
* Exercise 12 - Build a Docker image using a Dockerfile
- Time :: 10 minutes
- 3 minutes: /Try by yourself/
- 5 minutes: /Check, Verify, Ask/
- Description :: After completing last exercise try to build the very same image but using a Dockerfile instead of creating it from a running container. Understand how and why your image is different from the initial one. Give it a name and a tag and optionally upload it on the public Docker registry. Finally start a container based on the custom image.
* Solutions and Instructions
** Write a Dockerfile
You can look at this [[file:Dockerfile][Dockerfile]].
=FROM= command _must_ be at the very first line
#+BEGIN_EXAMPLE
FROM <original_image>
#+END_EXAMPLE
In =<original_image>= we could specify a tag, if not =latest= is used:
#+BEGIN_EXAMPLE
ubuntu
ubuntu:latest
ubuntu:bionic
#+END_EXAMPLE
** Build the image
#+BEGIN_SRC sh
cd e4
docker build -t hub.docker.com/myfiglet-${USER: -3} .
#+END_SRC
** List all images
#+BEGIN_SRC sh
docker image list
#+END_SRC
** Give it a different tag
Default tag is =latest=, we can add a new one to mark our very specific version
#+BEGIN_SRC sh
docker tag hub.docker.com/myfiglet-${USER: -3}:latest hub.docker.com/myfiglet-${USER: -3}:v1
#+END_SRC
List all images again
#+BEGIN_SRC sh
docker image list
#+END_SRC
** Upload it to the Docker Hub (optional)
Login into Docker Hub (hub.docker.com)
#+BEGIN_SRC sh
docker login
#+END_SRC
Push your image /(please look next step before)/
#+BEGIN_SRC sh
docker push hub.docker.com/myfiglet-${USER: -3}
#+END_SRC
The above command can not work because Docker Hub has namespaces-based permission. If I had been logged in, I would have used something like:
#+BEGIN_SRC sh
docker tag hub.docker.com/myfiglet-${USER: -3}:latest hub.docker.com/dsantoro/myfiglet:v1
docker push hub.docker.com/dsantoro/myfiglet:v1
#+END_SRC
** Start a new container from the new image
=figlet= utility is already there
#+BEGIN_SRC sh
docker run -it hub.docker.com/dsantoro/myfiglet:v1
figlet "Best UniTN course of the year ;D"
#+END_SRC
* Exercise 13 - Make two containers talking each others
- Time :: 5 minutes
- 2 minutes: /Try by yourself/
- 3 minutes: /Check, Verify, Ask/
- Description :: Create a custom bridged network. Create two different container (a client and a server) and attach them to the same network. Finally use Docker internal DNS to communicate from one to the other.
* Solutions and Instructions
** Clear all stopped container (optional)
#+BEGIN_SRC sh
docker rm $(docker ps -a -q)
#+END_SRC
** Create a custom Docker network
Look at the current Linux bridges
#+BEGIN_SRC sh
brctl show
#+END_SRC
Create the Docker custom network named =mynet-PLACEHOLDER=
#+BEGIN_SRC sh
docker network create mynet-${USER: -3}
#+END_SRC
Look at the network that has been created
#+BEGIN_SRC sh
docker network list
#+END_SRC
Look at the Linux bridge that has been created
#+BEGIN_SRC sh
brctl show
#+END_SRC
** Create the server
#+BEGIN_SRC sh
docker run -d --net mynet-${USER: -3} --name server-${USER: -3} busybox nc -l 0.0.0.0:7000
#+END_SRC
** Create the client and test
Get your personal placeholder
#+BEGIN_SRC sh
echo ${USER: -3}
ntu
#+END_SRC
Create the personal client and test on your personal server
#+BEGIN_SRC sh
docker run --net mynet-${USER: -3} busybox ping server-ntu
#+END_SRC
* Exercise 14 – Run a Service with Docker
- Time :: 15 minutes
- 5 minutes: /Try by yourself/
- 10 minutes: /Check, Verify, Ask/
- Description :: Using the =nginx= container image at https://hub.docker.com/_/nginx/, setup a simple webserver. Expose its port on the Docker host and connect to it.
1) Run a =nginx= container in detached mode exposing its service on a random host port
2) Check if the container is in execution
3) Identify the random port that has been exposed
4) Connect with the container web-server using curl on the host
5) Connect with the container web-server using a web browser
6) How Docker knows the internal container port which is now bound on the random one?
7) Practice with docker logs during http server requests
* Solutions and Instructions
1) Run a =nginx= container in detached mode exposing its service on a random host port
#+BEGIN_SRC sh
docker run -P -d --name webserver-${USER: -3} nginx
#+END_SRC
2) Check if the container is in execution
#+BEGIN_SRC sh
docker ps
#+END_SRC
3) Identify the random port that has been exposed
#+BEGIN_SRC sh
PORT=`docker port webserver-${USER: -3} | sed s/.*://g`
echo "You can connect using a browser with: http://localhost:$PORT"
#+END_SRC
4) Connect with the container web-server using curl on the host
#+BEGIN_SRC sh
curl http://localhost:$PORT
#+END_SRC
5) Connect with the container web-server using a web browser
1) Setup the socks proxy on your browser
2) Use the following URL: =http://localhost:$PORT=. /See above/
6) How Docker knows the internal container port (in this case the port 80) which is now bound on the random one?
In =Dockerfile= we specify ports to expose using the keyword: =EXPOSE=, see [[https://docs.docker.com/engine/reference/builder/#expose][this reference doc]].
7) Practice with docker logs during http server requests
/Need to use two different shells or the browser/
On the second shell
#+BEGIN_SRC sh
docker logs -f webserver-${USER: -3}
#+END_SRC
on the first one
#+BEGIN_SRC sh
curl http://localhost:$PORT
#+END_SRC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FROM nginx
MAINTAINER Daniele Santoro <dsantoro@fbk.eu>
COPY index-v1.html /usr/share/nginx/html/index.html
\ No newline at end of file
* Exercise 15 – Run a custom Service with Docker
- Time :: 10 minutes
- 4 minutes: /Try by yourself/
- 6 minutes: /Check, Verify, Ask/
- Description :: Using the =nginx= container image at https://hub.docker.com/_/nginx/, setup a simple webserver. Replace nginx default page with a custom content. Expose its internal port on the port =8080= of the Docker host and connect to it. Finally change the custom content exposed by the webserver.
1) Create a custom =index.html= file
2) Create a =Dockerfile=
3) Create a custom image based on the =nginx=
4) Start the new custom container in detached mode exposing port =8080= on the Docker host
5) Check if the container is in execution
6) Connect with the container web-server using curl or a web browser
7) Modify content of =index.html=
8) Check the web-server page now
9) Destroy and restart the container
10) Check the web-server page now
11) How can I persist the state of the latest version of my webserver?
* Solutions and Instructions
1) Create a custom =index.html= file\\
See [[file:index-v1.html][index-v1.html]] and [[file:index-v2.html]]
2) Create a =Dockerfile=
See [[file:Dockerfile][Dockerfile]]
3) Create a custom image based on the =nginx=
#+BEGIN_SRC sh
docker build -t cws .
#+END_SRC
4) Start the new custom container in detached mode exposing port =8080= (each user should use different port) on the Docker host
#+BEGIN_SRC sh
docker run -p8080:80 -d --name cws-${USER: -3} cws
#+END_SRC
5) Check if the container is running
#+BEGIN_SRC sh
docker ps
#+END_SRC
6) Connect with the container web-server using curl or a web browser
#+BEGIN_SRC sh
curl http://localhost:8080
#+END_SRC
7) Modify content of =index.html=
#+BEGIN_SRC sh
docker cp index-v2.html cws-${USER: -3}:/usr/share/nginx/html/index.html
#+END_SRC
8) Check the web-server page now
#+BEGIN_SRC sh
curl http://localhost:8080
#+END_SRC
9) Destroy and restart the container
/Let us now assume that for some reason the container must be restarted by an admin, the server hosting the container goes down or the container restarts for an application fatal error. Of course we will simulate this bad situation (that honeslty in production may appear very frequently) using the following commands:/
#+BEGIN_SRC sh
docker stop cws-${USER: -3}
docker rm cws-${USER: -3}
docker run -p8080:80 -d --name cws-${USER: -3} cws
#+END_SRC
10) Check the web-server page now
#+BEGIN_SRC sh
curl http://localhost:8080
#+END_SRC
11) How can I persist the state of the latest version of my webserver?
<!DOCTYPE html>
<html>
<head>
<title>Custom webserver v1</title>
</head>
<body>
<h1>Custom webserver v1</h1>
<h2>Absolutely !!! This is the best course in UniTN... ;D</h2>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>Custom webserver v2</title>
</head>
<body>
<h1>Custom webserver v2</h1>
<h2>Absolutely !!! This is the best course in UniTN... ;D</h2>
<h3>...unfortunately teachers are not so good :D</h3>
</body>
</html>
\ No newline at end of file
* Exercise 16 – Run a custom Docker Service with persistency
- Time :: 7 minutes
- 3 minutes: /Try by yourself/
- 4 minutes: /Check, Verify, Ask/
- Description :: Adapt last exercise using a Bind mount or a Docker Volume to add persistency.
* Solutions and Instructions
** Start the custom container with a Bind Mount
#+BEGIN_SRC sh
cd e8
docker run -p 8090:80 -d --name cwsp-${USER: -3} -v `pwd`:/usr/share/nginx/html nginx
#+END_SRC
** Browse v1 or v2
#+BEGIN_SRC sh
curl http://localhost:8090/index-v1.html
curl http://localhost:8090/index-v2.html
#+END_SRC
** Browse default index
#+BEGIN_SRC
curl http://localhost:8090/index.html
#+END_SRC
** Switch the default index between two versions and check
#+BEGIN_SRC sh
ln -sf index-v2.html index.html
curl http://localhost:8090/index.html
ln -sf index-v1.html index.html
#+END_SRC
** Check the folder in the container
#+BEGIN_SRC sh
docker exec -it cwsp-${USER: -3} ls -l /usr/share/nginx/html
#+END_SRC
<!DOCTYPE html>
<html>
<head>
<title>Custom webserver v1</title>
</head>
<body>
<h1>Custom webserver v1</h1>
<h2>Absolutely !!! This is the best course in UniTN... ;D</h2>
</body>
</html>
\ No newline at end of file
<!DOCTYPE html>
<html>
<head>
<title>Custom webserver v2</title>
</head>
<body>
<h1>Custom webserver v2</h1>
<h2>Absolutely !!! This is the best course in UniTN... ;D</h2>
<h3>...unfortunately teachers are not so good :D</h3>
</body>
</html>
\ No newline at end of file
index-v1.html
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment