---
# System prepended metadata

title: Docker
tags: [Docker]

---

# Docker
###### tags : `Docker`
[markdown語法](https://markdown.tw/#link)
## 參考網址:
* [Docker菜鳥教程](https://www.runoob.com/docker/docker-tutorial.html)
* [Docker--從入門到實踐](https://philipzheng.gitbook.io/docker_practice/)
![](https://miro.medium.com/max/594/1*DkIQGsv9YsPgB0dQpIfikA.png)
Containers as a Service ( CaaS ) - 容器如同服務
Docker 是一個開源專案，出現於 2013 年初，最初是 Dotcloud 公司內部的 Side-Project。
它基於 Google 公司推出的 Go 語言實作。（Dotcloud 公司後來改名為 Docker）

## 基本介紹 - 映像檔、容器、倉庫
**什麼是容器技術Container： 應用程式為中心的虛擬化**

### Docker 歷史
* 1982年Unix系統內建的chroot機制
:::info
chroot是起源於Unix系統的一個操作，作用於正在執行的行程和它的子行程，改變它外顯的根目錄。一個運行在這個環境下，經由chroot設定根目錄的程式，它不能夠對這個指定根目錄之外的檔案進行存取動作，不能讀取，也不能更改它的內容。chroot這一特殊表達可以指chroot系統呼叫或chroot應用程式。
由chroot創造出的那個根目錄，叫做「chroot監獄」（chroot jail，或chroot prison）。
:::
* LXC 利用controler groups 與namespaces的功能， 提供應用軟體一個獨立的作業系統環境
* 2013 Linux之父Linus Torvalds 發布Linux核心3.8版 支援Container技術
* 2013 dotCloud公司將內部專案Docker開源釋出程式碼

###  Virtual Machines(虛擬主機) V.S Containers(容器)
![](https://images.contentstack.io/v3/assets/blt300387d93dabf50e/bltb6200bc085503718/5e1f209a63d1b6503160c6d5/containers-vs-virtual-machines.jpg)

### Docker 三個基本概念
#### 映像檔（Image） 
* Docker 映像檔就是一個**唯讀的模板**。
* 映像檔可以用來建立container。
#### 容器（Container）
* 容器是**從映像檔建立**的執行實例。
* Docker 利用容器來執行應用。
* 可以被啟動、開始、停止、刪除。
* 每個容器都是相互隔離的、保證安全的平台。
* 最終被用來執行的程序，就是我們的主角
#### 倉庫（Repository）
* 倉庫是集中 **存放映像檔(image)** 檔案的場所，很像github。
* 每個倉庫中又包含了多個映像檔。
* 倉庫分為公開倉庫（Public）和私有倉庫（Private）兩種形式。


## 指令說明 - 安裝、指令
```docker --help```

![](https://i.imgur.com/yT8BH4e.png)

![](https://i.imgur.com/Lk48eXT.png)

### 映像檔(image)常用指令
| 指令         | 說明 | 範例                           |
| ------------ | ---- | ------------------------------ |
| search       | 搜尋 | docker search centos           |
| pull         | 下載 | docker download centos         |
| push         | 上傳 | docker push                    |
| images       | 列表 | docker images                  |
| run          | 執行 | docker run -ti centos/bin/bash |
| rmi[imageID] | 刪除 | docker rmi 615cb40d5d19        |
| build        | 建立 | docker build -t member:1 .     |
| login        | 登入 | docker login docker.okborn.com |

**ex:```docker search centos```**
Search 搜尋 Centos 映像檔
![](https://i.imgur.com/hrGJpoG.png)
:::info
NAME：映像檔名稱
DESCRIPTION：映像檔描述
STARS：越多代表越多人使用
OFFICIAL：官方Image
AUTOMATED：自動化
:::

**ex:```docker iamges```**
顯示目前本機的 Images 列表
![](https://i.imgur.com/JBs3o6r.png)
:::info
REPOSITORY：倉庫位置和映像檔名稱
TAG：映像檔標籤(通常是定義版本號)
IMAGE ID：映像檔ID(唯一碼)
CREATED：創建日期
SIZE：映像檔大小
:::

**ex:```docker run -ti centos /bin/bash```**
啟動容器
![](https://i.imgur.com/93PeR28.png)
:::info
run : 參數說明 or docker run --help 常用：
-i(interactive) ：互動模式，保持標準輸入
-t(tty)：讓Docker分配一個虛擬終端（pseudo-tty）並綁定到容器的標準輸入上
-d：背景執行
-e：設定環境變數(AAA=BBB)
-p：Port 對應(host port:container port)
-v：資料對應(host folder:container folder)
--name：設定容器名稱
/bin/bash:容器啟動後要執行的命令
:::
**在run映像檔時，若本地端沒檔案，會先下載再執行**

rmi : 刪除映像檔前要先移除所有Container
build : 使用build 指令時要先切換到Dockerfile 目錄下面

### 容器(container)常用指令
| 指令              | 說明                   | 範例                         |
| ----------------- | ---------------------- | ---------------------------- |
| run               | 新建或啟動             | docker run -d centos         |
| start[Contain ID] | 啟動                   | docker start a469b9226fc8    |
| stop[Contain ID]  | 停止                   | docker stop a469b9226fc8     |
| rm[Contain ID]    | 刪除                   | docker rm a4                 |
| ps -a             | 列表                   | docker ps -a                 |
| logs[Contain ID]  | 查看容器內的資訊       | docker logs -f a4            |
| exec [Contain ID] | 進入容器(開新console)  | docker exec -ti a4 /bin/bash |
| attach            | 進入容器(退出停止容器) | dockr attach a4              |
| inspect           | 查看                   | docker inspect a4            |

**ex:```docker run -d centos ping google.com```**
啟動一個container並且在背景執行ping google.com
![](https://wt-box.worktile.com/public/aef96620-2681-441c-bb12-1ac5a046b9d4)

**ex:```docker ps```**、**```docker ps -a```**
查看container(-a查看全部，包含未運行的容器)
![](https://i.imgur.com/pUstZaR.png)
:::info
CONTAINER ID：容器ID
IMAGE：映像檔名稱
COMMAND：執行指令
CREATED：創建時間
STATUS：容器狀態
POSTS：開啟的Port號
NAMES：容器名稱
:::

**ex:```docker exec -it 6c /bin/bash```**
進入容器
![](https://i.imgur.com/YIorjyG.png)
:::info
exec : 參數說明 or docker exec --help 常用：
-i：則讓容器的標準輸入保持打開
-t：讓Docker分配一個虛擬終端（pseudo-tty）並綁定到容器的標準輸入上
-e：設定環境變數(AAA=BBB)
:::

**ex:```docker inspect 2b(containerID前兩碼)```**
查看容器資訊
![](https://i.imgur.com/XNT47bf.png)
### 倉庫(Repository)常用指令
| 指令   | 說明     |                         範例                         |
| ------ | -------- |:----------------------------------------------------:|
| commit | 容器存檔 |               docker commit db aaa:v1                |
| pull   | 下載     |      docker pull docker.okborn.com/okborn:base       |
| tag    | 標籤     |         docker tag aaa docker.okborn.com/aaa         |
| push   | 上傳     |        docker push docker.okborn.com/member:1        |
| login  | 登入     |            docker login docker.okborn.com            |
| export | 匯出     |       docker export 7691a814370e > ubuntu.tar        |
| import | 匯入     | cat ubuntu.tar sudo docker import - test/ubuntu:v1.0 |

**ex:```docker commit [repositary name]```**
對容器存檔(因為每個container都是獨立的，若想使用之前在container中做過的事可使用commit，把我們的container做成一個新的image)
![](https://i.imgur.com/msrW4JX.png)


## Dockerfile 說明 
**Dockerfile 包含一系列指令用來創建(build) Docker image, 再使用image建立container運行(run)在不同的裝置之間**
![](https://miro.medium.com/max/1400/0*CP98BIIBgMG2K3u5.png)
### Dockerfile 基本語法
| 指令                                          | 說明                     | 範例                                                        |
| --------------------------------------------- | ------------------------ | ----------------------------------------------------------- |
| FROM :                                        | 映像檔來源               | FROM python:3.5                                             |
| MAINTAINER                                    | 維護者訊息               | MAINTAINER docker_user docker_user@email.com                |
| RUN                                           | 創建映像檔時執行動作     | RUN apt-get -y update && apt-get install -y supervisor      |
| RUN ["executable", "param1", "param2"]        | 創建映像檔時執行動作     | RUN ["/bin/bash", "-c", "echo hello"]                       |
| CMD command param1 param2                     | 啟動容器時執行的命令     | CMD pserve development.ini                                  |
| CMD ["executable","param1","param2"]          | 啟動容器時執行的命令     |                                                             |
| CMD ["param1","param2"]                       | 啟動容器時執行的命令     |                                                             |
| EXPOSE                                        | 容器對外的埠號           | EXPOSE 8082                                                 |
| ADD                                           | 複製檔案(單檔)           | ADD requirements.txt /usr/src/app/                          |
| COPY                                          | 複製檔案(資料夾)         | COPY . /usr/src/app                                         |
| ENV                                           | 環境變數                 | ENV PG_VERSION 9.3.4                                        |
| ENTRYPOINT command param1 param2              | 指定容器啟動後執行的命令 |                                                             |
| ENTRYPOINT ["executable", "param1", "param2"] | 指定容器啟動後執行的命令 | ENTRYPOINT ["/docker-entrypoint.sh"]                        |
| VOLUME ["/data"]                              | 掛載資料卷               | VOLUME /var/lib/postgresql/data                             |
| USER daemon                                   | 指定運行使用者           | RUN groupadd -r postgres && useradd -r -g postgres postgres |
| WORKDIR /path/to/workdir                      | 指定工作目錄             | WORKDIR /usr/src/app                                        |
| ONBUILD [INSTRUCTION]                         | 基底映像檔建立時執行     | ONBUILD COPY . /usr/src/app                                 |

ex:
hello.py
```
print("hello")
```
Dockerfile
```
# 將 image 文件繼承官方的3.7版本的 python 
FROM python:3.7
# 將當前目錄下的所有文件(除了 .dockerignore 排除的路徑)，都拷貝進 image 文件的/app 目錄
COPY . /app
# 指定接下來的工作路徑為 /app
WORKDIR /app
# 在 /app目錄下，進行 python 文件
CMD python3 hello.py
```
.dockerignore
```
__pycache__
env
```
執行時:
`docker image build -t python-app .`
`docker run python-app`
### 注意事項
* RUN 命令較長時可以使用 \ 來換行。
* 每個 Dockerfile 只能有一條 CMD 命令(如果指定了多條命令，只有最後一條會被執行)
* 每個 Dockerfile 中只能有一個 ENTRYPOINT(當指定多個時，只有最後一個會生效)
* USER：要臨時取得管理員權限可以使用 gosu，而不推薦 sudo