<style>
.alert-info img{
background-color: #fff0
}
img[src^="https://i.imgur.com/WUomAUM.png"]{
position: relative;
left: 10%;
background-color: #fff0;
}
.title {
color: #009933;
font-weight:bold;
}
.highlight {
color: #ff4d4d;
font-weight:bold;
border-bottom:2px red solid; padding-bottom:2px;
}
</style>
<!-- <font class="highlight"> -->
<!-- <font class="title"> -->
<!-- 縮寫提示 -->
<!-- *[O-RAN]:Open Radio Access Network -->
:::warning
# <center><i class="fa fa-book"></i> Introduction to Docker </center>
:::
###### tags: `study` `Docker`

:::success
**🎯 Goals:**
- [x] - <a href="#11-Docker-Architecture">To know Docker Architecture</a>
- [x] - <a href="#Module-2-Basic-concept">To know the basic concept</a>
- [x] - <a href="#Module-4-Try-it">Try it </a>
- [x] - <a href="#Module-5-Summary">Summary </a>
:::
:::info
:bookmark: **Reference:**
- [Dockerhub](https://hub.docker.com/)
- [Chinese detailed practice](https://azole.medium.com/docker-container-%E5%9F%BA%E7%A4%8E%E5%85%A5%E9%96%80%E7%AF%87-1-3cb8876f2b14)
---
:link: **++Links++ to my notes on the same topic**
- [](/@MingHung/Kubernetes)      [](/@MingHung/Helm)
:::
[toc]
# Module 1: Introduce
- **Docker is not cross platform, docker is platform**
Docker is a tool for simulating the environment, not like a java virtual machine to simulate a machine.
- Docker is a **==system==**-level service, and jvm is an **==application==**-level service.
So, <span style="background-color:springgreen">**can run jvm and dotnet in docker**</span>,
but conversely, <span style="background-color:orange">**can't run docker in jvm or dotnet**</span>.
- **Docker Image**: A Docker image is a lightweight, portable software package used to create Docker containers. The image contains all the code, dependencies, and configuration files needed for an application, and can be reused across different environments to achieve portability and consistency.
- **Docker Container**: A Docker container is a runtime environment created from a Docker image, containing all the runtime dependencies of an application such as libraries, frameworks, and the execution environment. Containers are self-contained and lightweight, can run anywhere, and can be quickly started and stopped.
- **Docker Hub**: Docker Hub is a Docker image hosting service platform used to upload, download, and share Docker images. You can use images from Docker Hub to create containers, or upload your own images for others to use.
- **Docker Compose**: Docker Compose is a tool used to define and run multiple Docker containers. It uses a YAML file to define container configuration, dependencies, and other related information, enabling fast application deployment and simplified development processes.
## 1.1 Docker Architecture

:::info
**Three basic things that matter:**
- **Image:** read-only, build container
- **Container**
- **Docker registr:** [Docker Hub](https://hub.docker.com/)、private registry
:::
# Module 2: Basic concept
## 2.1 registry (Dockerhub)
- Usually we rarely build a language environment by ourselves, but use the officially provided
- The official image file usually provided above
> Example link for golang: [dockerhub](https://hub.docker.com/_/golang)
| latest | slim | alpine |
| -------- | -------- | -------- |
| Latest Features | Remove some unimportant features | Usually the smallest version |
## 2.2 Image
It contains running programs and environments
> For example golang images: **linux** and installed **go**
### 2.2.1 Make sure images exists
```cmd=
docker images
```
### 2.2.2 Build
```cmd=
docker build -t <image_name:tag_name> .
```
>The dot at the end of the command is **important**.
### 2.2.3 Remove
```cmd=
docker rmi IMAGE_ID
```
>If any Container is using the Image, you need to [delete the Container](#23-Container) first
- **Format:** `image_name:tag_name`
> tag_name is optional, default latest
:::info
**Relationship with Container:**
- **Images are ==read-only==, Containers are ==read-write==**
<!--  -->
  
- Creating multiple read-write Containers will be **built on top of** read-only Images
<!--  -->

- **Create a new Image from the current Container:**
```cmd=
docker commit CONTAINER_ID [Repository:[Tag]]
```
- **The new Image will refer to the parent Image**
- So Docker will no longer build the existing Image
<!--  -->

:::
## 2.3 Container
Everything is done in this container,
Therefore, no matter what operation is done in the container, it has **nothing to do with the image**.
Because the image is only responsible for providing the information needed to run the container
### 2.3.1 View all docker containers (whether it is alive or dead)
```cmd=
docker ps -a
```
- `-a`: whether it is alive or dead
- `-l`: Show the latest created container (includes all states)
### 2.3.2 command to run/creat
```cmd=
docker run <image-name>
docker run busybox echo "hello world"
```
```cmd=2
docker run -it -v /home/user1/storage:/storage centos /bin/bash
```
- `--name <NAME>` : Give this Container a name
- `-d` : Detached、Daemonized (work in the background)
- `-i` : `--interactive` Start interactive mode, keeping standard input open.
- `-t` : `--tty` Let Docker allocate a virtual terminal (pseudo-TTY) and bind to the standard output of the container.
- `-v` : Mapping the folder path of the entity host to the folder path of the Container
### 2.3.3 remove
```cmd=
docker rm <CONTAINER_ID>
```
> Stop the container before attempting removal or force remove
```cmd=
docker stop <CONTAINER_ID>
```
- **remove the unneeded containers**
```cmd=
docker system prune
```
### 2.3.4 Logs
```cmd=
docker logs [OPTIONS] CONTAINER
```
- `[OPTIONS] :`
- `-f`、`--follow`: Follow log output
- `--until`: Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m)
- Example:
```cmd=
docker logs -f --until=2s test
```
### 2.3.5 Enter Docker Container
- exec
- Enter `exit` to leave, the Container itself is still executing in the background and will ==not be closed==.
```cmd=
sudo docker exec -it ubuntu bash
```
- attach
- Type `exit` to leave, the Container itself will also ==be closed==.
- `Ctrl+P` and `Ctrl+Q` to leave, the Container will ==still be executed== in the background state.
```cmd=
sudo docker attach ubuntu
```
### 2.3.6 Get container IP
```cmd=
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_name_or_id>
```
### 2.3.7 More Command
- [userful link](https://joshhu.gitbooks.io/dockercommands/content/Containers/ContainersBasic.html)
## 2.4 Dockerfile

Contains a series of instructions for users to **automatically install Docker Image**
- **example:**
- FROM : Indicates which image to use to build
- WORKDIR : Indicates the work folder
- ADD : Indicates copying the file to the directory of the image, similar to the role of container -v, where . means to copy all the current directory to /home/go
- CMD : Represents the default command to be executed once the image is put into the docker operation
```cmd=
FROM golang:rc-alpine
WORKDIR /home/go
ADD . /home/go
CMD ["go", "run","."]
```
### 2.4.1 Question:
**What is the difference between using RUN to run a program, using CMD to run a program, and using ENTRYPOINT to run a program in a Dockerfile?**
In Dockerfile, there are three commands that can be used to execute programs:
**RUN:** Executes commands during the creation of the Docker Image. It is usually used to install software or update the system, and after execution, it will generate a new Image Layer.
**CMD:** When using the Docker Image to start a Container, it will execute the command specified by CMD. Only one CMD command can be used in Dockerfile, and if there are multiple CMD commands, only the last one will be executed.
**ENTRYPOINT:** Similar to CMD command, it will execute the command specified by ENTRYPOINT when using the Docker Image to start a Container. The difference is that using ENTRYPOINT can allow the Container to run as an application, rather than simply executing a command. If ENTRYPOINT is used in Dockerfile, CMD can be used to provide default parameters required by ENTRYPOINT during execution.
In summary, RUN is used to execute commands during Image creation, CMD is used to execute commands during Container startup, and ENTRYPOINT is used to define the application entry point for the Container.
:::spoiler Chinese
在 Dockerfile 中,可以使用以下三種指令來執行程式:
1. RUN: 在建立 Docker Image 的過程中執行指令,通常用來安裝軟體或更新系統等,執行完畢後會產生一個新的 Image Layer。
2. CMD: 在使用 Docker Image 來啟動 Container 時,會執行 CMD 指定的指令。Dockerfile 中只能使用一次 CMD 指令,如果有多次,只會執行最後一次。
3. ENTRYPOINT: 類似 CMD 指令,也是在使用 Docker Image 來啟動 Container 時,會執行 ENTRYPOINT 指定的指令。不同的是,使用 ENTRYPOINT 可以讓 Container 以應用程式的方式執行,而不是單純的執行一個指令。如果在 Dockerfile 中使用了 ENTRYPOINT,則 CMD 可以用來提供 ENTRYPOINT 執行時需要的預設參數。
簡單來說,RUN 是用來在 Image 建立時執行指令,CMD 是用來在啟動 Container 時執行指令,而 ENTRYPOINT 則是用來定義 Container 的應用程式入口點。
:::
## 2.5 Docker composer

- a handy tool
- Useful when running **more than just one image**
- Establish **relationship links** between Containers
- Start multiple containers quickly and **easily**
:::danger
**Docker run**
 If we want to start a lot of Docker Containers, we need to enter the **`docker run` command many times**. In addition, if we want to associate the container and the container, we must remember how to **link the Containers**, so that we need to **start multiple Docker containers**. In the case of Container, it will be more troublesome.
:::
:::success
**Docker-Compose**
 just write a `docker-compose.yml`, write all the Docker **Images to be used**, and you can also **link the relationship** between the Containers, and finally just run the `docker-compose up` command, you can put all the The Docker Container is executed, so that multiple containers can be **started quickly and easily**.
:::
### 2.5.1 Install Docker composer
- [LINK](https://docs.docker.com/compose/install/other/)
```cmd=
sudo -i
cd /usr/bin
wget https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64
mv docker-compose-Linux-x86_64 docker-compose
chmod 755 docker-compose
# or
curl -SL https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
```
### 2.5.2 Compose a sample docker-compose.yml file
- The main function is to start a container (e2-simulator).
```cmd=
version: '3.8'
services:
e2-simulator:
image: "o-ran-sc/ntsim-e2-simulator:2.0.0"
build:
context: ~/e2-interface/e2sim/e2sm_examples/kpm_e2sm
container_name: e2-simulator
entrypoint: ["kpm_sim", "10.0.10.205", "32222"]
```
### 2.5.3 Start all Docker Containers
```cmd=
docker-compose up -d
```
> `-d` : background execution[color=gray]
### 2.5.4 Find a working Container by Composer
- **Before entering this command, change the path to the path at the ==same level== as `docker-compose.yml`**
```cmd=
$ docker-compose ps [<Container Name>]
```
### 2.5.5 Logs
```cmd=
docker-compose logs
```
### 2.5.6 Stop all containers
- Stop all Containers executed by docker-compose
```cmd=
docker-compose stop
```
### 2.5.7 Remove all Containers
- Delete all Containers of docker-compose
```cmd=
docker-compose rm
```
## 2.6 Volumes
- [Official document - Volumes](https://docs.docker.com/storage/volumes/)
- Volumes are the preferred mechanism for persisting data generated by and used by Docker containers.
- When the Docker Container is deleted, the data stored in the Docker Container **will also be deleted**. Therefore, it is necessary to ==store the data== that do not want to be deleted on the ==physical machine== to avoid the problem of missing data.
- 
## 2.7 Docker Swarm
- **It is a tool that can execute Docker Container on multiple different physical machines.**
- **Form a Cluster.**

- The function of **++Manager++** is to allocate the Node on which Docker Container needs to be executed. The main allocation strategies are as follows:
**spread:** Select Node that executes fewer Containers
**binpack:** Try to put the Container on the same Node for execution, so as to reduce the usage of Node
**random:** Randomly assign the Container on which Node to execute
- **++Node++** is the physical machine that mainly executes Container.
# Module 3: Comparison
## 3.1 Compared to Virtual Machine

:::danger
- **VM disadvantage**
- spend a lot of resources
- Lengthy steps to execute
- slow execution
- It is easy to have **conflicts** between different platform versions
:::
:::success
- **Docker Container advantage**
- Provide a one-time environment
- Elastic cloud service
- Convenient transfer system
:::
# Module 4: Try it!
## 4.1 Beginning
1. Determine if docker is installed successfully
2. See what images are on computer
3. Download the hello-world test image
```cmd=
docker version
docker image ls
docker image pull hello-world
docker image ls
```
1. Run container bt test image (hello-world)
```cmd=
docker container run hello-world
```
> The test container has been automatically terminated
- 
## 4.2 Kill it (For do not terminate automatically)
- ❗ Some containers do not terminate automatically
1. See what containers are on computer (List newly created)
```cmd=
docker container ls -l
```
2. close the container
```cmd=
docker container ls
docker kill [OPTIONS] CONTAINER [CONTAINER...]
```
# Module 5: Summary
  Docker is an environment **simulation platform** that provides software engineers to quickly build, test and deploy applications.
  Applications can be quickly deployed and scaled to a **variety of environments**, knowing the code will **execute**.
# Question & Answer:
## Q1:
Today, the xApp is running in container based, and there are some problems of xApp. You try to solve them, so you enter the container of xApp to modify the code. Is the solution wrong ? If it is wrong, how do you solve the problems?
> Ans: This is the wrong approach. If I find bugs in xApp, after modifying the source code, I should re-deploy the image and re-run a Container.
----
<!-- >**Name**: `名稱` -->