原文地址:https://blog.csdn.net/itguangit/article/details/80222387
安裝
這里我的電腦是mac,采用brew安裝,安裝完畢記得更換國內的docker鏡像源哦.
安裝完畢,就開始使用,一探docker的神秘了.
開始之前先看一張圖:現在看不懂沒關系,之后我會解釋

Image 文件
Docker把應用程序及其依賴打包在一個image文件里面,可以理解為一個容器的說明書. 通過這個image文件可以生成容器的實例.同一個image文件可以生成同時運行的多個實例.
image文件是一個二進制文件,實際上,一個image文件往往繼承自另外一個image文件,加上一些個性化設置而成.舉例來說:你可以在ubuntu的image基礎上加上Apache服務器,形成你自己的image.
# 列出本機的所有 image 文件。 $ docker image ls # 刪除 image 文件 $ docker image rm [imageName]
並且image文件是通用的,一台機器上的image文件拷貝到另一台機器上,照樣可以使用.一般來說,我們往往是使用別人制定好的image文件,及時要定制,也可以對已有的image文件進行加工,而不是從頭制作,這樣可以節省很多時間.
為了方便,image制作完成后,可以上傳到網上的倉庫,Docker 的官方倉庫 https://hub.docker.com/ 是最重要、最常用的 image 倉庫。此外,出售自己制作的 image 文件也是可以的。
實例: Hello world
下面,我們通過最簡單的 image 文件“hello world”,感受一下 Docker。
首先,運行下面的命令,將 image 文件從倉庫抓取到本地。
1 $ docker image pull library/hello-world
上面的代碼中,docker image pull 是抓取image文件的命令,library/hello-world是image文件在倉庫里面的位置,其中library是image文件所在的組,hello-world是image文件的名字.
由於Docker官方提供的文件都放在library組里面,所以他是默認組,可以省略.因此上面的命令可以寫成下面這樣:
$ docker image pull hello-world
抓取成功后就可以看到本地的image文件了,
ig:~ itguang$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest e38bc07ac18e 3 weeks ago 1.85kB
現在運行這個image文件,可以看到如些輸出:
1 ig:~ itguang$ docker container run hello-world 2 3 Hello from Docker! 4 This message shows that your installation appears to be working correctly. 5 6 To generate this message, Docker took the following steps: 7 1. The Docker client contacted the Docker daemon. 8 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. 9 (amd64) 10 3. The Docker daemon created a new container from that image which runs the 11 executable that produces the output you are currently reading. 12 4. The Docker daemon streamed that output to the Docker client, which sent it 13 to your terminal. 14 15 To try something more ambitious, you can run an Ubuntu container with: 16 $ docker run -it ubuntu bash 17 18 Share images, automate workflows, and more with a free Docker ID: 19 https://hub.docker.com/ 20 21 For more examples and ideas, visit: 22 https://docs.docker.com/engine/userguide/
docker container run 會從一個鏡像文件中生成一個容器實例,並且運行它.注意,docker container run命令具有自動抓取 image 文件的功能。如果發現本地沒有指定的 image 文件,就會從倉庫自動抓取。因此,前面的docker image pull命令並不是必需的步驟。
待上面那段提示輸出后,hello-world就會停止運行,容器就會終止.
有些容器不會終止,因為提供的是服務,比如安裝unbuntu的image,就可以在命令行體驗unbutu系統.
對於那些不會自動終止的容器,必須使用docker container kill [container_id]來終止.
我們可以新打開一個終端窗口:
ig:~ itguang$ docker container ls # 查看當前運行容器 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 649a6b785a86 ubuntu "bash" 3 seconds ago Up 4 seconds loving_austin ig:~ itguang$ docker container kill 649a6b785a86 # 殺死某個容器 649a6b785a86 ig:~ itguang$ docker container ls 再次查看 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ig:~ itguang$
container 容器文件
image文件生成的實例本身也是一個文件,成為容器文件.也即是說,一旦容器生成,就會存在兩個文件:一個image文件,一個容器文件.而且關閉容器並不會刪除容器文件,只是容器停止運行而已.
1 # 列出本機正在運行的容器 2 $ docker container ls 3 4 # 列出本機所有容器,包括終止運行的容器 5 ig:~ itguang$ docker container ls --all 6 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7 649a6b785a86 ubuntu "bash" 10 minutes ago Exited (137) 9 minutes ago loving_austin 8 85b9c705e73f hello-world "/hello" 10 minutes ago Exited (0) 10 minutes ago silly_lumiere 9 c9281ad7f7b8 ubuntu "bash" 17 minutes ago Exited (127) 11 minutes ago stupefied_curran 10 e06bf36259ef hello-world "/hello" 24 minutes ago Exited (0) 24 minutes ago flamboyant_chaplygin 11 ig:~ itguang$
可以看出,我現在已經有了四個容器,終止運行的容器文件依然會占用硬盤空間,可以使用docker container rm [container_id]命令刪除.
1 ig:~ itguang$ docker container ls --all 2 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3 c9281ad7f7b8 ubuntu "bash" 22 minutes ago Exited (127) 17 minutes ago stupefied_curran 4 e06bf36259ef hello-world "/hello" 29 minutes ago Exited (0) 29 minutes ago flamboyant_chaplygin 5 ig:~ itguang$ docker container rm c9281ad7f7b8 e06bf36259ef
Dockerfile 文件
學會了如何使用image文件和生成容器文件之后,接下來你可能會想直到這個image文件是如何生成的呢?如果你要推廣自己的軟件,勢必要制作自己的image文件.
這時候就要用到Dockerfile文件,他是一個文本文件,用來配置image.Docker容器根據Dockerfile文件生成image二進制文件.
下面通過一個實例,來演示如何編寫Dockerfile文件生成自己的image二進制文件.
實例:制作自己的 Docker 容器
下面我以 koa-demos 項目為例,介紹怎么寫 Dockerfile 文件,實現讓用戶在 Docker 容器里面運行 Koa 框架。
- 1.先下載源代碼:
1 $ git clone https://github.com/ruanyf/koa-demos.git 2 $ cd koa-demos
- 2.編寫 Dockerfile 文件
首先,在項目的根目錄下,新建一個文本文件.dockerignore,寫入下面的內容。
1 .git 2 node_modules 3 npm-debug.log
上面的代碼表示,這三個路徑要排除,不要打包進image文件,如果你沒有路徑可以排除,這個文件也可以不用建立.
然后在項目根目錄下再新建一個Dockerfile文本文件,寫入下面的內容:
1 FROM node:8.4 2 COPY . /app 3 WORKDIR /app 4 RUN npm install --registry=https://registry.npm.taobao.org 5 EXPOSE 3000
上面代碼解釋如下:
1 From node:8.4 : 該image繼承自官方的node image,冒號表示標簽,這里表示8.4,即8.4版本的node. 2 3 COPY . /app :將當前目錄下的所有文件都拷貝到image文件的 /app 目錄. 4 5 WORKDIR /app : 指定接下來的工作目錄為 /app . 6 7 RUN npm install:在/app目錄下,運行npm install命令安裝依賴。注意,安裝后所有的依賴,都將打包進入 image 文件。 8 9 EXPOSE 3000 : 將容器的3000 端口暴露出來,允許外部連接這個端口.
- 創建 image 文件.
有了 Dockerfile文件以后就可以使用 docker image build 命令創建image文件了.
1 $ docker image build -t koa-demo . 2 # 或者 3 $ docker image build -t koa-demo:0.0.1 .
上面代碼中,-t參數用來指定image文件的名字,后面還可以用冒號指定標簽,如果不指定,默認標簽就是latest,最后那個.表示Dockerfile文件所在的路徑.這個例子Dockerfile文件在當前路徑,所以就是一個.
如果構建成功,會有如下提示信息:
1 ... 2 Successfully built 979e0930e4b6 3 Successfully tagged koa-demo:latest
我們使用docker images 查看當前的image文件
1 ig:koa-demos itguang$ docker images 2 REPOSITORY TAG IMAGE ID CREATED SIZE 3 koa-demo latest 979e0930e4b6 About a minute ago 676MB 4 ubuntu latest 452a96d81c30 8 days ago 79.6MB 5 hello-world latest e38bc07ac18e 3 weeks ago 1.85kB 6 node 8.4 386940f92d24 8 months ago 673MB
- 生成容器
前面講過,docker container run 命令會從image文件生成容器,
1 $ docker container run -p 8000:3000 -it koa-demo /bin/bash 2 # 或者 3 $ docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash
上面各個參數解釋如下:
1 -p : 容器的3000端口映射到本地的8000端口. 2 3 -it : 容器的shell會映射到當前本地的shell,你在本機窗口輸入的命令會傳入到容器中. 4 5 koa-demo:0.0.1 :image 文件的名字(如果有標簽,還需要提供標簽,默認是 latest 標簽)。 6 7 /bin/bash : 容器啟動以后,容器內部第一個執行的命令.這里是啟用Bash,以保證用戶可以使用shell
如果一切正常,運行上面的命令以后,就會返回一個命令行提示符。
root@6be4c4a279df:/app#
這表示你已經在容器里面了,返回的提示符就是容器內部的 Shell 提示符。執行下面的命令。
root@6be4c4a279df:/app# node demos/01.js
這時,Koa 框架已經運行起來了。打開本機的瀏覽器,訪問 http://127.0.0.1:8000,網頁顯示”Not Found”,這是因為這個 demo 沒有寫路由。
這個例子中node進程運行在Docker容器的虛擬環境里面,進程接觸到的文件系統和網絡接口都是虛擬的,與本機文件系統和網絡接口都是隔離的,因此需要定義容器與物理機的端口映射(map).
現在,在容器的命令行下,按ctrl+c停止node進程,按ctrl+d(或者exit)退出容器.此外,也可以使用docker container kill [container-id]終止容器的運行.
1 # 在本機的另一個終端窗口,查出容器的 ID 2 $ docker container ls 3 4 # 停止指定的容器運行 5 $ docker container kill [containerID]
也可以使用docker container run 命令的 --rm 參數,在容器終止運行后自動刪除容器文件.
1 $ docker container run --rm -p 8000:3000 -it koa-demo /bin/bash
CMD 命令
上一節的例子里面,容器啟動以后,需要手動輸入命令node demos/01.js。我們可以把這個命令寫在 Dockerfile 里面,這樣容器啟動以后,這個命令就已經執行了,不用再手動輸入了。
1 FROM node:8.4 2 COPY . /app 3 WORKDIR /app 4 RUN npm install --registry=https://registry.npm.taobao.org 5 EXPOSE 3000 6 CMD node demos/01.js
上面的Dockerfile文件最后面多了一行CMD node demos/01.js,表示容器啟動后,自動執行node demos/01.js.
你可能會問RUN 命令和 CMD 命令的區別是什么呢?
簡單來說:RUN命令在image文件的構建階段執行,執行結果會打包進image文件;CMD命令則是在容器啟動后執行.另外一個Dockerfile文件只能包含多個RUN命令,但只能包含一個CMD命令,
注意:制定了CMD命令后,docker container run命令就不能附加命令了,比如前面的/bin/bash,否則,它會覆蓋CMD命令
現在啟動容器可以用下面的命令:
1 $ docker container run --rm -p 8000:3000 -it koa-demo:0.0.1
發布image文件
容器運行成功后,就確認了image文件的有效性,這是我們就可以考慮把image文件分享到網上.
首先,去 hub.docker.com 或 cloud.docker.com注冊一個賬戶。然后,用下面的命令登錄。
1 $ docker login
接着,為本地的 image 標注用戶名和版本。
1 $ docker image tag [imageName] [username]/[repository]:[tag] 2 # 實例 3 $ docker image tag koa-demos:0.0.1 ruanyf/koa-demos:0.0.1
也可以不標注用戶名,重新構建一下 image 文件。
1 $ docker image build -t [username]/[repository]:[tag] .
最后,發布 image 文件。
1 $ docker image push [username]/[repository]:[tag]
發布成功以后,登錄 hub.docker.com,就可以看到已經發布的 image 文件。
其他有用的命令
docker的主要用法就是上面這些,另外還有一些常見的命令:
docker container start
前面的docker container run命令是新建容器,每運行一次,就會新建一個容器.同樣的命令運行兩次就會生成兩個一模一樣的容器文件.如果希望重復使用容器,就需要使用docker container start命令,它用來啟動已經生成,已經停止運行的容器文件.
$ docker container start [container_id]
docker container stop
前面的docker container kill命令終止容器的運行,相當於向容器的主進程發送SIGKILL信號,而docker container stop也是用來終止容器的運行,相當於向容器的主進程發送SIGTERM信號,然后過一段時間在發送SIGKILL信號.
$ docker container stop [container_id]
這個信號的差別就是,程序收到SIGTERM信號后,可自行進行收尾清理工作,但也可以不理會這個信號;但如果收到SIGKILL信號,就會立即終止這個容器的運行,那些正在進行的操作會全部丟失
docker container logs
docker container logs用來查看容器的輸出,即容器里shell的標准輸出.比如: 如果docker run命令運行容器的時候,沒有使用-it參數,就要使用這個命令查看輸出.
$ docker container logs [container_id]
docker container exec
docker container exec命令用於進行一個正在運行的容器.如果docker container run命令運行容器的時候,沒有使用-it參數,就要使用這個命令進入進入容器,一旦進入容器,就可以在容器的shell執行命令了.
$ docker container exec [container_id] /bin/bash
docker container cp
docker container cp命令用於從正在運行的容器里,將文件拷貝到本機.下面是拷貝當前 目錄的寫法:
$ docker container cp [container_id]:[/path/to/file] .
總結
到了這里相信你對docker的基本操作與相關概念已經有了大概了解,現在讓我們回到文章開頭的那個圖:

可以看出: Dockerfile,Docker hub,image鏡像文件,container容器文件,容器實例 的關系一目了然.
- image文件來源有兩個:Dockfile文件和Docker hub.
- 可以使用
docker container run命令從image文件生成並運行容器.
關於docker常用命令我在這里進行了詳細總結:
