---
tags: Docker,Command
---
# Docker 範例
在要離開 docker container 的 terminal 時有一個坑。就是如果輸入 exit 指令時,container 會被關閉,如下圖:
![img](https://ithelp.ithome.com.tw/upload/images/20171207/20103456o52mlrYmiA.png)
如果不要停止 container 而要退出 docker container 的terminal 需要輸入 ****ctrl + p之後再輸入 ctrl + q 的按鍵**** ,就不會把 container 關閉。
## Dockerfile
### ㄧ.Dockerfile 的範例如下
```dockerfile
FROM centos:7
MAINTAINER Neil
RUN yum install -y wget
RUN cd /
ADD jdk-12.0.2_linux-x64_bin.tar.gz /
RUN wget http://apache.stu.edu.tw/tomcat/tomcat-7/v7.0.94/bin/apache-tomcat-7.0.94.tar.gz
RUN tar zxvf apache-tomcat-7.0.94.tar.gz
ENV JAVA_HOME=/jdk-12.0.2
ENV PATH=$PATH:/jdk-12.0.2/bin
CMD ["/apache-tomcat-7.0.94/bin/catalina.sh", "run"]
```
FROM: 使用到的 Docker Image 名稱,今天使用 CentOS
MAINTAINER: 用來說明,撰寫和維護這個 Dockerfile 的人是誰,也可以給 E-mail的資訊
RUN: RUN 指令後面放 Linux 指令,用來執行安裝和設定這個 Image 需要的東西
ADD: 把 ****Local 的檔案(要與Dockerfile同目錄)**** 複製到 Image 裡,如果是 tar.gz 檔複製進去 Image 時會順便自動解壓縮。Dockerfile 另外還有一個複製檔案的指令 COPY 未來還會再介紹
ENV: 用來設定環境變數
CMD: 在指行 docker run 的指令時會直接呼叫開啟 Tomcat Service
---
#### COPY
複製本地端的檔案/目錄到映像檔的指定位置中
使用COPY的注意事項:
>指令的來源位置可以多個
>如果目的位置是目錄的話,記得最後要以/結尾,例如:/mypath/
>目的位置可以是絕對路徑或者相對於WORKDIR定義值的相對路徑
若****目的位置不存在,會自動建立****
COPY的範例如下:
COPY file1.txt file2.js file3.json ./
COPY ["file1.txt", "file2.js", "file3.json" "./"]
#### ADD
和COPY一樣,可將本地端的檔案/目錄加到映像檔的指定位置內
雖然ADD和CMD功能類似,但有二點最大的不同:
>ADD的來源路徑支援URL,也就是說可以加入遠端的檔案,COPY則不支援URL
若來源檔案是壓縮檔(副檔名為gzip、bzip2、xz),則使用ADD加入檔案時會自動解壓縮,而COPY不會
ADD的範例如下:
ADD file1.txt file2.js file3.json ./
ADD https://www.google.com/demo.gzip $ENV_DEMO_VALUE
>ENV_DEMO_VALUE 是用ENV指令所設定的環境變數
### 二. Build Docker Image
預設在和 Dockerfile 檔案同層的資料夾底下輸入, docker build 指令,如下
```shell
$ docker build -t mytomcat . --no-cache
```
使用 --no-cache 的主要原因,是避免在 Build Docker image 時被 cache 住,而造成沒有 build 到修改過的 Dockerfile。
Build 完 Docker Image 之後,使用 docker images 指令查看是否有 build 成功如下圖
![img2](https://ithelp.ithome.com.tw/upload/images/20171208/20103456EE1uDr0ky4.png)
### 三. Run Docker Image
之後就可以執行 Docker Container,這時Tomcat 的 Service 也會跟者被執行起來,指令如下
```shell
$ docker run mytomcat
```
### 四.打開 Browser 確認
要打開 Browser 確認 Tomcat Service 有沒有被執行起來時,發現我們不知道 Docker Container 的 IP,這時侯只能使用 docker exec 進入 docker container查詢 IP 。
要使用 docker exec 指令之前需要先知道 Container 的 ID 所以需要先使用 docker ps 指令查詢 Container ID,如下圖:
![img3](https://ithelp.ithome.com.tw/upload/images/20171208/20103456jB4ENkLTJY.png)
有了 IP 之後就可以打開 Browser 輸入 http://172.17.0.2:8080 URL的位置,確認 Tomcat Service 是否有啟動,如下圖:
![img4](https://ithelp.ithome.com.tw/upload/images/20171208/20103456oXtdRCpB99.png)
前面直接進入 Docker Container 去看 IP 的位址其實有點麻煩,會故意這樣 Daemon 主要的原因,是讓大家了解到我們把 Docker Container 執行啟來時並不會知道它的 IP 位址在哪,這需要透過設定有關於 Docker 的 Network 來解決這個問題。目前使用最簡單的方法,就是在run docker container 時用 Port 的 Mapping 來解決此問題,重新再一次 run docker container,指令如下:
```dockerfile
$ docker run -p 8080:8080 mytomcat
```
Container 的 8080 port mapping到 localhost 的 8080 port ,這樣只要輸入
http://localhost:8080 就可以看到 tomcat service 的 WebUI 畫面了。
![img5](https://ithelp.ithome.com.tw/upload/images/20171208/20103456jfkE7ZMFZP.png)
## Docker Image Push 到 Docker Hub
### 1. 要把 Docker Image Push 到 Docker Hub 上,需要把 Docker Image 加上 tag,如下指令
```dockerfile
$ docker tag mytomcat jackyohhub/mytomcat
```
使用的Docker tag格式如下:
docker tag ${Image Name} ****DockerHub帳號****/Image Name
執行結果的畫面如下:
![img6](https://ithelp.ithome.com.tw/upload/images/20171209/20103456pNwMxZoKTi.png
)
### 2. 輸入 docker login 指令登入到 Docker Hub,畫面如下
![img7](https://ithelp.ithome.com.tw/upload/images/20171209/20103456A1i2Lu8mOC.png
)
### 3.使用 docker push 指令把 Docker Image Push 到 Docker Hub 裡,指令如下
```dockerfile
$ docker push jackyohhub/mytomcat
```
成功之後的畫面如下
![img](https://ithelp.ithome.com.tw/upload/images/20171209/20103456grz4Tgf1Bo.png)
1. 測試是否成功的把 Docker Image Push 到 Docker Hub 上
****在 Docker Hub 網站裡,登入帳號進去可以看到 Repositories 已經有 jackyohhub/mytomcat 的 Docker Image 如下圖****
![img](https://ithelp.ithome.com.tw/upload/images/20171209/201034563uQP7LqpPa.png
)
2. 使用 docker rm 指令把 local 的 Image 刪除掉,測試從 Docker Hub pull Docker Image 下來,指令如下
```dockerfile
$ docker rmi -f jackyohhub/mytomcat
$ docker rmi -f mytomcat
```
3. 從 Docker Hub Pull Docker Image 下來,指令如下
![i](https://ithelp.ithome.com.tw/upload/images/20171209/20103456oyC3uwCgFz.png)
```dockerfile
$ docker pull jackyohhub/mytomcat
```
4. 啟動 Docker Container,指令如下
```dockerfile
docker run -p 8080:8080 jackyohhub/mytomcat
```
5. 啟動完成之後就可以使用 Browser 查看結果,輸入 URL 位址為 http://localhost:8080
## 建立 private 的 Docker Registry
### 一. 建立 Docker Registry Server
直接透過啟動 Docker container 的方式,就可以把 Docker Registry Server 建立起來,指令如下:
```dockerfile
$ docker run -d -p 5000:5000 -v /home/user1/storage:/var/lib/registry --name registry registry:2
```
參數說明如下:
-d:執行的 docker container 是 run 在背景的狀態,所以需要使用 docker logs 的指令才可以看到 log 狀態
-p:主機的 5000 port mapping 到 container 的 5000 port
****-v:因為 push 到 docker registry 的資料是放在 container 裡面的,如果把 docker container 刪除掉 docker registry 的 Image 資料就會不見,因此需要使用 –v 參數將主機的檔案路徑 mapping 到 container 裡面的檔案路徑,這樣 docker container 被刪除 docker registry 的 Image 資料還會存在****
--name:設定 docker container 的名稱
執行成功之後畫面如下:
![m](
https://ithelp.ithome.com.tw/upload/images/20171210/20103456fc6uJcn1HN.png
)
### 二. 把第5天做好的 Docker Image Push 到上個步驟架設好的 Docker Registry Server
跟使用 docker hub 一樣要把 Docker Image Push 到 Docker需要先使用 docker tag 的指令如下:
$ docker tag mytomcat 192.168.182.134:5000/mytomcat
因為這裡是 Demo 所以直接使用 IP 位址指定 Docker Reigstry 的位址,在實務上這是 Hard Code的做法,所以較好做法應該是使用指定 Host Name的方式。
把 Docker Image Push 到 Docker Registry Server 上,指令如下:
$ docker push 192.168.182.134:5000/mytomcat
畫面如下:
![i](
https://ithelp.ithome.com.tw/upload/images/20171210/201034560wIYdpo5wi.png
)
沒有成功的把 Docker Image Push 到 Docker Registry 上
在上個步驟把 Docker Image Push 到 Docker Registry 收到錯誤訊息主要是因為安全性上的問題,需要修改 client 的 Docker 設定,如下
(1) vi /etc/docker/daemon.json
daemon.json 的檔案內容如下
{
"live-restore": true,
"group": "dockerroot",
"insecure-registries": ["192.168.182.134:5000"]
}
(2) 重新啟動 Docker 的 service 指令如下
$ systemctl restart docker
重新 push docker image,指令如下
$ docker push 192.168.182.134:5000/mytomcat
可以看到畫面如下
![i](
https://ithelp.ithome.com.tw/upload/images/20171210/20103456R2hpOcavVk.png
)
以上就成功的把 Docker Image Push 到了 Docker Hub 上了
### 三. 再另外找一台電腦把 Docker Image Pull下來測試
需要修改 docker 的設定,如下
$ vi /etc/docker/daemon.json
daemon.json 的檔案內容如下
{
"live-restore": true,
"group": "dockerroot",
"insecure-registries": ["192.168.182.134:5000"]
}
重新啟動 Docker 的 service 指令如下
$ systemctl restart docker
Pull docker image 指令如下
$ docker pull 192.168.182.134:5000/mytomcat
執行成功之後畫面如下
![i](
https://ithelp.ithome.com.tw/upload/images/20171210/20103456KlfsjSn8V3.png
)
## 備份 Docker Image 為 tar 檔
### 一. 把實作的 Docker Image存檔出一個檔案
使用以下的指令將 Docker Image 存檔出一個檔案如下
$ docker save -o mytomcat.tar mytomcat
參數說明如下:
-o: 輸出檔案
mytomcat 是 Docker Image 的名稱
畫面如下:
![m](
https://ithelp.ithome.com.tw/upload/images/20171212/20103456UJuBrNx61M.png)
在這過程可能會需要花費一些時間,執行完成之後就可以看到產生出 mytomcat.tar的檔案
(儲存所有images
$ docker save $(docker images -q) -o myimages.tar )
### 二. 檔案放到另外一台電腦之後 Load 到 Docker 上
把檔案 Load 到 Docker 的指令如下
$ docker load -i mytomcat.tar
參數說明如下:
-i: 放要 import 的檔案名稱
畫面如下:
![m](
https://ithelp.ithome.com.tw/upload/images/20171212/20103456Vfsd6BoLcl.png)
### 三. 啟動Docker container,確認 Docker Image 有成功的被 Load 進到另外一台電腦上
*使用以下指令啟動 Docker container
$ docker run -d -p 8080:8080 mytomcat
畫面如下
![m](
https://ithelp.ithome.com.tw/upload/images/20171212/20103456vmSSicp4cp.png)
在 Browser 上輸入 http://192.168.182.130:8080 看到 tomcat 畫面,就可以確認 Docker container 有啟動起來,畫面如下
![m](
https://ithelp.ithome.com.tw/upload/images/20171212/20103456HWP9gCyOKv.png)
今天已經介紹了如何備份 Docker Image 的部份了,適合在沒有網路而且只需要個人使用的情況下使用。
## Docker 的 Network (較麻煩)
### 替代方案**docker-compose CLI**
[先導作業](#docker-network)
![m](https://ithelp.ithome.com.tw/upload/images/20171223/20103456bATaXz4Pcl.png)
Host1 的實體主機需要連線到 Host2 的實體主機裡面的 Container1,如果在沒有設定網路情況下 Host1 連不到 Host2,因為 Container1 是被保護在 Host2 實體機器裡,如果要讓 Host1 連到 Host2 上,最簡單的方法是先讓 ****Host2 的 Port 對應到 Container1 的 Port****,然後 Host1 會先連到 Host2 實體主機的 Port,然後就會對應到 Container1 的 Port,這樣 Host1 就可以連到 Host2 上的 Container1,這是最常使用的方法。
### Example1
測試在使用 docker run 指令時參數指定為大寫的 -P,這樣實體主機會隨機的產生一個 Port 對應到 Container 裡面的 Port,但在這之前需要修改一下 Dockerfile,實作的步驟如下:
1. Dockerfile 如下
```dockerfile
FROM centos:7
MAINTAINER Neil
RUN yum install -y wget
RUN cd /
RUN wget http://apache.stu.edu.tw/tomcat/tomcat-7/v7.0.94/bin/apache-tomcat-7.0.94.tar.gz
RUN tar zxvf apache-tomcat-7.0.94.tar.gz
CMD ["/apache-tomcat-7.0.94/bin/catalina.sh", "run"]
EXPOSE 8080
```
EXPOSE 就是宣告有 8080 Port,在執行 Docker Container時需要把它開放出去
2. Build Docker Image 指令如下
```dockerfile
$ docker build -t tomcatporttest .
```
3. Build 完 Image 之後,使用以下的指令啟動 Docker Container 指令如下
```dockerfile
$ docker run -d -P tomcatporttest
```
4. 我們可以使用 docker ps 指令或是 docker port 指令得到對應實體主機隨機產生出來的 Port,指令和畫面如下
```dockerfile
$ docker ps -a
```
![m](
https://ithelp.ithome.com.tw/upload/images/20171223/201034566TXTdGNmfx.png)
```dockerfile=
$ docker port [CONTAINER ID]
```
![m](https://ithelp.ithome.com.tw/upload/images/20171223/20103456HL5tqCdPoi.png)
2fec91391edb 為 ContainerID
5. 上個步驟可以得出實體主機對應的 Port 為 32770,因此我們可以用實體主機的IP 和 32770 Port,連到 Tomcat 的 Web 畫面,畫面如下
![m](https://ithelp.ithome.com.tw/upload/images/20171223/201034564ZVM9dz9ow.png
### Example2
使用 Example1 的 Docker Image,在執行 docker run 時,指定小寫的-p參數,指令如下:
$ docker run -d -p 8080:8080 tomcatporttest
左邊的 8080 Port 代表指定實體主機的 Port,對應到右邊 Container 裡面的 8080 Port,畫面如下:
![m](https://ithelp.ithome.com.tw/upload/images/20171223/20103456xfGmHWcAqs.png
)
![m](
https://ithelp.ithome.com.tw/upload/images/20171223/20103456LpjjO8iT3T.png
)
### Example3
啟動 container1 的 Docker Container,然後再啟動 container2 並且 link 到 container1,最後測試看看直接在 container2 上是否 ping 得到 container1,步驟如下:
1. 啟動 container1 指令如下
```dockerfile
$ docker run -it --name container1 centos /bin/bash
```
2. 開啟另外一個視窗,啟動 container2 指令如下
```dockerfile
$ docker run -it --name container2 --link container1 centos /bin/bash
```
3. 測試 container2 是否 ping 得到 container1,畫面如下
![m](
https://ithelp.ithome.com.tw/upload/images/20171223/201034563uTD9jXVYe.png
)
## Container 之間互相的溝通:
![m](
https://ithelp.ithome.com.tw/upload/images/20171225/20103456nk2xTDWgQk.png)
上圖主要是說明 Host1 實體主機裡面有 Container1,然後 Host2 實體主機裡面有 Container2,可以透過 Docker Overlay 的 Network 的模式將 Container1 和 Container2 連接起來做溝通。另外 Consol 是一個存放連線資訊的資料庫,在使用 overlay 時必需要在 Docker 設定,這樣才能存放 overlay 網路模式的連線資訊。
另外在使用 overlay 網路模式時,要先確認 Linux Kernel 的版本。目前我使用的版本是 3.19.8 是可以正常執行的。
Example:
使用 Docker Overlay的網路模式,實作不同的實體主機之間的 container 可以互相的連接,步驟如下:
1. 切換到 root 使用者,修改 Host1 的 Docker 設定,指令如下:
$ vi /etc/docker/daemon.json
設定檔如下
{
"live-restore": true,
"group": "dockerroot",
"hosts": [
"unix:///var/run/docker.sock",
"tcp://10.1.0.221:2375"
],
"cluster-store": "consul://10.1.0.221:8500",
"cluster-advertise": "enp8s0:2375"
}
主要的設定就是 cluster-store 和 cluster-advertise,分別是要連接到 consul 的 service,取得 overlay 網路模式的連線資訊,以及設定可以讓不同實體主機連線的網路卡。
2. 重新啟動 Host1 的 Docker Service 指令如下:
```docker
systemctl restart docker
```
3. 在 Host1 使用啟動 docker container 的方式啟動 consul service,指令如下
```dockerfile
docker run -d -p 8500:8500 progrium/consul -server -bootstrap
```
4. 在 Host1,使用 docker network 指令建立一個 overlay1 的網路,指令如下
```dockerfile
docker network create -d overlay overlay1
```
使用 docker network ls,查看建立之後的結果,畫面如下
![m](
https://ithelp.ithome.com.tw/upload/images/20171225/201034563ANVBlncRj.png)
5. 在 Host1 啟動一個連接到 overlay1 的 container,指令如下
```docker
docker run -it --name=container1 --net=overlay1 busybox
```
6. 開一個新視窗,到 Host2 修改 Docker 的設定如下
$ vi /etc/docker/daemon.json
設定如下:
{
"live-restore": true,
"group": "dockerroot",
"hosts": [
"unix:///var/run/docker.sock",
"tcp://10.1.0.223:2375"
],
"cluster-store": "consul://10.1.0.221:8500",
"cluster-advertise": "enp8s0:2375"
}
以上的設定和 Host1 是很像的
7. 在 Host2 上重新啟動 Docker service 指令如下
```docker
$ systemctl restart docker
```
8. 在 Host2 上,使用 docker network ls 指令確認是否有連到 consol service,畫面如下
![m](
https://ithelp.ithome.com.tw/upload/images/20171225/20103456drGjWylBlU.png)
9. 在 Host2 上啟動一個 container,並且連到 overlay1 的網路,指令如下
```dockerfile
$ docker run -it --name=container2 --net=overlay1 busybox
```
10. 測試在 container1 ping 到 container2 的 IP
container2 的畫面如下:
![m](
https://ithelp.ithome.com.tw/upload/images/20171225/20103456oAhIyqmk7P.png)
container1 的畫面如下:
![m](
https://ithelp.ithome.com.tw/upload/images/20171225/20103456bbPY3MVvPw.png)
## Docker-Compose 範例
### Example1:
利用docker-compose啟動開發環境需要的服務
來看下面我用來啟動eureka, hystrix, rabbitmq的例子
```yaml
version: '3'
services:
eureka:
image: springcloud/eureka:latest
container_name: eureka-server
depends_on:
- "rabbitmq"
ports:
- "8761:8761"
hystrix:
image: kennedyoliveira/hystrix-dashboard:latest
container_name: hystrix-dashboard
depends_on:
- "rabbitmq"
ports:
- "7979:7979"
rabbitmq:
image: rabbitmq:3-management
container_name: rabbitmq
ports:
- "5672:5672"
- "15672:15672"
volumes:
networks:
```
先從大分區來看
version, services, volumes, networks
version: 這個docker-compose對應到的docker版本,不同版本指令略有區別
services: 就是****容器****的各項設定
image: 指定用來啟動的image
container_name: 啟動後的容器名稱
depend_on: 等待特定容器先啟動完成(****啟動順序的安排****),在這個例子中我先啟動RabbitMQ才啟動其他兩個
ports: locallost跟containers的port映射
volumes: 共用儲存空間的設定, 就是data volume
networks: 容器間內部網路的設定
由於沒有database又是透過主機的port連線,所以沒有內容
一行docker-compose up就讓我在利用steeltoeoss開發中需要的環境啟動完成
利用docker-compose啟動的過程中,產生新的image再啟動container
注意最下面的productservice,apigateway
```yaml
version: '3'
services:
eureka:
image: springcloud/eureka:latest
container_name: eureka-server
depends_on:
- "rabbitmq"
ports:
- "8761:8761"
hystrix:
image: kennedyoliveira/hystrix-dashboard:latest
container_name: hystrix-dashboard
depends_on:
- "rabbitmq"
ports:
- "7979:7979"
rabbitmq:
image: rabbitmq:3-management
container_name: rabbitmq
ports:
- "5672:5672"
- "15672:15672"
productservice:
image: productservice:latest
container_name: productservice
build:
context: ./productservice
depends_on:
- "eureka"
apigateway:
image: apigateway:latest
container_name: apigateway
environment:
- BUILD=LOCAL
build:
context: ./apigateway
depends_on:
- "rabbitmq"
- "hystrix"
```
利用****build指令,可以切換到不同目錄下然後以該目錄底下的dockerfile進行編譯後發行image****, 再依據最新的image啟動容器。當然docker-compose的步驟可以靠寫批次檔完成,但不會像使用docker-compose搭配yml這麼方便管理,利用docker-compose在localhost一次啟動所有開發所需的服務,這個還蠻實用的,當你的服務越來越多,可以幫你省下不少手動啟動跟環境設置的時間。
### Example2:
再一個空目錄下建立nginx 和php兩個目錄,首先進入nginx目錄並建立一個Dockerfile檔案
```shell
cd nginx
vi Dockerfile
```
在Dockerfile檔案中寫入如下指令
```dockerfile
FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/default.conf
```
儲存Dockerfile檔案後再建立一個default.conf內容為
```
#以下內容僅供參考,請按實際環境定製
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm index.php;
location ~ \.php$ {
fastcgi_pass php-fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/$fastcgi_script_name;
include fastcgi_params;
}
}
```
儲存檔案後再執行 cd ../php 進入php目錄 編輯Dockerfile檔案(主要增加了一些常用擴充套件,請按實際情況定製) 內容如下
```dockerfile
FROM php:7.3-fpm
RUN docker-php-ext-install pdo pdo_mysql mysqli \
&& pecl install redis-4.2.0 && docker-php-ext-enable redis
```
然後儲存,cd .. 回到外層目錄建立docker-compose.yml檔案
vi docker-compose.yml 並鍵入如下內容
```yaml
version: '3'
networks:
dev-net:
driver: bridge
services:
mysql:
image: mysql:latest
command: --default-authentication-plugin=mysql_native_password
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
networks:
- dev-net
nginx:
build: nginx
restart: always
ports:
- 80:80
volumes:
- /home/wwwroot/default/:/usr/share/nginx/html
depends_on:
- mysql
- redis
- php-fpm
networks:
- dev-net
php-fpm:
build: php
volumes:
- /home/wwwroot/default/:/usr/share/nginx/html
networks:
- dev-net
redis:
image: redis:latest
networks:
- dev-net
```
儲存後執行
docker-compose up -d
等待完成自動構建即可
## 用Docker 起一個 Mysql
**docker pull mysql:5.7** (*最新版的會有加密登入問題*)
有時候需要先刪除一些port
sudo pkill mysql
sudo pkill mysqld
* **docker run --name log_db -d -p3306:3306 --restart=always -e MYSQL_ROOT_PASSWORD=password mysql:5.7**
**以下為進入local端**
* mysql -h 127.0.0.1 -u root -p
* ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
* FLUSH PRIVILEGES;
docker stop my-mysql
docker start my-mysql
**以下為進入容器**
* docker exec -it log_db /bin/bash
* mysql -uroot -ppassword
進入mysql
* show databases;
![](https://i.imgur.com/oK1UnZA.png)
**docker inspect log_db 檢查對外連線ip**
## 用Docker 起一個 Vue
* Dockerfile
```dockerfile
FROM ubuntu:18.04
RUN apt-get update -y && apt install nodejs -y && apt install npm -y
WORKDIR /app
COPY . .
CMD ["npm", "run", "serve"]
EXPOSE 8080
```
* sudo docker build -t vue .
* sudo docker run -it -p 8080:8080 -d --name web vue
web是container的名稱
vue是image的名稱
![](https://i.imgur.com/j3peDa8.png)
# Docker Command
## Options
|Name, |shorthand |Default Description
|----------|------------| -------------------------------
|--all , |-a |Show all containers (default shows just running)
|--filter ,|-f |Filter output based on conditions provided
|--format | |Pretty-print containers using a Go template
|--last , |-n -1 |Show n last created containers (includes all states)
|--latest ,|-l |Show the latest created container (includes all states)
|--no-trunc| |Don’t truncate output
|--quiet , |-q |Only display numeric IDs
|--size , |-s | Display total file sizes
| |-d |Daemonized 背景執行container
| |-P |隨機port映射,容器內部port隨機映射到主機的port
| |**-p** |指定port映射,格式為:****主機(外網)****:****容器(內網)****
|-volume , |**-v** |將主機的檔案路徑 mapping 到 container 裡面的檔案路徑,這樣 docker container 被刪除 docker registry 的 Image 資料還會存在 </br> ex: docker run -v /主機/的路徑:/image/的路徑 image
| |**-i** |--interactive <font color="red">(互動模式)</font> 當跑的程序需要監聽輸入的時候可加入 ex: docker run -i image
| |-t, --tty |配置一個終端機
| |**-it** |互動模式通常會搭配終端機,ex: docker run -it image
|--restart=always:| |如果 container 遇到例外的情況被 stop 掉,例如是重新開機,docker 會試著重新啟動此 container
| |-e |設定docker image的環境變數 </br>ex: docker run -e APP_COLOR=red image
#### 顯示 docker 的 images 清單
* docker images
#### 刪除所有的 images
* docker rmi $(docker images -a -q)
## Container
docker start [OPTIONS] CONTAINER [CONTAINER...]
docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker restart [OPTIONS] CONTAINER [CONTAINER...]
#### 查看正在執行的 containers
* docker ps
#### 查看所有的 containers
* docker ps -a
#### 中止Container(kill)
等同強制停止container
* docker kill container_id
#### 停止所有容器
* docker stop $(docker ps -aq)
#### 刪除 container
* docker rm [Container ID]
#### 強迫刪除所有container
* docker rm $(docker ps -a -q) -f
#### 刪除硬碟裡面所有containers及image cache
* docker system prune
#### 啟動 nginx 的 Continer,使用以下的指令執行如下
* docker run -d -p 8080:80 --restart=always --name nginx nginx
參數說明:
-d:把 container 執行在背景裡
-p: 做 port 的mapping,container裡的port 80 mapping 到 host 的8080 port
--restart=always:如果 container 遇到例外的情況被 stop 掉,例如是重新開機,docker 會試著重新啟動此 container
--name:設定 container 的 name 為 nginx
最後一個參數 nginx 是 docker image 的 Name
* docker port [CONTAINER ID] 可以尋找port
#### 使用 docker run 指令的流程如下:
* (1)會試著在 local 裡找有沒有 nginx Docker Image,如果沒有會自動的從 Docker Hub 上 pull 下來
* (2)有了 Docker Image 之後從會mount Init設定 Container 系統和 mount 可讀可寫層
* (3)Container 啟動完成
#### 在執行 Container 如何看到 log
* docker logs
#### 執行特定容器
* docker exec -i -t [Container ID] bash
離開則輸入Ctrl+D
* cat /etc/hosts 查看容器內的host ip
#### 把 Container Export 成檔案
- docker export nginx > nginx.tar
- ##### 使用 import 匯入進 Docker,這時它就會是一個 Docker Image,如下:
* cat nginx.tar | docker import - nginxbak
nginxbak 是 Import 進 Docker 取得 ****Image Name****。
#### 指令把 Container重新啟動起來
* docker start
#### 停止 Container
* docker stop [CONTAINER ID]
#### 加入 VOLUME 指令,做到把資料存放在實體的主機上
docker run 指令時,指定 -v 參數,使得實體主機的資料夾路徑 Mapping 到 Container 的資料夾路徑,指令如下
* docker run -it -v /home/user1/storage:/storage centos /bin/bash
/home/user1/storage 是實體主機的資料夾路徑 Mapping 到 Container 裡面的 /storage 資料夾路徑。
* docker run -it -v /storage centos /bin/bash
若不指定實體機位置,則需要docker inspect -f '{{.Mounts}}'[CONTAINER ID]尋找
## Network <a id="docker-network"></a>
在執行 docker run 指令時,有一個參數是 ****--net****,它可以設定在執行 Docker Container 是要使用哪一種的網路模式,目前所知道的網路模式有 none、container、host、bridge、overlay… 等等的模式,它們是透過使用 Linux 的 libnetwork 所建立出來的網路模式,以下分別說明這些網路模式:
* none: 在執行 container 時,網路功能是關閉的,所以無法與此 container 連線
* container: 使用相同的 Network Namespace,所以 container1 的 IP 是 172.17.0.2 那 container2 的 IP 也會是 172.17.0.2
host: container 的網路設定和實體主機使用相同的網路設定,所以 container 裡面也就可以修改實體機器的網路設定,因此使用此模式需要考慮網路安全性上的問題
bridge: ****Docker 預設****就是使用此網路模式,這種網路模式就像是 NAT 的網路模式,例如實體主機的 IP 是 192.168.1.10 它會對應到 Container 裡面的 172.17.0.2,在啟動 Docker 的 service 時會有一個 docker0 的網路卡就是在做此網路的橋接。
overlay: container 之間可以在不同的實體機器上做連線,例如 Host1 有一個 container1,然後 Host2 有一個 container2,container1 就可以使用 overlay 的網路模式和 container2 做網路的連線。