# Docker Notes #### Links [Introduction to Docker](https://www.youtube.com/watch?v=3c-iBn73dDE) [Dockerizing a React Application](https://mherman.org/blog/dockerizing-a-react-app/) ## What is Containerization? ## Difference between Containerization and Virtualization. #### Docker Compose `docker-compose` is used for defining and running multi-container applications, by defining all of the configuration in a single config file. #### Docker Machine `docker-machine` allows you to deploy your containerized applications on cloud. #### Docker Stack `docker-stack` allows you to manage a cluster of Docker containers with Docker Swarm. --- # Docker ## What is a Container? - A way to package application with all the necessary dependencies and configuration. - That package is portable just like any other artifact is, easily shared and moved around. - Makes development and deployment more efficient. - Layers of images. - Bottom Layer: mostly linux based image, because small in size. - Top Layer: application image on top. - Why docker containers are split into layers? - When we need to install another version of same app, only the layers that are same between both applications will be downloaded. ## Where do containers live? - In container repository, a special type of storage for containers. - Some companies have thier private repos. - Public repo `dockerhub` for Docker containers. ## How containers improved development process? - Before Containers, all developers had to install the tools on thier OS and configure it in their local environment. - Installation process was different for different OS. - Many Steps where something can go wrong. - With containers, you dont have to isntall any tools directly on OS. - It has its own isolated environment. - A container is packaged with all needed configuration. - One step to install the app. - Run same app with 2 different version. ## How containers improved Deployment process? - Before containers, Configuration on the server needed, install everything directly on the OS. - Dependency version conflicts. - Misunderstandings in Textual guide of deployment. - With containers, Developers and operations work together to package the application in a container. - No environmental configuration needed on server - except Docker Runtime. ## Docker Image vs Docker Container - Image is the actual package with all the configurations and dependencies, moveable around. - Container is when we pull that image on our local machine and starts it, the application in it starts and container environment is created. - Running environment for IMAGE. - port binded: talk to application running inside of container. - Container has its won abstraction of OS, the filesystem is virtual in container ## Docker vs VM - OS has two layers: Application and Kernel. ### Docker Containers - Docker virtualizes Application Layer of OS. - Size: Size is much smaller. - Speed: Start and run much faster than VM. - Compatibility: VM of any OS can run on any OS host but this is not the case with OS because each OS has different Kernel Layer. ### VM - VM virtualizes both Application and Kernel layer of OS. ## Container Port vs HOST Port - If we run 2 containers of an image both containers will run on same port (specified in image), then why there is no conflict if two apps are running on one port? - Multiple containers can run on your host machine. - PC has only certain ports available. - A binding is created between port of host and the container. - Conflict if 2 apps are opened at one port in host machine. - On the other hand, different containers running on same container port are bound to 2 different HOST Ports. - Once the port binding between host and container is already done, we can connect to the running container using the HOST Port. The host will then know how to forward the request to the container using the port binding. - If we dont do port binding then the container is unreachable. - We can do port binding by specifying the binding of the ports during run command. ## Docker Network - Docker creates its isonlated docker network, where the docker containers are running in. - When we deploy two containres in docker network, they cna talk to each other usng their names, without localhost, port number. - The applications that run outside of docker network, is going to connect to them from outside using localhost and port number. - Later when we package our application into its own docker image what we are going to have is a docker network containing those containers and the application that was communicating from outside in its own docker container. - By default docker provides some default networks. ## Docker Compose - With docker-compose file, we can take whole command with its configuration and map it into a file so that we have a structured command. - We dont have to add Docker network here, because docker-compse will handle it for us. It will create a common network for the containers that are talking to eachother. ```yaml version: "3" # version of `docker-compose` services: # list of containers mongodb: # container name image: mongo:latest # Image name ports: - 27017:27017 # Port Binding (HOST:CONTAINER) environment: - MONGO_USERNAME=admin mongo-express: image: mongo-express ports: - 8081:8081 environment: - MONGO_PASSWORD=admin ``` ## Dockerfile - To deploy the application, our application should be packaged in a Docker Container. So this means we have to build a Docker Image from our JS nodeJS application and prepare it to be deployed on some environment. - In order to build a docker imge from an application. We basically have to copy the contents of that application into Dockerfile and configure it. - We are going to use a blueprint for building images which is called a Dockerfile. - First line of every dockerfile is `FROM <image>`. Whatever image you are building, you have to base it on another image. - We can configure environmental variables inside our Dockerfile (optional, it is prefered to decalre env_vars in docker-compose-file), `ENV MONGO_DB_USERNAME=root MONGO_DB_PWD=password`. - After that, its `RUN <command>`, executed inside docker container, `RUN mkdir -p /home/app`. Using `RUN` we can execute any linux command. - Next is `COPY ./home/app` Coppy - executes on the HOST machine. Copy files from host to container. - `CMD["node","server.js"]` is always part of docker file. It executes an entrypoint linux command. - We can have multiple `RUN` commands but `CMD` is just one and tells docker that this is the entry point. ```dockerfile FROM node ENV MONGO_DB_USERNAME=admin MONGO_DB_PWD=password RUN mkdir -p /home/app COPY ./home/app CMD ["node","server.js"] ``` ## Docker Private & Public Repository - Create a private repository for Docker image, also called Docker Registry. - In AWS ECR, each image has its own repository and the repository containes different tags/versions of the same image. ## Docker Volumes - Docker volumes are used for data persistance. - For databases and other stateful applications. - Containers are stateless. When we restart or remove the container, data is gone. - The way Volume works is, we plug/mount HOST file system into Container's filesystem. - When a container writes to its filesystem, it automatically replicated to host's filesystem and vice versa. ### 3 Volume Types - Docker volumes can be added using `docker run -v HOST_DIR:CONTAINER_DIR`. This type of volume is called HOST Volume. We decide where on the host file system, the reference is made. - In second type, we only specify Container's directory. Docker automaticall generates directory on host file system and mounts it. These are called Anonymous Volumes. - Third volume type only specifies the name of host filesystem's directory, not the whole path. `docker run -v HOST_DIR_NAME:CONTAINER_DIR_PATH`. These are called Named volumes. # Commands ### Main Commands `docker ps` - Shows status of all running containers. `docker ps -a` - Lists running and stopped containers. `docker pull <image>:vesion` - Pull an image from docker hub. `docker rmi <imageId>` - Delete an Image. `docker rm <containerId>` - Delete a Container. `docker images` - Displays all existing images on PC. `docker tag <img> <newName>` - Rename an image. `docker start <containerId>` - Starts a stopped container. `docker stop <containerId>` - Stops a running container. `docker container ls` - List docker containers. `docker build -t <tag>:version .dockerfileLocation` - Create an image from Dockerfile. `docker push <image>` - Push Image to Docker Repository. #### Dcoker run Commands `docker run` - Creates a new container from image. `docker run <image>:version` - Combines `docker pull` and `docker start`. Runs a container of the image, checks if it is available locally, if not then it will pull the image from dockerhub. `docker run -d <image>:version` - Runs container in dettached mode. By default it runs in attached mode, if you exit cmd, the container will stop. `docker run -p<HOST_PORT>:<CONTAINER_PORT>` - Runs a container of the image, with port binding between host port and container port. `docker run --name contianerName <image>` - Runs a cintainer with a defined name (useful if you dont want to work with container IDs or want to differentiate between containers) of the image. `docker run -e ENV_NAME=value <image>` - Add Env Variables and run container. `docker run --net <image>` - Specify the docker network in whch the containre should be running. #### Docker Network Commands `docker network ls` - List docker networks. `docker network create <network-name>` - Create a new docker network. ```bash docker run -d \ --> run in detached mode -p 27017:27017 \ --> port binding HOST:CONTAINER -e MONGO_INITDB_ROOT_USERNAME=admin \ --> Set ENV -e MONGO_INITDB_ROOT_PASSWORD=password \ --> Set Env --name mongodb \ --> Container NAme --net mongo-network \ --> Docker Network to connect mongo --> Docker Image ``` ### Troubleshooting Commands `docker logs containerId:containerName` - To check what's happening in case the application crashes. `docker exec -it <containerId> /bin/bash` - Get the terminal of running container. ### Docker Compose Commands `docker-compose -f <filename>.yaml up` - Creates containers from a docker compose file.`up` starts all the containers. `docker-compose -f <filename>.yaml down` - Stop and Remove the containers and the docker network. ## Docker Volumes for Data Persistance