What Is Docker?

Docker is a tool to build, deploy and run applications, on any platform irrespective of the infrastructure, with the use of containers. A container is a unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. Since docker packages all the dependencies of an application together with the required version, it solves the problem of having missing dependencies or version conflicts on developer’s local environment or production environment.

Docker Container

A docker container is a unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. A docker container is built from a docker image. Each container has its own binaries and libraries and will be run on the host OS itself.

Docker containers architecture

Docker containers architecture

Docker uses namespaces to isolate a container and limit the resources(CPU, Memory etc) that they consume. Namespaces are a feature of the Linux kernel that partitions kernel resources such that one container sees one set of resources while another container sees a different set of resources. When you run a container, Docker creates a set of namespaces for that container. These namespaces provide a layer of isolation. Some of the namespaces are pid for process isolation, net for managing network interfaces, ipc for managing resources for interprocess communication etc.

Docker Image

A Docker image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings. An image is a read-only template with instructions for creating a Docker container. An image is created from a dockerfile and contains a filesystem and the initial command that should the run when a container is run.

Docker Image Structure

Docker Image Structure

A docker image con consist of one or more layers, where each layer is an image in itself. Each layer except the very last one is read-only.

Writing A Dockerfile

Example of a Dockerfile for a simple node application:

FROM node:16-alpine 
WORKDIR /usr/app   
COPY . .                                    
RUN npm install 	
CMD ["npm", "start"]

Explanation:

  1. FROM command specifies the base package on top of which our files must be added. Alpine is a lightweight linux distribution and node:16-alpine is the alpine version with npm installed.
  2. WORKDIR sets the directory in the container’s file system into which our files must be installed. If working directory is not mentioned, it will be installed in root directory.
  3. COPY . . command copies all files from current local directory to the working directory of the container’s file system.
  4. RUN command runs npm install and installs all the dependencies mentioned in package.json into the working directory.
  5. CMD specifies the command which should be run when the container created from the image is run, called the startup command.

Build Steps: Creating Docker Image From Dockerfile

When building the dockerfile above, each line of command in the dockerfile creates an image (a layer) and the next command on the dockerfile works on the previous image and creates a new image.

Layers help in rebuilding docker images faster. Docker cache keeps track of information which has not been changed from the previous build and rebuilds the image layer from the point where the data has been changed. For example, in the given node application, if any of the dependencies has changed, only the npm install command (step 4) needs to run again. So rebuilding the dockerfile will only rebuild step 4 and 5. The images for steps 1-3 will be retrieved from docker cache.

Steps In Building A Docker Image

Steps In Building A Docker Image

  1. The FROM command starts out by creating a layer from the base image. This image with imageId 28fd30c24deb is then used by the 2nd step.
  2. A container is started with the image of step 1, added /usr/app directory to the filesystem, and a new image with this modified filesytem is generated. This intermediate container that was started is then removed.
  3. COPY/ADD command does not spin up a container as the buildkit used by docker supports built-in file operations during build, like copying files without having to run a container.
  4. RUN command starts up a container from the previous image, installs all the dependencies in package.json, and then created a new image. The intermediate container is removed.
  5. CMD command spins up a container from the pervious image, adds the initial startup command and then creates the final image layer.

Basic Docker Commands

  • Docker run <image-name> : Combination of create and start
  • Docker run -p 8080:8080 <image-name>
  • Docker run <image-name> <startup command to override>
  • Docker ps : Display all running containers
  • Docker ps -a : Display all containers
  • Docker create <image-name> : Creates a container
  • Docker start <container-id> : Runs the containers
  • Docker start -a <container-id> : -a stands for attach to the container, watch the output and print the output in the terminal
  • Docker exec -it <container-id> <command to run> : Run another command inside a running container, exec: execute
  • Docker exec -t <container-id> sh/zsh/bash : Getting into the shell
  • Docker logs <container-id> : Display all logs and output from running a container
  • Docker stop <container-id> : Stops the container by shutting down. If shutting down takes more than 10sec, falls back to kill command
  • Docker kill <container-id>: Stops the container immediately
  • Docker rm <container-id>
  • Docker system prune : Delete all containers and build cache