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
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 processesdocker ps -a- show all processes, included those that have exiteddocker images- show a list of imagesdocker run- create a new container from an imagedocker stop- stop a running containerdocker 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
FROMand the image name & tag WORKDIRis like runningcdin your terminal. It sets the working directory to run subsequent commands inCOPYwill copy files from host (the machine this is running from) to the imageRUNwill run commands, so we copy thepackage.json, then install dependencies- NOTE: Docker commits each step as a layer, this is why we copy the
package.jsonfile 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 forpackage.jsonand the resulting deps.
- NOTE: Docker commits each step as a layer, this is why we copy the
ENVsets environment variablesEXPOSEwill expose specific ports TODO: add example aboveCMDwill run a command. This is different fromRUNbecause this is an entry point command. You only have one of these, but you can have multipleRUNsteps. 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> .
-tallows you to tag the image. The tag can have slashes, often used to applyregistryDomain/<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>
-pis port forwarding in the formatlocal:containerso the host machine's port5000would forward to8080in the container.-dwill 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