Docker concepts


Container: A runnable, isolated instance of an image

Image: A container's filesystem

Volume: Used to pass information into or persist data for our application. See below for examples.


The docker build command uses a Dockerfile to build a new container image. Using -t tags the image with a human readable tag. The final '.' tells it to look for the Dockerfile in the current folder.

docker build -t getting-started .

Running a container

You have to run your new container in order to access it - something like this connects port 3000 on localhost to port 3000 on the container...

docker run -dp 3000:3000 getting-started

Networking containers

First, we create the network.

Next we start our container and connect it to that network, making sure to assign a network alias. Note that '-e' defines environment variables for the new container.

-v is used to define a volume - in this case pointing to a subfolder of /var/lib - Docker will automatically create a named volume with this command.

docker network create todo-app

docker run -d \

--network <network name> \

--network-alias <network alias> \

-v <volume name>:/var/lib/<volume location> \

-e SOME_PASSWORD=secret \

-e SOME_USERNAME=username \


Working with containers

Random container commands can be ran using

docker exec -it <container name> <command>

For example, you could connect to a mySQL shell running within a container as:

docker exec -it <mysql-container-id> mysql -u root -p

Watch the logs with docker logs -f <container-id>

Watch logs from a docker compose instance with docker compose logs -f <app>

Check on running containers with docker ps

Working with volumes:

docker run -dp 3000:3000 \

-w /app -v "$(pwd):/app" \

node:18-alpine \

sh -c "yarn install && yarn run dev"


  • -dp 3000:3000 - same as before. Run in detached (background) mode and create a port mapping

  • -w /app - sets the “working directory” or the current directory that the command will run from

  • -v "$(pwd):/app" - bind mount the current directory from the host into the /app directory in the container

  • node:18-alpine - the image to use. Note that this is the base image for our app from the Dockerfile

  • sh -c "yarn install && yarn run dev" - the command. We’re starting a shell using sh (alpine doesn’t have bash) and running yarn install to install all dependencies and then running yarn run dev. If we look in the package.json, we’ll see that the dev script is starting nodemon.