Skip to content

Bureau d'Γ©tudes Cloud & DockerπŸ”—

Link to slides

Objectives of this BEπŸ”—

This Bureau d'Γ©tudes (BE, for short) will guide you through the essential notions to be able to manipulate with regard to cloud computer and docker,

We will go through several steps

  • Working in a remote environment (in a GitHub CodeSpace, inside a VM)
  • Creation and ssh connection to virtual machine instances
  • Using managed storage capabilities (gcs://)
  • Creating your own docker images
  • Exchanging docker images through a Container Registry
  • Pulling and running docker images created by your teammates

In particular, this workflow:

workflow

Warning

Please read all the text in the question before executing the step-by-step instructions because there might be help or indications after the instructions.

How to run this BEπŸ”—

The best way to run this BE is to setup a Github Codespace VM and install the google cloud sdk. Refer to the previous hands-on to learn more

We will be using the gcloud CLI for the following:

  • Create a GCE Virtual Machine
  • Connect to SSH with port forwarding to said machine

For the rest of this walkthrough, if it is specified "from your local machine", this will be "github codespace"

If it is specified "inside the VM", this means that you should run it inside the GCE VM, which means you need to connect to it using an SSH tunnel first...

πŸ™πŸ» Use Google Chrome without any ad blockers if you have any issues, or use the local VSCode + CodeSpace extension

Warning

⚠️ Normally you will do everything from your browser, connected to the github codespace, so it should work
⚠️ if you have any issues, switch your wi-fi connection between eduroam (preferred), isae-edu or a 4G hotspot

Team composition & SetupπŸ”—

You should be in team of 5, however this will work with a minimum of 2 people.

Each team member picks a different cute mascot and remembers it:

  • 🐈 cat
  • πŸ• dog
  • πŸ‘½ (baby) yoda
  • πŸ¦‰ owl
  • 🐼 panda

Find a groupname, because you will need it for the next steps

One of the team member will add the others into their GCP project so that everyone can collaborate.

Designate a "project manager" (the person who is the most comfortable with the google cloud platform UI). That person will have the hard task of giving access to his/her GCP project to the other team members to enable collaboration.

This means that the project of the "team leader" will be billed a little more for the duration of this BE, so please be kind with the project and apply good cloud hygiene :)

Rest assured, this will not cost very much !

How to do that ?

Go to the "IAM & Admin / IAM" section of the Google Cloud Console, then locate the "grant access",

Grant access to your each of your teammates using the "Editor Role" (Basic -> Editor)

Here are some screenshots to help you

access1 access2

1 - Build, Ship, Run (Deploy) as a TeamπŸ”—

1.1 - BuildπŸ”—

1.1.1 - Start Development Environment (Github Codespace)πŸ”—

1.1.2 - Get the necessary resources from Google Cloud StorageπŸ”—

From your github codespace,

The resources are located at the URI gs://fchouteau-isae-cloud/be/${MASCOT},

Your ${MASCOT} name is either:

  • cat
  • dog
  • owl
  • panda
  • yoda

I advise you to export MASCOT=.... to remember it :)

ONLY DOWNLOAD your mascot resources (no cheating ! this will only cause confusion later)

Download them to your instance using the gcloud cli (refer to your previous work for more information)

Hint

gsutil -m cp -r {source} {destination}
Remember that google storage URIs always begin with gs://

Go to (cd) the folder where you downloaded your resources

You should see a file structure like this

fchouteau@be-cloud-mascot:~/be$ tree yoda  -L 2
yoda
β”œβ”€β”€ app.py
β”œβ”€β”€ AUTHOR.txt
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ favicon.ico
β”œβ”€β”€ imgs
β”‚Β Β  β”œβ”€β”€ 1.gif
β”‚Β Β  β”œβ”€β”€ 2.gif
β”‚Β Β  β”œβ”€β”€ 3.gif
β”‚Β Β  β”œβ”€β”€ 4.gif
β”‚Β Β  └── 5.gif
└── template.html.jinja2

1 directory, 10 files

1.1.3 - Build your docker imageπŸ”—

Question

  • Look at the Dockerfile (cat Dockerfile), what does it seem to do ?
  • Look at app.py (cat app.py). What is Flask ? What does it seem to do ?
  • Edit the file AUTHOR.txt to add your name instead of the placeholder
  • Refer to your previous work to build the image

Danger

On which port is your flask app running ? (cat Dockerfile) Note it carefully ! You will need to communicate it to your teammate :)

  • When building the image, name it appropriately... like eu.gcr.io/${PROJECT_ID}/webapp-gif:${GROUPNAME}-${MASCOT}-1.0 !
Hint

to get your project id:

PROJECT_ID=$(gcloud config get-value project 2> /dev/null)

  • now if you list your images you should see it !
REPOSITORY                                      TAG                 IMAGE ID            CREATED             SIZE
eu.gcr.io/{your project name}/{your-app}    1.0                 d1c5993848bf        2 minutes ago       62.1MB

Question

Describe concisely to your past self what is a Docker Image

1.2 - ShipπŸ”—

1.2.1 - Push your Docker image in the shared Container RegistryπŸ”—

Question

Describe succintly to your past self what is a Container Registry

1.3 - Run (deploy)πŸ”—

1.3.1 - Create Google Compute Engine VMπŸ”—

Each team member creates a separate GCE Instance (Virtual Machine) on the same project,

Here, you will create a Google Compute Engine instance, preconfigured with everything you need,

If you use the google cloud CLI (from your codespace), you can use this

First, set a variable with the name of your instance,

export INSTANCE_NAME="be-cloud-mascot-{yourgroup}-{yourname}" # Don't forget to replace values !

Then create your VM

gcloud compute instances create $INSTANCE_NAME \
        --zone="europe-west1-b" \
        --image-family="common-cpu" \
        --image-project="deeplearning-platform-release" \
        --maintenance-policy="TERMINATE" \
        --scopes="storage-rw" \
        --machine-type="n1-standard-1" \
        --boot-disk-size="50GB" \
        --boot-disk-type="pd-standard"

If you have an issue with quota, use any of europe-west4-{a,b,c,d} or europe-west1-{b,c,d}

If you use the web interface, follow this

Question

Describe concisely to your past self what is a Virtual Machine and what is Google Compute Engine

1.3.2 - Connect using SSH to the instanceπŸ”—

If you are using the google cloud sdk from github codespace, you can connect to ssh using the usual command.

Tunnel the following ports to your local machine:

  • 8080: This is reserved for a jupyter lab session by default, it makes it easy to see & edit text
  • 8081: You will neeed to run containers and expose them on a port
Hint
gcloud compute ssh {user}@{instance} -- \
    -L {client-port}:localhost:{server-port} \
    -L {client-port-2}:localhost:{server-port-2}

Go to your browser and connect to http://localhost:8080, you should be in a jupyter lab where you can access a terminal, a text editor etc...

Question

Where is this jupyter lab hosted ? Describe concisely what is a SSH Tunnel and what is port forwarding

1.3.3 - Pull Docker Images from your teammateπŸ”—

You should be inside the your VM,

Question

How to check that you're inside your VM ? On your terminal you should see user@hostname at the beginning. Hostname should be the name of your VM

1.3.4 - Run Docker Containers from their Docker ImagesπŸ”—

Hint

the port is not the same as yours
if you don't set the username, it will come to bite your later ;)

1.3.5 - Display the results & share themπŸ”—

  • You just launched a webapp on the port 8081 of your remote instance.

  • If you have a ssh tunnel directly from your laptop, ensure that you made a tunnel for your port 8081 to any port of your machine then, go to http://localhost:(your port) inside your browser. The resulting webpage should appear

  • If you are using github codespace, open web preview on port 8081 (you should have a tunnel running between your github codespace and your GCE instance)

  • You can also publicly share the codespace preview link so that other people can see your results

Checklist

  • The webpage should display the mascot your chose to run
  • The webpage should display the name of the author (not you)
  • The webpage should display your name

Bug

If any of the three item above are missing, find the bug and solve it :)

Example

Try to refresh the webpage to make more gifs appear

Share your result on slack

1.4. Cleanup the GCP projectπŸ”—

1.5. Yay !πŸ”—

Success

πŸŽ‰ you have successfully finished the mandatory part of the BE. You know how to manipulate the basic notions around cloud computing and docker so that you won't be completely lost when someone will talk about it

Continue the BE below (you can do it alone or by group of 2 or 3) to discover more nice things !

2 - Another deploymentπŸ”—

2.1 - Let's discover StreamlitπŸ”—

We will now introduce streamlit, which is a very nice tool to build quick webapps in python !

In this TP you will build your first interactive webapp in python and package it in a container.

First, look at this video,

Then, take a look at an introduction to streamlit and the streamlit application gallery

Question

Can you describe what exactly is streamlit ? Could you find any way it could be useful to you ?

2.2 Your first streamlit applicationπŸ”—

Take a look at the code below,

import streamlit as st
from streamlit_image_comparison import image_comparison
import cv2

st.set_page_config("Webb Space Telescope vs Hubble Telescope", "πŸ”­")

st.header("πŸ”­ J. Webb Space Telescope vs Hubble Telescope")

st.write("")
"This is a reproduction of the fantastic [WebbCompare](https://www.webbcompare.com/index.html) app by [John Christensen](https://twitter.com/JohnnyC1423). It's built in Streamlit and takes only 10 lines of Python code. If you like this app, please star [John's original repo](https://github.com/JohnEdChristensen/WebbCompare)!"
st.write("")

st.markdown("### Southern Nebula")
image_comparison(
    img1="https://www.webbcompare.com/img/hubble/southern_nebula_700.jpg",
    img2="https://www.webbcompare.com/img/webb/southern_nebula_700.jpg",
    label1="Hubble",
    label2="Webb",
)


st.markdown("### Galaxy Cluster SMACS 0723")
image_comparison(
    img1="https://www.webbcompare.com/img/hubble/deep_field_700.jpg",
    img2="https://www.webbcompare.com/img/webb/deep_field_700.jpg",
    label1="Hubble",
    label2="Webb",
)

st.markdown("### Carina Nebula")
image_comparison(
    img1="https://www.webbcompare.com/img/hubble/carina_2800.png",
    img2="https://www.webbcompare.com/img/webb/carina_2800.jpg",
    label1="Hubble",
    label2="Webb",
)

st.markdown("### Stephan's Quintet")
image_comparison(
    img1="https://www.webbcompare.com/img/hubble/stephans_quintet_2800.jpg",
    img2="https://www.webbcompare.com/img/webb/stephans_quintet_2800.jpg",
    label1="Hubble"
    label2="Webb",
)

Question

Can you describe, by reading the documentation, what does the code do ?

2.3 - Local deployment in codespaceπŸ”—

First, we will install in the codespace the dependencies for our application,

pip install streamlit streamlit opencv-python-headless streamlit-image-comparison

Then create a file streamlit_jswt.py and copy/paste the code above.

Then execute it streamlit run streamlit_jswt.py

This will launch the application on the port 8501 (by default) of our codespace. You can connect to it as usual.

🀩 Nice, isn't it ?

Now you can quit the server.

2.4 - A more complex applicationπŸ”—

We will run and package a more complex application, but a lot more useful for your deep learning class

Clone the following repository git clone https://github.com/fchouteau/isae-demo-streamlit-activation-functions.git

cd to the directory cd isae-demo-streamlit-activation-functions then as last time, install the dependencies pip install -r requirements.txt then run the application streamlit run app.py

You can visualize it as last time. This should be quite useful for you given you just left the Deep Learning Class !

2.5 - Transform application into docker imageπŸ”—

Refer to the previous TP where we built a website to convert what we just did into a docker image.

In short, create a Dockerfile that inherits from FROM python:3.10, copy all the app files COPY ./ /app/, install the dependencies RUN pip install -r /app/requirements.txt, expose the port EXPOSE 8501 then run as the app as an entrypoint CMD ["python", "-m", "streamlit", "run", "app.py"].

You should be able to do it yourself, but if you need help, here's what your Dockerfile looks like :

Solution
  FROM python:3.10

  COPY ./ /app/
  RUN pip install -r /app/requirements.txt

  EXPOSE 8501

  WORKDIR /app/

  CMD ["python", "-m", "streamlit", "run", "app.py"]

Then build your image, and run it locally (using the correct port forwarding which is 8501)

Solution
  # build
  docker build -t eu.gcr.io/sdd2324/streamlit-fch:1.0 -f Dockerfile . 
  # run
  docker run --rm -p 8501:8501 eu.gcr.io/sdd2324/streamlit-fch:1.0 # change this name to yours

Once you know it works locally, tag it and push it to our shared container registry

Solution
  # push to registry
  docker push eu.gcr.io/sdd2324/streamlit-fch:1.0 # change this name to yours

2.6 - Deployment in a VMπŸ”—

We will now create yet another VM to deploy our application. This time, we will deploy directly our container in a VM without connecting to ssh to it,

Don't forget to change the instance name & zone according to what you did previously.

Take a note to the --container-image and change it to the name of the image you just pushed

gcloud compute instances create-with-container fch-streamlit-demo \
    --project=[your project] \
    --zone=europe-west1-b \
    --machine-type=n1-standard-1 \
    --image=projects/cos-cloud/global/images/cos-stable-109-17800-66-27 \
    --boot-disk-size=10GB \
    --boot-disk-type=pd-standard \
    --container-image=[your image] \
    --container-restart-policy=always

Compared to previously, note that we explicitly specify a container to deploy to the VM and we don't use ubuntu but a container optimized OS.

2.7 - Publish the results on the webπŸ”—

First run this command in your codespace. This will expose the port 8501 to the web

gcloud compute --project=[your project] firewall-rules create open-8501 --direction=INGRESS --priority=1000 --network=default --action=ALLOW --rules=tcp:8501 --source-ranges=0.0.0.0/0
Then, locate the public IP of your VM using the google cloud console.

Finally, take your phone (it won't work over ISAE wifi, maybe on eduroam) and connect to its port 8501, http://ip-of-the-machine:8501

🧐 The app should appear !

We just deployed a webapp written in python to a public website :)

2.8 - CleanupπŸ”—

As usual, cleanup your resources. Delete the GCE VM.

2.9 - Yay !πŸ”—

Success

🍾 you have successfully finished the all parts of the BE. You know how to manipulate the basic notions around cloud computing and docker so that you won't be completely lost when someone will talk about it

Finish the previous hands-on (cloud & docker) if you have time. In particular, take a look at the docker-compose section.

3 - I'm finished, now I'm bored !πŸ”—

I advise you to ensure you've done this part of the previous GCP hands-on