Skip to content

Instantly share code, notes, and snippets.

@andyrichardson
Last active February 9, 2021 12:09
Show Gist options
  • Save andyrichardson/78514a276cfc7cf3a346428bbd61eca8 to your computer and use it in GitHub Desktop.
Save andyrichardson/78514a276cfc7cf3a346428bbd61eca8 to your computer and use it in GitHub Desktop.

Docker 101

Grammar

  • server: A physical machine connected to the web
  • service: A deployed program (e.g. GraphQL endpoint / REST endpoint)
  • environment: The OS that a service runs in

Before docker

  • There was one environment on a server
  • These environments were mutable
  • They needed lots of maintenance (for security)
  • This meant their environment was constantly changing

This causes a number of problems.

Reproducability

  • How do we reproduce an environment that is constantly changing
  • Our code works in CI but might fail when deployed (different environnments)
  • An update/new package to the environment break our deployed service

Example:

== CI Run ==
Ubuntu 20.04
Node 12 

Tests run fine

== Deployment ==
Ubuntu: 20.04
Node: 12

Tests fail

Multiple services

  • A single environment could have many services
  • Services could have conflicting environment dependencies (e.g. node 12 and node 14)

Example:

== Service A requirements ==
Chrome: 67
Node: 12

== Service B requirements ==
Chrome: 64 (!)
Node: 12

Security

  • If one of our services has a vulnerability, all services are vulnerable
  • Malicious code on the server could attack all services
  • What is to stop one service from accidentally breaking another (e.g. deleting files)

Docker

  • A runtime for contained environments
  • Each service gets its own evironment
  • A single server can now run many environments

How it works:

  • Images are created prior to deploy time
  • These images can then be run on any machine with the Docker runtime
  • A running image, is called a container

How this solves the above problems:

Mutability

  • Environments are now declarative
  • They do not change over time
  • Any change to an environment would be the creation of a new image

Here's an example Dockerfile which is used to create a docker image

# Specify OS
FROM ubuntu:12.04

# Install OS dependencies to image
RUN apt install chrome@75 node@14

# Copy files to image
COPY . /app

# Run command
CMD [ "node", "/app/index.js" ]

Reproducability

  • Running an image on any machine will reap identical results
  • The only variables are network and compute performance/capability

Multiple services

  • Services are now contained
  • Containers cannot communicate with other containers without explicit permission
  • A vulnerable container will be an isolated incident
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment