Published on

Docker Quick Start Guide

Authors

Getting Started with Docker CLI

docker run

Let's start with the most basic docker command and go from there

docker run <dockerImageName>

The most basic example of this is

docker run hello-world

If you have Docker setup properly, you will see a block of text outputted to STDOUT

The docker run can also take Docker Image params and pass them on i.e,

docker run busybox echo extra cmd args

The busybox docker image is just an image with a basic linux filesystem that allows you to run basic commands such as pwd,ls, etc...

If you ran the following command you should have seen the following output

extra cmd args

The Docker Image above simply took those params and ran them in the container.

Diving Deeper in docker run

The docker run command is actually composed of 2 seperate docker commands

Command #1 $ docker create <dockerImageName>
Command #2 $ docker start -a <dockerImageId (output from command#1)>

These 2 commands tie into the Docker Container Lifecycle.

Command #1 gets that filesystem snapshot aka image ready to be consumed. It essentially allocates the memory space needed for it to run.

Command #2 starts the script that is inside the image. In the helloworld case it's that script that outputs a block of text.

If you were to run the docker start without the -a flag your container will be running in the background. The -a flag or --attach allows you to run your container in the foreground with access to the containers STDOUT.

docker start and docker ps

If you have actively running in the background you can run docker ps this will list all running containers in the following format

CONTAINER ID   IMAGE     COMMAND      CREATED          STATUS          PORTS      NAMES

If you want to see all actively running and terminated containers then docker ps --all will display that.

you can restart terminated containers using the start command and the listed containerId i.e, docker start CONTAINER_ID. Keep in mind the restarted container won't contain any new script changes, it will simply just restart the container

If you want to clean your Docker process history and free up some space then run docker system prune. Keep in mind this will also deleted any cached images you have from the Docker Hub which will require a redownload upon next run.

docker logs

you can retrieve STDOUT logs of containers running in the background or foreground using the docker logs CONTAINER_ID

docker stop and docker kill

you can gracefully terminate a container usign the docker stop CONTAINER_ID command as this will send a SIGTERM to the Linux Kernel. If the container takes longer than 10s to terminate then Docker will also send a SIGKILL to the kernel

If you want the container to terminate without any clean up then use docker kill CONTAINER_ID as this will send a SIGKILL and terminate the process immediately.

Multi-Command Containers and docker exec

Let's say you want to spin a container and then run some commands inside it...

you can spin up a container using the commands listed above but to communicate with the container you will need to use the docker exec <CONTAINER_ID> <script/cmd> command. This command will run the param in the background.

If you want access to the container's STDIN then run the exec command along with with the interactive flag and the t flag i.e, docker exec -it.

If you have a running container and you would like to access the shell inside that contrainer you can combine the exec command along with the sh (shell) command like so

docker exec -it <CONTAINER_ID> sh

You can also use both the exec and sh commands with docker run. This will give you the ability to start a docker shell with a shell. Keep in mind, this will not allow you to run any other command/script after sh executes. All extra commands will need to be run in the container's shell. Example command is listed below.

docker run -it busybox sh

Creating a Docker Image

To create a Docker Image, you

  1. start off with a configuration file aka your .Dockerfile this docker file is then

  2. feed into the Docker Client which can be the Desktop App or the CLI.

  3. The Docker client then sends this file to the Docker Server. The Docker Server does all the heavy lifting of compling your Dockerfile and producing a usable Docker Image.

Dockerfile Breakdown

All Dockerfiles start off with a

  1. Base image. You must specify a base image to work off of as this will be the foundation for your env.
  2. After you have your base image then you need to see what additional commands/programs/instrutctions you need to get everything working together.
  3. Lastly, you have to specify what command to run when your container starts up. Basically a command for the entry point.

Example Dockerfile:

Dockerfile
# Use base image
FROM alpine

# Download Dependecies
RUN apk add --update redis

# Start command
CMD ["redis-server"]

To build a Dockerfile run docker build . This command will out put an id or a sha. This can be combersome to keep track of but luckily you can tag every build as follows

docker build -t authorNameAKAdockerID/projectnName:version .

Dockerfile Compilation

If you read through the build output when running the build command, you will notice that each of those 3 steps FROM RUN CMD run seperately.

For each step, docker creates an intermediary container that runs for each of those steps. Each container is saved and used to build upon the next step in the file.

This introduction of intermediary containers during the build process has the added benefit of speeding up build times due to caching.

When the Dockerfile changes, the build process see from what line did the change happen, it will reuse all the cached intermediary containers before the changed line and build onto those.

To test this out, try adding a line after the first RUN like so

Dockerfile
# Use base image
FROM alpine

# Download Dependecies
RUN apk add --update redis
RUN apk add --update gcc

# Start command
CMD ["redis-server"]

If you build this new Dockerfile, you will notice that the first 2 lines were cached and the rest of the file was rebuilt.

Pro tip: to speed up build times, keep your changes at the bottom of the file as this will allow for max reuse of cached containers.