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: false
docker-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 .
-t
tags 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
--name
gives the container a nice name-p
maps the host port4000
to the container port80
- go to
localhost:4000
in your browser
ctrl + c
cancel process running in terminaldocker ps --all
to see all existing containersdocker start app
to start container againdocker stop app
to stop container
docker rm app
remove 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-network
docker run --name app -p 4000:80 --network my-network example-app
docker run --name redis --network my-network redis
- go to
localhost:4000
in 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
app
andredis
- 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
Dockerfile
for each component - Write a
docker-compose.yaml
including 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 6667
15MB 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