Skip to content

Practical example of using Docker for those who learn it

Notifications You must be signed in to change notification settings

ulexxander/docker-workshop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

38 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Docker Workshop

Practical example of using Docker for those who learn it.

Docker helps with:

  • Development
  • Testing
  • Deploying to any environment (stage, production)
  • Continuous integration and Continuous delivery
  • Quick start for new developers and contributors
  • ...and many other things...

Backend

Simple serice written in Go.

# Ensure you are in correct directory
cd backend
# Run test with in-memory NotesStore
go test -v . -store=memory

# Run test with MongoDB NotesStore
go test -v . -store=mongo
# Run locally
HTTP_SERVER_ADDR=:4000 go run main.go
# Build image so it can be run as container
docker build -t docker-workshop-backend .
# Run image (starts new container)
# --rm flag can be used to delete container after it stops
docker run docker-workshop-backend
# List all containers (-a means running AND stopped)
docker ps -a
# Remove container
docker container rm <container_id>

Frontend

Minimal page built using React. Project was created with command yarn create vite docker-workshop --template react-ts

# Ensure you are in correct directory
cd frontend
# Build image so it can be run as container
docker build -t docker-workshop-frontend .
# Run frontend container
# -p <host>:<container> stands for port forwarding
# it makes port 80 inside container available on host port 3000
# so you can open http://localhost:3000 and see the application
docker run --rm -p 3000:80 docker-workshop-frontend

Traefik and docker-compose

Traefik is an open-source Edge Router that makes publishing your services a fun and easy experience. It receives requests on behalf of your system and finds out which components are responsible for handling them.

Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration.

docker-compose.yml defines 3 services:

  • traefik - accepts all http requests and forwards them based on domain, it also has its admin dashboard
  • backend - our backend image that has port 80 exposed (see Dockerfile) and labels defined so traefik can proxy it
  • frontend - our frontend image that calls /api endpoints which are fulfilled by backend
# Run whole stack (make sure you have images already built)
docker-compose up -d

Open traefik dashboard: http://traefik.localhost

Backend is exposed at standalone domain: http://backend.docker-workshop.localhost or at http://frontend.docker-workshop.localhost/api

Frontend is served at http://frontend.docker-workshop.localhost

MongoDB

When we have docker-compose adding new containers is very easy.

Few specifics of database containers:

  1. We probably don't want our containers to be exposed to the rest world - we don't forward ports and we don't need to configure reverse-proxy for them.
  2. We may still use ports forwarding during development (database runs inside docker container, but our app usually runs on localhost)
  3. Database containers save state to filesystem - to persist that data reliably we should use Docker volumes.
  4. We want our backend apps to run on same Docker network with database containers, so we can connect them using hostnames and exposed (not forwarded) ports.

Deploying to production

Because we have all our infrastructure defined in docker-compose.yml file - it is all we need to run our stack!

Except images - some of them are public (traefik, mongo) and some of them are our custom images (docker-workshop-backend, docker-workshop-frontend).

Public images are pulled from Docker Hub. Our images were available only locally (we produced them with docker build).

So to pull our custom images in production environment we first need to push them to some registry (just like with git)

We have more options:

We will store images in Docker Hub in this workshop.

# Build images that will be published
cd backend
docker build -t ulexxander/docker-workshop-backend:1.0.0 .
cd ../frontend
docker build -t ulexxander/docker-workshop-frontend:1.0.0 .
# Authenticate to the images registry, you will be prompted for username and password
docker login
# Push images to the registry
docker push ulexxander/docker-workshop-backend:1.0.0
docker push ulexxander/docker-workshop-frontend:1.0.0
# Now we can pull images anywhere registry is accessible!
# Like on our production environment!
docker pull ulexxander/docker-workshop-backend:1.0.0
docker pull ulexxander/docker-workshop-frontend:1.0.0

Workshop Checkpoints

You can follow progress with git checkout <hash>

Commit Message Hash
prepared Dockerfile for backend and explained docker commands in README 71fe95659f05f057bd6a26bc24c3345481fd8c6b
frontend Dockerfile and more docker commands in README 4d488562d2b0d726ad5f00bcc8eaff7602c5c129
simple docker-compose to run both backend and frontend 709d8ab1e40f7a7f85c76fbaf16b7d7526f707ca
readme - added Traefik and docker-compose section 2af80721db0122b046bbd4bf3da3cdcf67cfa0a3
backend - implemented NotesStore backed by mongodb and tested it 41b520aaf297ee9a90e77ab8fea81575c6029b39
docker-compose mongo service - added volume to persist database 7a974019c97bc8f353ead1f0a39b40d9da1eab98
readme backend - Run locally note eed43c7b9c2317c0525b6514bfbeab66601978f1

About

Practical example of using Docker for those who learn it

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published