Complete Docker guide

·

6 min read

Docker

Containerization

Containerization is something which should be done when we want our application to run any machine with out any worry about the machine configuration and softwares installed.

This takes all the configuration of the application and build an image which runs in any machine which has Docker

Container will run in an isolated environment in an machine it doesnt have any connection with host machine . Its some kind of VM which runs and has its own file system

Docker is the first comer in this race which makes the thing hastle free

Docker check

After installing docker make sure that docker is successfully installed by running the below command

docker run hello-world

Cli Engine Registry

  1. CLI is one way to run docker containers with docker Cli

  2. Engine is the thing which runs undelying docker container and build images for docker (its is also called docker deamon)

  3. Registry is something like gitub where we can push images

Images vs containers

The Image is a template from which we can create the containers.

The Image is created using our code with all the dependencies included , It doesnt need any other external dependency

docker build .

This is the command used to build the image of a code . This is done in Dockerfile

Conatiner are something will be run from the image

Ex: image is like ISO file and container are like os we run , like with one ISO file we can run os in many systems, same way with one image we can run many containers

Structure

The first line is the base image on top of which we want to build our application , we can use ubuntu or our language node or golang

Second command is the working dir which means the in which dir the application exists and the command also changes the location to the workdir

The third command is copy . . (the dot means everything and second dot means everything to the workdir)

The fourth command is Run this is the command which runs any installation of any other type of commands

The fifth comnmand is expose , as docker is an isolated thing which need to expose something to host to know that its accepting the req at this port

This is the sixth command CMD , This command will run when the image is converted to container , All other command runs when image is built. This command is for runing the application

Docker build
docker build -t <somename>

The -t is tag name for the image

Run the image as container

docker run -p 3000:3000

-p is for port mapping from container is mapped to 3000 port of the host

first port is host second port is container's

pushing the docker image to docker hub

create repon in docker hub and get the tag name from there and build the image with that tagname and do docker push

docker push <tagname>

Docker pull

docker pull <tagname>

Caching and Layers

Docker does caching and layers

Layers: every statement in dockerfile is a layer

docker will cache all the layers

It will use the cached layer when there are no change while building

Lets say we have index.js and package.json

in the above dockerfile

first statment From Node:20 is cached it didnt change

but when we change index.js and rebuild it the build will run again for that

In that case package.json is not changes and npm install is running again so we can use below code so that first package json gets copied and npm install is done and then others are copied

In this case if there is any change in package json the docker will build it again else it will use cached layer ....

It has no dependency with index.js

  1. why layers

caching re using layers faster build time

Go inside container

docker exec -it <containerId> /bin/bash

kill container

docker kill <containerId>

Volumes and Networks

Volumes is used for database and auxilory services like kafka

This makes the data available even the container is down We can also use a folder for volumes

docker volume rm volume database
Networks

one container cannot talk to another container Every container has its own network container cannot talk to host machine or another container

We need to create a network to make one container talk to another

Bridge network: You would use a bridge network for most applications that need to communicate with each other, but do not need to access resources on the host machine. Host network: You would use a host network for applications that need to access resources on the host machine, such as a database or a web server. None network: You would use a none network for applications that need to be completely isolated from the outside world, such as a security-critical application. Overlay network: You would use an overlay network for applications that need to be deployed across a cluster of machines, such as a distributed database or a web application. Macvlan network: You would use a macvlan network for applications that need to have a specific MAC address, such as a virtual machine.

docker network create <netwrokname>

This will craete a anew bridge bridge newtork

docker run -p 3000:3000 --name backend --network my_custom_network <image_tag>

docker run -v volume_database:/data/db
--name mongo
--network my_custom_network
-p 27017:27017
mongo

Here we need to give sam netwrok with --network for the container which needs to talk to each other and with --name

The --name is imp because this name will be the part of connection string to other service which want to talk to this services. The name will act as the IP in the network . If we wan to connect to mongo container we will give mongo1 as name and in node api container we will give mongo1 as connection stirng befor the port number

Env variables

The -e takes the env variable

--env-file

The env file tag takes the env file itself rather than variables independently

Multi stage builds

We can take a base image and create multiple builds according to our envs such as prod or dev

as shown in below example

In the run command we should give target for dev or prod and :dev or :prod for which build we want to run

we can directly mount our system volume to the docker container when we svae the file the container runs

FROM node:20 AS base
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install

FROM base AS development
COPY . .
CMD ["npm", "run", "dev"]

FROM base AS production
COPY . .
RUN npm prune --production
CMD ["npm", "run", "start"]
Docker compose

when we have lot of auxilary soluitons in contaienr then we want to run multiple docker run commands , rather than this we can do the compose where we can declare all the things in a single file

docker run -d <tagname>

this is ditach mode which clears the console for us

when ever we start a docker compose all the container are connected by a network

services:
  mongodbi_db:
    image: mongo:latest
    ports:
      - "27017:27017"
    volumes:
      - mongodb-data:/data/db
  custom_app:
    build: ./
    ports:
      - "3000:3000"

volumes:
  mongodb-data:

Important : container talk to each other with container ner in same network

How to reduce size of docker image

  1. To use multi stage docker images

  2. To reduce the layers in dockerfile

  3. To use the scratch as base image