Learning Docker

I’m re-learning Docker after 7/8 years or so of not using it 😬. These are some of my rough notes.

What Is It?

  • Package software to run on any hardware
  • Runs your code & the required environment in a container
  • Environments are easily and consistently reproduced

Installing

Docker

Get Docker

I’m using Docker Desktop for Mac. Installing this installs all the needed CLI tools, as well as a UI for seeing processes, inspecting them, and shutting them down.

Tools

Docker VSCode extension from MSFT

Basic Terminology

Dockerfile

This is the instructions, or blueprint for creating an Image

Image

This is the actual artifact that can be moved/shared/published to a repo.

It contains the linux distro, applications, source code, etc.

An image is the output generated from the Dockerfile.

Container

This is a running environment for an image.

Core Commands

  • docker ps - show running processes
  • docker ps -a - show all processes, included those that have exited
  • docker images - show a list of images
  • docker run - create a new container from an image
  • docker stop - stop a running container
  • docker start - start an existing container

Dockerfile

Create the Dockerfile in the root of your project.

# source image to build from
FROM node:16-alpine

# working directory in the container
WORKDIR /usr/server/app

# copy files from host to container
COPY ./package.json ./

# run npm install to install dependencies in the container
RUN npm install

# copy files from host to container
COPY ./ .

# build the app in the container
RUN npm run build

# set the NODE_ENV to production
ENV NODE_ENV=production

# start the app in the container
CMD ["npm", "start"]
  • Start from a base image with FROM and the image name & tag
  • WORKDIR is like running cd in your terminal. It sets the working directory to run subsequent commands in
  • COPY will copy files from host (the machine this is running from) to the image
  • RUN will run commands, so we copy the package.json, then install dependencies
    • NOTE: Docker commits each step as a layer, this is why we copy the package.json file and install deps before copying the rest of the source code. If our source changes, but the deps don’t, spinning up the container will be faster since it will rely on cached layers for package.json and the resulting deps.
  • ENV sets environment variables
  • EXPOSE will expose specific ports TODO: add example above
  • CMD will run a command. This is different from RUN because this is an entry point command. You only have one of these, but you can have multiple RUN steps. This is the thing that starts your server/database/whatever

.dockerignore

You should also add a .dockerignore file to the project root. This works just like a .gitignore file and excludes certain files from COPY operations in the Dockerfile.

Building the Image

NOTE: You’ll want to make sure the

docker build -t <username/tag>:<version> .

  • -t allows you to tag the image. The tag can have slashes, often used to apply registryDomain/<ACTUAL TAG> with an optional version added on with a colon.
    • registryDomain/tag will come into play when pushing to your account on Dockerhub
  • . This is the path, in this case, just the current working directory on the host machine.

Running a Container

docker run -p 5000:8080 -d <imagename-or-id>

  • -p is port forwarding in the format local:container so the host machine’s port 5000 would forward to 8080 in the container.
  • -d will run the container in “detached” mode.

Pushing the Image to a Repo

Not a git repo, but something like Dockerhub or AWS ECR (Elastic Container Registry)

TODO: docker push information

Pulling an Image from a Repo

TODO: docker pull information

Docker Compose

Using compose allows you to


Resources

Docker Best Practices video