Docker?

  • Docker is a tool used for bundling together everything needed for a piece of code to run, into an image
  • It can later use this image to take care of running the code. It takes care of installing all dependencies, starting running it (and even making sure it keeps running)

Why docker?

  • No more "it works on my machine" - because docker can create environments that are identical to the developer machine, so it always works :D
  • Share it with your friends - Create images, share it with your frends; now they can also self-host your work. yay!
  • No more messing up your system because of one wrong command and not knowing how to fix it. Just remove the container and make a new one

Installing Docker

  • Installing Docker with apt

    apt install docker.io
    
  • Verify the docker installation is working with

    sudo docker run hello-world
    
  • To use docker without sudo, add the non-root user (if3) to the docker group

    sudo gpasswd -a if3 docker
    

    Note: Need to logout and log back into the VPS for this change to take effect

Dockerfile

A Dockerfile is a file containing all the instructions needed to build an image

A simple Dockerfile

  • Create a file with the name Dockerfile

    nano Dockerfile
    

    and add these two lines to the file:

    FROM debian:12
    ENTRYTPOINT "echo" "Hello, World!"
    
  • An image can be built from this Dockerfile with the command

    docker build <directory containing the Dockerfile> -t <tag>

    docker build . -t if3-hello-world
    
  • All available images can be seen using docker image ls

    $ docker image ls
    REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
    if3-hello-world   latest    128a133d9ac4   11 minutes ago   117MB
    debian            12        676aedd4776f   2 weeks ago      117MB
    
  • A container can be created and started with docker run ...

    $ docker run if3-hello-world
    Hello, World!
    

Simple, but in style - another Dockerfile

  • Edit the Dockerfile like below
    FROM debian:12
    -ENTRYPOINT "echo" "Hello, World!"
    +RUN apt-get update
    +RUN apt-get install figlet -y
    +ENTRYPOINT "figlet" "Hello, World!"
    
  • Save the file and build a new image. Let's call the new image if3-hello-world-figlet
    docker build . -t if3-hello-world-figlet
    
  • Start a container with the new image
    $ docker run if3-hello-world-figlet
     _   _      _ _         __        __         _     _ _ 
    | | | | ___| | | ___    \ \      / /__  _ __| | __| | |
    | |_| |/ _ \ | |/ _ \    \ \ /\ / / _ \| '__| |/ _` | |
    |  _  |  __/ | | (_) |    \ V  V / (_) | |  | | (_| |_|
    |_| |_|\___|_|_|\___( )    \_/\_/ \___/|_|  |_|\__,_(_)
                        |/
    

A Python web app with Docker

  • clone the figlet-web repository
    $ cd -
    $ git clone https://github.com/anandology/figlet-web
    
  • Writing a Dockerfile
    $ cd figlet-web
    $ nano Dockerfile
    
    Dockerfile:
    FROM python:3
    WORKDIR /app
    RUN apt update
    RUN apt install figlet -y
    COPY . .
    RUN pip install -r requirements.txt
    CMD [ "gunicorn", "--bind", "0.0.0.0:8080", "webapp:app" ]
    
  • Building the image
    $ docker build . -t figlet-web
    
    $ docker image ls
    REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
    figlet-web   latest    d0fbac841345   31 seconds ago   1.09GB
    python       3         17e65561fd2c   11 days ago      1.02GB
    
  • Now that the image is built, it can be ran with docker run ...
    $ docker run figlet-web
    
  • Now the app should be running and should be accessible from the browser. goto http://HOSTNAME_IN_CHIT.i10e.xyz:8080 to see it.
  • Not seeing anything? We need to ask docker to let us see what's on port 8080
  • use Ctrl+C to stop your the running container

    -p <host port>:<container port> flag for the docker run ... command gives access to the <container port> from <host port> on the host.

    $ docker run -p 8080:8080 figlet-web
    

    use docker run ... -d if you want to continue using the terminal, or don't want the app to stop if you press Ctr+C. -d stands for detach. it tells docker to detach from the terminal and run in the background once the container has started.

  • Try again by visiting http://HOSTNAME_IN_CHIT.i10e.xyz:8080
  • How to remove that ugly :8080 at the end? For that, we have to tell caddy to do its magic
  • Update the Caddyfile, /etc/caddy/Caddyfile so it knows where out docker python app is.
    +figlet-web-docker.HOSTNAME_IN_CHIT.i10e.xyz {
    +  reverse_proxy :8080
    +}
    
    and reload Caddy with sudo systemctl reload caddy.service
  • Enjoy your app at https://figlet-web-docker.HOSTNAME_IN_CHIT.i10e.xyz
  • How to see all my running containers? what if I want to stop one of them?
    $ docker ps
    
  • To stop any of them, we need the container id show by docker ps
    $ docker stop <container id>
    

    If you're too lazy to look for and remember the gibberish id everytime, use docker run ... --name "cool_name" when starting the container. Now you can use cool_name instead of the id. Yay!

Docker Compose

What is Docker compose?

  • It's a way to automate the docker run ... commands. YOu can write everything needed in a file called docker-compose.yaml and with a single command the containers.
  • You can add multiple containers to a single docker-compose.yaml and they all can be started/stopped together
  • no need to remember long and complex docker run ... commands

Installing Docker Compose

  • docker-compose can be installed with apt
    $ sudo apt install docker-compose
    
  • a new command called docker-compose should be available

In newer versions of Docker, this step is not needed as docker compose is available with the docker installation. Debian smh.

Using Docker Compose

  • To use docker-compose, we need to write a new file called docker-compose.yaml for our app
  • Go to the figlet-web repo we cloned earlier and open you favorite text editor
    $ cd -
    $ cd figlet-web
    $ nano docker-compose.yaml
    
  • Add these lines
    version: "3"
    services:
      figlet_web:
      image: figlet-web:latest
      build: .
      ports:
       - 8081:8080
    
  • Build the image using docker-compose
    $ docker-compose build
    
  • Start the container
    $ docker-compose up
    

    use docker-compose up -d if you want to continue using the terminal, or don't want the app to stop if you press Ctr+C. -d stands for detach. it tells docker compose to detach from the terminal and run in the background once the app has started.

  • Now the app should be running and should be accessible from the browser. goto http://HOSTNAME_IN_CHIT.i10e.xyz:8081 to see it.
  • Again, we need to remove the :8081 at the end.
  • Update the Caddyfile, /etc/caddy/Caddyfile so it knows we want to see the new docker compose app instead.
    figlet-web-docker.HOSTNAME_IN_CHIT.i10e.xyz {
    -  reverse_proxy :8080
    +  reverse_proxy :8081
    }
    
    and reload Caddy with sudo systemctl reload caddy.service
  • Enjoy your app at https://figlet-web-docker.HOSTNAME_IN_CHIT.i10e.xyz
  • Stopping the container
    $ docker-compose down
    

What is Docker Registry?

  • How to share your application images with you friends?
  • Docker Registries let you publish your images to a public repository, from where anyone can download it and use
  • Some examples: Docker Hub, Github Container Registry and many more