Skip to content

Latest commit

 

History

History
307 lines (237 loc) · 8.74 KB

File metadata and controls

307 lines (237 loc) · 8.74 KB

Trainer guide

Deck 2 Slide 25

Container lifecycle

# Pull the latest Ubuntu image
docker pull ubuntu:latest
# Create a container from the Ubuntu image
docker create --name my-ubuntu-container ubuntu:latest
# Run a container and access its shell
docker run -it --name my-running-container ubuntu:latest /bin/bash
# List all containers, running and stopped
docker ps -a
# Stop a container
docker stop my-running-container
# Start a stopped container
docker start my-running-container
# Access the shell of a running container
docker exec -it my-running-container /bin/bash
# View logs from a container
docker logs my-running-container
# Remove a container
docker rm my-running-container

Deck 2 Slide 41

Containerize apps

# app.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

# requirements.txt
Flask

pip install -r requirements.txt
python app.py

# Containerizing a Single-Container App with Docker

This guide demonstrates the steps to containerize a simple application using Docker.

## Prerequisites
- Docker installed on your machine.

## Step 1: Create a Dockerfile
Create a `Dockerfile` in the root directory of your project with the following content:

```Dockerfile
# Use an official Python runtime as a parent image
FROM python:3.8-slim

# Set the working directory in the container
WORKDIR /usr/src/app

# Copy the current directory contents into the container at /usr/src/app
COPY . .

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

# Run app.py when the container launches
CMD ["python", "./app.py"]

docker build -t my-single-container-app .
docker run -p 80:80 my-single-container-app

Docker Compose

Slide 63

create a docker-compose.yml


## Step 2: Create a Dockerfile
Refer to the previously provided Dockerfile for a Python Flask application.

## Step 3: Create a `docker-compose.yml` File
Create a `docker-compose.yml` in your project directory with the following content:

```yaml
version: '3.8'
services:
  web:
    build: .
    ports:
      - "80:80"
    environment:
      - FLASK_ENV=development
    volumes:
      - .:/usr/src/app

This defines a single service called web which will be built using the Dockerfile in the current directory. It binds the host's port 4000 to the container's port 80.

docker-compose up --build

Slide 78

Let's experiment with how creating some data within a container at runtime behaves!

# Build a container image with ubuntu image as base and ping installed
docker build --tag my-ubuntu-image -<<EOF
FROM ubuntu:22.04
RUN apt update && apt install iputils-ping --yes
EOF

# Run a container based on that image
docker run -it --rm my-ubuntu-image

# Confirm that ping was pre-installed
ping google.com -c 1 # Success!

# Create a container from the ubuntu image
docker run -it --rm ubuntu:22.04

# Make a directory and store a file in it
mkdir my-data
echo "Hello from the container!" > /my-data/hello.txt

# Confirm the file exists
cat my-data/hello.txt
exit

If we then create a new container, (as expected) the file does not exist!

# Create a container from the ubuntu image
docker run -it --rm ubuntu:22.04

# Check if the file exists
cat my-data/hello.txt # Produces error: `cat: my-data/hello.txt: No such file or directory`

We can use volumes and mounts to safely persist the data.

# create a named volume
docker volume create my-volume

# Create a container and mount the volume into the container filesystem
docker run  -it --rm --mount source=my-volume,destination=/my-data/ ubuntu:22.04
# There is a similar (but shorter) syntax using -v which accomplishes the same
docker run  -it --rm -v my-volume:/my-data ubuntu:22.04

# Now we can create and store the file into the location we mounted the volume
echo "Hello from the container!" > /my-data/hello.txt
cat my-data/hello.txt
exit
We can now create a new container and mount the existing volume to confirm the file persisted:

# Create a new container and mount the volume into the container filesystem
docker run  -it --rm --mount source=my-volume,destination=/my-data/ ubuntu:22.04
cat my-data/hello.txt # This time it succeeds! 
exit

Where is this data located? On linux it would be at /var/lib/docker/volumes... but remember, on docker desktop, Docker runs a linux virtual machine.

Demo containers

# Create a container from the ubuntu image
docker run --interactive --tty --rm ubuntu:22.04

# Try to ping google.com
ping google.com -c 1 # This results in `bash: ping: command not found`

# Install ping
apt update
apt install iputils-ping --yes

ping google.com -c 1 # This time it succeeds!
exit

Let's try that again:


docker run -it --rm ubuntu:22.04
ping google.com -c 1 # It fails! 🤔

It fails the second time because we installed it into that read/write layer specific to the first container, and when we tried again it was a separate container with a separate read/write layer!

We can give the container a name so that we can tell docker to reuse it:


# Create a container from the ubuntu image (with a name and WITHOUT the --rm flag)
docker run -it --name my-ubuntu-container ubuntu:22.04

# Install & use ping
apt update
apt install iputils-ping --yes
ping google.com -c 1
exit

# List all containers
docker container ps -a | grep my-ubuntu-container
docker container inspect my-ubuntu-container

# Restart the container and attach to running shell
docker start my-ubuntu-container
docker attach my-ubuntu-container

# Test ping
ping google.com -c 1 # It should now succeed! 🎉
exit
We generally never want to rely on a container to persist the data, so for a dependency like this, we would want to include it in the image:

# Build a container image with ubuntu image as base and ping installed
docker build --tag my-ubuntu-image -<<EOF
FROM ubuntu:22.04
RUN apt update && apt install iputils-ping --yes
EOF

# Run a container based on that image
docker run -it --rm my-ubuntu-image

# Confirm that ping was pre-installed
ping google.com -c 1 # Success! 🥳

Dockerfile

"a text document that contains all the commands a user could call on the command line to assemble an image"

Application recipe

  • Start with an operating system
  • Install language runtime
  • Install application dependencies
  • Setup execution environment
  • Run application

docker build

https://docs.docker.com/engine/reference/builder

dockerbuild

Lab/Demo

This lab shows how you can develop locally with a project that has multiple projects in it. Then create a release version of the Image to push to a production environment. This demonstration should be shown during Deck 2 and after slide 13.

Add Dockerfile

  1. Download the student version to the Downloads folder on the VM

  2. Extract downloaded file

  3. Open/Setup Docker

  4. Open VSCode and select extracted folder

  5. Explain to add the Dockerfile at the root where the solution file is

  6. Hand type the values into the Dockerfile while using the comments from the supplied file located here link to explain the steps as you type in the code

  7. After entering the values in the Dockerfile open a Terminal window. Shortcut is CTRL `

  8. Execute the following to

    docker build -t f1api .
    
  9. Debug if necessary

  10. Show deployed Image in Docker

    deployeddocker

  11. Ask students if they memorize all the commands yet

  12. Then open SLN file in Visual Studio 2022

  13. Right click API Project file. Add in Dockerfile automatically by selected Docker support

    docvkerfil

  14. Select Target OS as Linux

    targetlinux

  15. Show students the generated Dockerfile`

  16. Debug using Docker

    debug

  17. Visual Studio shows the running containers

    running containers

  18. Show the swagger interface automatically generated

    swagger 2

  19. Click on the Ports tab and show the exposed ports

    ports