Docker

Updated: 2021-11-19

What is Docker

When we talk about Docker, usually we are referring to Docker Engine, which consists of

  1. the Docker daemon (dockerd)
  2. a REST API that specifies interfaces for interacting with the daemon
  3. a command line interface (CLI) client (docker) that talks to the daemon (through the REST API wrapper), e.g. docker run <image>, docker image ls.

Because Docker operates at the OS level, it can still be run inside a VM!

2 most important APIs: Images and Container APIs

Docker Compose vs Docker Stack

  • docker-compose: a tool for defining and running multi-container Docker applications; a separate tool built in Python, internally uses the Docker API to bring up containers according to the specification
  • docker stack: built-in docker CLI, no additional packages needed; written in Go; (successor of docker-compose?)
  • both works with docker-compose.yml, however docker stack only works with version 3.

Docker for Mac

The Docker for Mac application does not use docker-machine to provision that VM; but rather creates and manages it directly.

CMD vs ENTRYPOINT

Both CMD and ENTRYPOINT instructions define what command gets executed when running a container. There are few rules that describe their co-operation.

  • Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
  • ENTRYPOINT should be defined when using the container as an executable.
  • CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container.
  • CMD will be overridden when running the container with alternative arguments.

Run Docker Engine

$ sudo dockerd

Network

List networks:

$ docker network ls

DRIVER:

  • null: the container does not have external network interfaces, only a local loopback interface.
  • host: the container is attached to the host's network, the configs inside the container matches the configs outside the container.
  • bridge: containers connected to the same bridge network can communicate; containers on different bridge networks cannot communicate directly with each other.

To get more details:

$ docker network inspect bridge

Dockerize a Node app

Use this Dockerfile template:

# node
FROM node:12-slim

# the path inside the container
WORKDIR /usr/src/app

# copy the package.json and package-lock.json, and install dependencies
COPY package*.json ./
RUN npm install

# copy all the source code
COPY . .

# port
EXPOSE 8080

# run the command inside the container
CMD [ "node", "app.js" ]

And add a .dockerignore file:

Dockerfile
.dockerignore
node_modules
npm-debug.log