theme: Courier, 6
[.build-lists: true]
- Why Docker
- Installation
- Basics of docker
- Containers in depth
- Networks
- Volumes
[.build-lists: true]
- Docker-Compose
- Excercise with own projects
- Useful tricks
- Pitfalls when using Docker
[.build-lists: true]
- Reproducibly installing dependencies
- Development very close to production
- Easily deploying apps
- Ecosystem of useful, shared components
- Little overhead
##[Fit] docs.docker.com/install/
##[Fit] docs.docker.com/compose/install/
$ docker version
Client: Docker Engine - Community
Version: 18.09.2
API version: 1.39
Go version: go1.10.8
Git commit: 6247962
Built: Sun Feb 10 04:12:39 2019
OS/Arch: darwin/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 18.09.2
API version: 1.39 (minimum version 1.12)
Go version: go1.10.6
Git commit: 6247962
Built: Sun Feb 10 04:13:06 2019
OS/Arch: linux/amd64
Experimental: falsedocker-compose --version
docker-compose version 1.23.2, build 1110ad01[.build-lists: true]
- Blueprint
- Contains everything necessary to run an application
- A layered, read-only File System
[.build-lists: true]
- Enable caching of shared requirements
- Each layer has a globally unique id
- only changed layers need to be pushed/pulled
[.build-lists: true]
- Contains application state
- Thin read/write layer
# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
# ignore files specified in .dockerignore
COPY . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -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"]FROM <image>
Specifies what image to use as a base
COPY <host path> <image path>
Copy file/directory from host directory to directory in image layer
RUN <command>
Runs the given command in a container
All changes to the filesystem are stored in a new image layer
[.build-lists: true]
docker build -t example-app .
-ttags the image with a nice name- use
.as the build context directory -> the host root path used forCOPY
[.build-lists: true]
docker run --name app -p 4000:80 example-app
--namegives the container a nice name-pmaps the host port4000to the container port80- go to
localhost:4000in your browser
ctrl + ccancel process running in terminaldocker ps --allto see all existing containersdocker start appto start container againdocker stop appto stop container
docker rm appremove containerdocker run --rm ...would have automatically removed the container after it is stopped -> especially helpful for stateless containers
-> no calls to things running on the host -> no calls to other containers
[.build-lists: true]
- containers can share networks
[.build-lists: true]
docker network create my-networkdocker run --name app -p 4000:80 --network my-network example-appdocker run --name redis --network my-network redis- go to
localhost:4000in your browser
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)How do I remember all of these commands?
[.code: auto(1)]
version: "3"
services:
app:
build: .
ports:
- "4000:80"
redis:
image: redis
ports:
- "6379:6379"
volumes:
- "./redis-data:/data"
command: "redis-server --appendonly yes"Will handle everything:
- creates the containers
appandredis - containers are part of the same network
- containers have the correct host ports bound
volumes:
- "./redis-data:/data"-> Slower than normal writes to disk
-> all data gone
-> No overhead in writing -> Data persists after a container was destroyed
docker run ... -v "$(pwd)/redis-data:/data" redis
[.build-lists: true]
- Pick one of your projects
- ideally with some kind of Database
- or just use this
- Write a
Dockerfilefor each component - Write a
docker-compose.yamlincluding all services
- What is my app supposed to do?
- Is there an appropriate Base Image?
- What dependencies do I need?
docker run -d ...
Run docker container in background
docker history <container name>
Examine size of each layer of the container
docker exec -it <container name> /bin/bash
Get an interactive terminal inside a running container
# use the golang dev image to compile binary
FROM golang:1.11 as builder
WORKDIR /go/src/github.com/alexmorten/mhist
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o mhist main/main.go
# use the stripped down alpine image
FROM alpine:latest
RUN apk --no-cache add ca-certificates
RUN mkdir app
# Copy the binary from the builder stage
COPY --from=builder /go/src/github.com/alexmorten/mhist/mhist /app
WORKDIR /app
CMD ["./mhist"]
EXPOSE 6666 666715MB tiny image
-> --network host will refer to the VM
-> carries performance overhead of a VM + Docker
Normally localhost is an alias for 127.0.0.1
Alpine images don't have that alias
Normally the OS contains ca-certificates to validate TLS certificates from servers for https calls
-> ... you should RUN apk --no-cache add ca-certificates
Docker Installation:
docs.docker.com/install/
docs.docker.com/compose/install/
Example repo
github.com/alexmorten/docker-example
Slides:
docker.alexmorten.info (PDF)
github.com/alexmorten/docker-workshop-presentation


