# Docker

Docker is a tool that makes it easy to run applications in containers.  
Containers are like small packages that hold everything an application needs to run. To create these containers, developers use something called a Dockerfile.

A **<mark>Dockerfile </mark>** is like a set of instructions for making a container.  
It tells Docker what base image to use, what commands to run, and what files to include.  
For example, if you were making a container for a website, the Dockerfile might tell Docker to use an official web server image, copy the files for your website into the container, and start the web server when the container starts.  
  
**Docker Files Contents:-**

`FROM`:- For the base image. This command must be on top of the docker file.

`RUN`:-To execute commands, it will create a layer in the image.

`MAINTAINER`:- author/Owner/Description

`COPY`:-Copy files from the local system (dockerVM) we need to provide a source, and destination. (We can’t download the file from the internet and any remote repo)

`ADD`:-Similar to copy, it provides a feature to download files from the internet, also we extract the file from the docker image side.

`EXPOSE`:- To expose ports such as port 8080 for tomcat, port 80 for Nginx, etc…

`WORKDIR`:- To set a working directory for a container.

`CMD`:- Execute commands but during container creation.

`ENTRYPOINT`:- Similar to CMD, but has higher priority over CMD, the first commands will be executed by ENTRYPOINT only.

Docker is made up of several components that work together to enable the creation, deployment, and management of containerized applications.  
Here are the main components of Docker:

1. **Docker daemon**: The Docker daemon is the core component of Docker that runs on the host operating system and manages Docker images and containers. It listens for Docker API requests and handles the creation, deletion, and management of Docker objects such as images, containers, networks, and volumes.
    
2. **Docker client**: The Docker client is a command-line tool that allows users to interact with the Docker daemon. Users can use the Docker client to build and manage Docker images, create and run Docker containers, and manage Docker networks and volumes.
    
3. **Docker images**: Docker images are read-only templates that contain everything needed to run an application, including the application code, dependencies, libraries, and system tools. Docker images are built from Dockerfiles, which are plain text files that specify the instructions needed to build the image.
    
4. **Docker containers**: Docker containers are running instances of Docker images. Each container runs in its own isolated environment, with its own file system and network interfaces. Containers can be created, started, stopped, and deleted using Docker commands.
    
5. **Docker registry**: A Docker registry is a central repository for Docker images. Docker users can push and pull Docker images from a registry to share them with others or use them across different environments. Docker Hub is a popular public registry for Docker images, but users can also set up their own private registries.
    
6. **Docker network**: Docker networks provide communication between Docker containers, as well as between Docker containers and the host system or other external systems. Docker supports several types of networks, including bridge networks, overlay networks, and host networks.
    
7. **Docker volumes**: Docker volumes provide persistent storage for Docker containers, allowing data to persist even if the container is stopped or deleted. Docker volumes can be created and managed using Docker commands and can be used to share data between Docker containers or between a container and the host system.
    
    ### **<mark>Install Docker Engine:</mark>**
    
    * **<mark>Login to your EC2 Instance</mark>**:
        

* Verify if the docker is installed or not  
    `rpm -qa | grep -i docker`
    
* Search for the docker RPM  
    `yum search docker`
    
* Update the System Packages  
    `yum update -y`
    
* Install Docker  
    `yum install docker -y`
    
* Verify the Docker service is in running and active status.  
    `systemctl status docker`  
    Start/Restart if required (If not running)  
    `systemctl restart docker`
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683041191637/68b408fa-2ba8-42f7-913a-9bd1dc5c3626.png align="center")
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683041965300/ea5b0cfd-d3b2-417e-bd64-ca0382de35fa.png align="center")
    
    * You can view the running containers using  
        `docker ps`  
        `docker ps -a`
        
    * If you are getting a "**permission denied**" error for the user then add the user to the **<mark>docker</mark>** group  
        `whoami`  
        `grep docker /etc/group`  
        `sudo usermod -aG docker ec2-user`  
        `grep docker /etc/group`  
        `docker ps`  
        `sudo su`  
        `docker ps`
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683042321346/5f1e7cac-2da0-433b-841a-02319d7d355a.png align="center")
        
    * **<mark>Download Mysql Image and Verify that the Image exists</mark>**
        
        `docker pull mysql`  
        `docker images`
        
    * Run the Container  
        `docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=em7admin mysql:latest`  
        `docker ps`
        
    * To go into the Docker Container  
        `docker ps`  
        `docker exec -it <Container-ID> bash`
        
    * Kill Docker Container  
        `docker kill <Container-ID>`  
        `docker ps`
        
    * Running the Docker Container in the background using <mark>-d</mark> \[deteched\] option  
        `docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=em7admin -d mysql:latest`  
        `Or`  
        `docker run -p 80:80 nginix:latest`
        

### <mark>Docker CMDS:</mark>

You can find the Images on DockerHub here:-  
[https://hub.docker.com/search?q=&type=image](https://hub.docker.com/search?q=&type=image)

* Check the version of the Docker Server Engine running on the Host  
    `docker version`
    
* Start a container from an Image \[**<mark>run</mark>**\]  
    `docker run <Image-Name>`  
    `docker run <`[`IMAGE:TAG`](IMAGE:TAG)`>`  
    `i.e`  
    `docker run nginx`  
    `docker run alpine:3.17`
    
    **Note:** It will download the image "nginx" from DockerHub if unable to find it in the local repository and run it.
    
    When you are using your own Images, in that case, you need to use your username and the repository name i.e  
    `docker run <username>/<Repository-name>`
    
* Run a container with the nginx:1.14-alpine image and name it webapp  
    `docker run -d --name webapp nginx:1.14-alpine`
    
* List containers \[**<mark>ps</mark>**\]  
    `docker ps`  
    To show all the containers including the existing ones  
    `docker ps -a`
    
* Stop a container\[**<mark>stop</mark>**\]  
    `docker stop <Container ID / Container Name>`
    
* Remove a container \[**<mark>rm</mark>**\]  
    `docker rm <Container ID / Container Name>`  
    You can remove multiple Containers same time.
    
* List images\[**<mark>images</mark>**\]  
    `docker images`  
    Note: Delete all dependent containers to remove the image
    
* Remove images \[**<mark>rmi</mark>**\]  
    `docker rmi <`[`IMAGE:TAG`](IMAGE:TAG)`>`
    
* Delete all images on the host  
    First:- Stop and delete all the containers being used by images.  
    `docker stop $(docker ps -a -q)`  
    `docker rm $(docker ps -a -q)`  
    Then run the command to delete all the available images:  
    `docker rmi $(docker images -aq)`
    
* Download an image \[**<mark>pull</mark>**\] \[Downloading the image without installing it\]  
    `docker pull <`[`IMAGE`](IMAGE:TAG)`>`
    
* Execute a command on a running container \[**<mark>exec</mark>**\]  
    `docker exec <Contianer-ID> <CMD-To-Run-On-Container>`  
    i.e  
    `docker exec ngnix cat /etc/hosts`
    
* Attach and Detach \[<mark>Run</mark>\]  
    `docker run kodekloud/simple-webapp`  
    <mark>-d</mark>: is used to run the container in the background  
    `docker run –d kodekloud/simple-webapp`  
    To attach the container again  
    `docker attach <container-id>`
    
* Append a command  
    `docker run centos`  
    `docker run centos sleep 50`  
    `docker run -d centos sleep 50`  
    `docker run ubuntu cat /etc/*release * docker run ubuntu:12.10 cat /etc/*release*`
    

When running a BASE image it will exit automatically as nothing is running on it, so you can use this to get that working.  
`docker run -it centos bash` // To login into the container  
`docker run -d centos sleep 20`

* RUN - STDIN
    
    **<mark>-i</mark>** : Interactive Mode  
    **<mark>-t</mark>** : sudo terminal
    
    `docker run –i kodekloud/simple-prompt-docker docker run –it kodekloud/simple-prompt-docker`
    
* Delete all containers \[Both Running and Not Running ones\] from the Docker Host.  
    **Note:** You may have to stop containers before deleting them.
    
    * Stop all the containers  
        `docker stop $(docker ps -a -q)`
        
    * Remove all the containers  
        `docker rm $(docker ps -a -q)`
        
    
    Or  
    `docker ps -a | cut -d " " -f1| xargs -I {} docker stop {}`  
    `docker ps -a | cut -d " " -f1| xargs -I {} docker rm {}`
    

**Note:-** The container is only live as long as the process inside it is Alive, if the Webservice container is stopped/crashed, the container exists.

* Run – PORT mapping
    
    `docker run –p 80:5000 kodekloud/simple-webapp`  
    `docker run –p 8000:5000 kodekloud/simple-webapp`  
    `docker run –p 8001:5000 kodekloud/simple-webapp`  
    `docker run –p 3306:3306 mysql`  
    `docker run –p 8306:3306 mysql`
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683361488533/474cf96b-9c18-4ea6-9d98-91903ce50b28.png align="center")

* **RUN – Volume mapping**
    

To persist data, you need to map the directory outside of the container on the Docker host to a directory inside the container...  
`docker run –v /opt/datadir:/var/lib/mysql mysql`

Containers are assigned with private IPs, which are not accessible on the Internet, you can use `docker inspect <container-id>` cmd to know the container IP.

**2 Ways to access the application on Web UI :-**  
  
1\. **Internal IP** \[To access it via Internal IP, you need to be inside the DockerHost \]  
2\. **Mapping** a port to the Docker Host and accessing it using the External IP  
`docker run -p 8080:8080 jenkins`

To persist the data/configuration across the docker container or during the restarts, you need to map a volume.

`docker run -p 8080:8080 -v /root/<local-directory>:/var/jenkins_home -u root jenkins`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683362171542/7eb974eb-c380-44d9-a973-ccb86ed04443.png align="center")

* Inspect Container  
    `docker inspect <container-ID/Name>`
    
* Container Logs  
    `docker logs <container-ID/Name>`
    
* Docker History  
    `docker history <IMAGE>`
    
* Run an instance of kodekloud/simple-webapp with a tag blue and map port 8080 on the container to 38282 on the host.
    

Run the command:  
`docker run -p <Contianer-Port>:<Host-Port> <`[`IMAGE:TAG`](IMAGE:TAG)`>`  
i.e  
`docker run -p 38282:8080 kodekloud/simple-webapp:blue`  
You can run this container in the background after adding the **\-d** flag.

Here:  
Container Port: `8080`  
Host Port: `38282`

### Docker Images

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683423727255/ce7b871d-bb51-49be-bba9-001adfa183b5.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683423804489/33843a46-7389-4685-a03f-fdd007c4bcb7.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683423867721/9f16c08d-f7ea-4265-8fbb-d6e2a7b442fd.png align="center")

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683430507117/28220695-b766-40c2-9443-41ef25ebba21.png align="center")

\-- **Build an Image**:  
`docker build -t . <`[`Image`](Image-Name:TAG) `Name>`  
`docker build -t <`[`Image-Name:TAG`](Image-Name:TAG)`> .`

**NOTE:** At the end of the command, we used the "**<mark>.</mark>**" (dot) symbol which indicates for the current directory, so you need to run this command from within the directory that has the Dockerfile.

* Run an instance of the image webapp-color and publish port 8080 on the container to 8282 on the host.  
    `Container with image 'webapp-color'`  
    `Container Port: 8080`  
    `Host Port: 8282`
    

**<mark>Sol:</mark>** `docker run -p 8282:8080 webapp-color`

* How to check what is the base Operating System used by the python:3.6 image?
    
    `docker run python:3.6 cat /etc/*release*`
    

\-- **Environment Variables**

You can use docker inspect cmd to identify the value set to the APP\_COLOR variable.  
`docker inspect <contianer-id> | grep APP_COLOR`

`export APP_COLOR=blue; python` [`app.py`](http://app.py)

`docker run -e APP_COLOR=blue simple-webapp-color`  
`docker run -e APP_COLOR=pink simple-webapp-color`

`docker run -p 38282:8080 --name blue-app -e APP_COLOR=blue -d kodekloud/simple-webapp`  
  
To know the env field from within a webapp container, run  
`docker exec -it <contianer-id> env`  
`i.e`  
`docker exec -it webapp env`

* Deploy a `MySQL` database using the mysql image and name it mysql-db. Set the database password to use db\_pass123. Look up the mysql image on Docker Hub and identify the correct environment variable to use for setting the root password.
    

`Name: mysql-db`  
`Image: mysql`  
`Env: MYSQL_ROOT_PASSWORD=db_pass123`

**<mark>Sol:</mark>**  
`docker run -d -e MYSQL_ROOT_PASSWORD=db_pass123 --name mysql-db mysql`

To know the env field from within a mysql-db container, run  
`docker exec -it mysql-db env`

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1683428970203/4790e265-15aa-4f51-96c3-b6ccbc59bc7b.png align="center")

**docker stop**: Stop a running container (send SIGTERM, and then SIGKILL after grace period) \[...\] The main process inside the container will receive SIGTERM, and after a grace period, SIGKILL.

**docker kill**: Kill a running container (send SIGKILL, or specified signal) \[...\] The main process inside the container will be sent SIGKILL, or any signal specified with option --signal.

Both the docker kill and docker stop commands stop a container. One more way to stop a container is just to remove it. We can use the **<mark>docker rm</mark>** command to remove a container. This will remove the container from local storage immediately.
