--- 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 做網路的連線。