Skip to main content

Container Training

This assignment assumes that you have basic knowledge of the following topics.

  • Go (Programming Language)
  • Docker

If you're not familiar with the mentioned topics, please checkout beginner tutorials. For Docker, please read brief guide to containers and checkout this video for a comprehensive tutorial.

Goal

  • Understanding container technology from Docker, Kubenetes, and Helm.
  • Able to create a k8s development environment using Tilt

Tools

All tools used in this assignment are listed below

  • go 1.21.1
  • Docker
    • Docker Engine 24.0.6
    • Docker Compose 2.21.0
  • Kubernetes 1.28
    • minikube v1.31.2
  • Tilt v0.33.5

Assignment 1: Use PostgreSQL instead of SQLite

You've been using SQLite as your database in the last assignment. In this assignment, we'll change from SQLite to PostgreSQL server.

  1. Start PostgreSQL server using the docker image (https://hub.docker.com/_/postgres)
  2. Try to use your Pokedex application with the new database.

Assignment 2: Create a Pokedex Docker Image

  1. Create a Dockerfile: In your Pokedex application's root directory, create a file named Dockerfile without any file extension. This file will define the steps to build your Docker image.
# Use the official Go image as the base
FROM golang:latest AS builder

WORKDIR /app

# Copy the application code into the container
COPY . .

# Build the Go application
RUN go build -o pokedex-app

# Create a minimal runtime image
FROM debian:buster-slim
WORKDIR /app

# Copy the binary from the builder image
COPY --from=builder /app/pokedex-app .

# Command to run the application
CMD ["./pokedex-app"]
  1. Build the Docker Image: Open a terminal, navigate to your application's directory (where the Dockerfile is located), and execute the following command:
docker build -t pokedex-app .

This will create a Docker image named pokedex-app based on the Dockerfile.

note

Don't forget to rebuild an image every time a change is made to the code! This is one of the mistakes beginners make when they start using container technology.

Assignment 3: Deploy Pokedex and Postgres using Docker Compose

  1. Create a Docker Compose File: Create a file named docker-compose.yml in your application's directory to define the services.
version: '3'
services:
pokedex-app:
image: pokedex-app
ports:
- '8080:8080' # Map the host port to container port
depends_on:
- postgres
postgres:
image: postgres:latest
ports:
- '5432:5432' # Map the host port to container port
environment:
POSTGRES_USER: pokedex
POSTGRES_PASSWORD: password
POSTGRES_DB: pokedex_db
note

The ports here may be different depending on your pokedex application! However, note that the default port for Postgres image is 5432. You can check that by looking the official Postgres Dockerfile.

The keyword EXPOSE 5432 (in the official Dockerfile) specify the port that postgres will listen on inside a container. This means that the second number of the port has to be 5432 (unless you explicitly change the default port yourself!)

  postgres:
ports:
- "(this_can_be_any_valid_port_number):5432" # Map the host port to container port
...
  1. Start the Services: Open a terminal in your application's directory and run:
docker compose up

This will start the Pokedex application and PostgreSQL database. We can check whether our service starts properly or not through curl command

$ curl 'http://localhost:8080/query' -X POST  -H 'content-type: application/json'  --data-raw '{"query":"query{  pokemons{    id    name    description    category  type{ name } abilities { name }}}"}' | json_pp

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 5511 0 5406 100 105 3096k 61583 --:--:-- --:--:-- --:--:-- 5381k

{
"data" : {
"pokemons" : [
{
"abilities" : [
{
"name" : "Static"
},
{
"name" : "Lightning Rod"
}
],
"category" : "Mouse Pokemon",
"description" : "Pikachu is an Electric type Pokemon introduced in Generation 1",
"id" : 1,
"name" : "Pikachu",
"type" : [
{
"name" : "Electric"
}
]
}
]
}
}

Alternatively, you can use GraphiQL to check the result. GraphiQL tutorial is provided in a separate section.

Next step with kubernetes

Useful resources

  • If you need a little Docker refresher, we recommend you following this official tutorial. It goes over the basics: writing a Docker file, building an image, and running a container.
  • 10 mins Docker Compose Tutorial
  • Docker vs VM, optional read.

Note for (absolute) beginners

If you are lost and not sure where to start, we suggest the following steps:

  1. Learn what Docker/Containerization is, why do we need it?
  2. Watch the suggested video tutorial.
  3. At this point, you should at least know some Docker terminologies (i.e. Docker Image, Container, Docker file etc). Now, start experimenting with these! Make your own Docker file, build an image, and run your container. The official tutorial is provided in the above section, useful resources.
  4. Start assignment 1.
  5. After previous step, you should have a Postgres container running (run an image to get a container). Next, we will turn your GO code into another container. This will be done in assignment 2.
  6. At this stage, we will have two containers running, but right now they don't know each other... Our goal is to have both containers talking to each other (GO code should be able to access Postgres data). This is where Docker-compose comes into play. This is assignment 3.