簡述
Docker是一個(gè)開源的引擎,可以輕松的為任何應(yīng)用創(chuàng)建一個(gè)輕量級(jí)的壹店、可移植的奉狈、自給自足的容器。
開發(fā)者在筆記本上編譯測試通過的容器可以批量地在生產(chǎn)環(huán)境中部署备畦,包括VMs(虛擬機(jī))低飒、bare metal、OpenStack 集群和其他的基礎(chǔ)應(yīng)用平臺(tái)萍恕。
Docker通常用于如下場景:
- web應(yīng)用的自動(dòng)化打包和發(fā)布逸嘀;
- 自動(dòng)化測試和持續(xù)集成、發(fā)布允粤;
- 在服務(wù)型環(huán)境中部署和調(diào)整數(shù)據(jù)庫或其他的后臺(tái)應(yīng)用崭倘;
- 從頭編譯或者擴(kuò)展現(xiàn)有的OpenShift或Cloud Foundry平臺(tái)來搭建自己的PaaS環(huán)境。
準(zhǔn)備
Docker系統(tǒng)有兩個(gè)程序:docker服務(wù)端和docker客戶端类垫。
其中docker服務(wù)端是一個(gè)服務(wù)進(jìn)程司光,管理著所有的容器。
docker客戶端則扮演著docker服務(wù)端的遠(yuǎn)程控制器悉患,可以用來控制docker的服務(wù)端進(jìn)程残家。
大部分情況下,docker服務(wù)端和客戶端運(yùn)行在一臺(tái)機(jī)器上售躁。
安裝docker (我是在ubuntu上安裝的 其他環(huán)境類似)
sudo apt-get install -y docker.io
查看version版本
docker version
Client:
Version: 1.12.3
API version: 1.24
Go version: go1.6.3
Git commit: 6b644ec
Built: Wed Oct 26 21:44:32 2016
OS/Arch: linux/amd64
Server:
Version: 1.12.3
API version: 1.24
Go version: go1.6.3
Git commit: 6b644ec
Built: Wed Oct 26 21:44:32 2016
OS/Arch: linux/amd64
以上可知docker環(huán)境已經(jīng)裝好了坞淮。
hello-world
現(xiàn)在讓我們運(yùn)行一下茴晋,docker的hello world~
docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker Hub account:
https://hub.docker.com
For more examples and ideas, visit:
https://docs.docker.com/engine/userguide/
由上可知,在我們運(yùn)行 docker run hello-world
命令后回窘,docker經(jīng)歷了一下四個(gè)步驟诺擅。
- docker客戶端連接服務(wù)器端的守護(hù)進(jìn)程。
- docker服務(wù)器端的守護(hù)進(jìn)程從 Docker Hub拉取"hello-world"鏡像啡直。
- docker服務(wù)器端的守護(hù)進(jìn)程根據(jù)拉取的鏡像創(chuàng)建一個(gè)容器烁涌,在容器中運(yùn)行了一個(gè)可執(zhí)行程序輸出了你剛才看到的一串信息。
- docker服務(wù)器端進(jìn)程將輸出傳給docker客戶端酒觅,顯示在你的終端上撮执。
提示中,還建議我們運(yùn)行docker run -it ubuntu bash
命令舷丹。
當(dāng)我們運(yùn)行以上命令時(shí)抒钱,可以發(fā)現(xiàn)我們進(jìn)入了一個(gè)ubunt bash環(huán)境。
就好像進(jìn)入到一個(gè)運(yùn)行ubuntu系統(tǒng)的虛擬機(jī)一樣掂榔。
Images & Container
Images和Container就好比是系統(tǒng)鏡像ISO鏡像文件和虛擬機(jī)的關(guān)系继效。
Images就好比系統(tǒng)鏡像,Vmware可以通過系統(tǒng)鏡像創(chuàng)建虛擬機(jī)装获,docker也可以通過Images創(chuàng)建Container瑞信。
Container就好比一個(gè)虛擬機(jī),我們可以在里面運(yùn)行服務(wù)穴豫,也可以登錄進(jìn)去運(yùn)行命令凡简,查看文件。
相關(guān)命令:
docker ps //查看系統(tǒng)中運(yùn)行的docker容器
docker kill [container] //刪除docker容器
docker stop [container] //停止正在運(yùn)行的docker容器
docker attach/exec [container] //進(jìn)入容器
docker run //運(yùn)行鏡像精肃,生成容器
docker images //查看系統(tǒng)中存在的docker鏡像
docker rmi [image] //刪除鏡像
docker build //生成鏡像
docker pull //拉取鏡像
docker push //上傳鏡像
docker search //搜索鏡像
Dockerfile詳解
- 指定基礎(chǔ)image
FROM <image>:<tag>
- 指定鏡像創(chuàng)建者信息
MAINTAINER <name>
- 安裝軟件 (該指令有兩種形式)
RUN <command> (the command is run in a shell - `/bin/sh -c`)
RUN ["executable", "param1", "param2" ... ] (exec form)
- 設(shè)置container啟動(dòng)時(shí)執(zhí)行的操作
CMD ["executable","param1","param2"] (like an exec, this is the preferred form)
CMD command param1 param2 (as a shell)
//當(dāng)Dockerfile指定了ENTRYPOINT秤涩,那么使用下面的格式:
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
- 設(shè)置container啟動(dòng)時(shí)執(zhí)行的操作
ENTRYPOINT ["executable", "param1", "param2"] (like an exec, the preferred form)
ENTRYPOINT command param1 param2 (as a shell)
<!--該指令的使用分為兩種情況,一種是獨(dú)自使用司抱,另一種和CMD指令配合使用筐眷。
當(dāng)獨(dú)自使用時(shí),如果你還使用了CMD命令且CMD是一個(gè)完整的可執(zhí)行的命令习柠,那么CMD指令和ENTRYPOINT會(huì)互相覆蓋只有最后一個(gè)CMD或者ENTRYPOINT有效匀谣。
另一種用法和CMD指令配合使用來指定ENTRYPOINT的默認(rèn)參數(shù),這時(shí)CMD指令不是一個(gè)完整的可執(zhí)行命令资溃,僅僅是參數(shù)部分武翎;
ENTRYPOINT指令只能使用JSON方式指定執(zhí)行命令,而不能指定參數(shù)溶锭。-->
- 設(shè)置container容器的用戶(默認(rèn)root)
USER root
- 指定容器需要映射到宿主機(jī)器的端口
EXPOSE <port> [<port>...]
# 映射一個(gè)端口
EXPOSE port1
# 相應(yīng)的運(yùn)行容器使用的命令
docker run -p port1 image
# 映射多個(gè)端口
EXPOSE port1 port2 port3
# 相應(yīng)的運(yùn)行容器使用的命令
docker run -p port1 -p port2 -p port3 image
# 還可以指定需要映射到宿主機(jī)器上的某個(gè)端口號(hào)
docker run -p host_port1:port1 -p host_port2:port2 -p host_port3:port3 image
- 設(shè)置環(huán)境變量
ENV <key> <value>
- 從src復(fù)制文件到container的dest路徑
COPY <src> <dest>
- 從src復(fù)制文件到container的dest路徑
ADD <src> <dest>
<src> 是相對(duì)被構(gòu)建的源目錄的相對(duì)路徑宝恶,可以是文件或目錄的路徑,也可以是一個(gè)遠(yuǎn)程的文件url,如果是壓縮包會(huì)被自動(dòng)解壓。
<dest> 是container中的絕對(duì)路徑s
- 指定掛載點(diǎn)
//設(shè)置指令垫毙,使容器中的一個(gè)目錄具有持久化存儲(chǔ)數(shù)據(jù)的功能霹疫,該目錄可以被容器本身使用,也可以共享給其他容器使用综芥。
VOLUME ["<mountpoint>"]
eg:
VOLUME ["/tmp/data"]
- 切換目錄
WORKDIR /path/to/workdir
# 在 /p1/p2 下執(zhí)行 vim a.txt
WORKDIR /p1 WORKDIR p2 RUN vim a.txt
- 在子鏡像中執(zhí)行
ONBUILD <Dockerfile關(guān)鍵字>
docker中運(yùn)行express項(xiàng)目
現(xiàn)在讓我們開始實(shí)戰(zhàn)一下更米,生成一個(gè)express項(xiàng)目,將之使用docker部署毫痕。
生成express項(xiàng)目
使用express-generator生成expess項(xiàng)目。
npm install -g express-generator
express express-jerrwy
//可以看到項(xiàng)目創(chuàng)建出來了迟几,目錄如下
app.js bin node_modules package.json public routes views
安裝依賴
npm i
//運(yùn)行項(xiàng)目
npm start
訪問localhost:3000可以看到express 歡迎頁面消请,表示express項(xiàng)目創(chuàng)建成功。
編寫Dokerfile
在項(xiàng)目根目錄类腮,新建一個(gè)Dockerfile文件臊泰,該文件名就叫Dockerfile,注意大小寫,沒有后綴蚜枢,否則會(huì)報(bào)錯(cuò)缸逃。
Dockerfile文件定義了如何創(chuàng)建Docker鏡像。
我的Dockerfile如下:
FROM node:6.9.1
USER root
RUN npm config set registry https://registry.npm.taobao.org
WORKDIR /var/workspace
COPY package.json /var/workspace/package.json
RUN npm install && npm cache clean
COPY . /var/workspace
大致解釋一下里面做了什么:
- 我使用基礎(chǔ)鏡像 node:6.9.1,也就是一個(gè)鏡像厂抽,里面裝了node 6.9.1
- 我鏡像里面使用的用戶是root
- 執(zhí)行命令需频,設(shè)置 npm源
- 設(shè)置鏡像的工作目錄
- 將package.json拷貝到鏡像的工作目錄中
- 安裝依賴
- 將項(xiàng)目代碼拷貝到工作目錄
生成鏡像
Dockerfile寫好之后,我們就可以生成鏡像了筷凤。
docker build . -t moyunchen/express-jerrwy:test
moyunchen/express-jerrwy:test
中moyunchen
是我docker hub的賬號(hào)名昭殉,express-jerrwy
是鏡像名稱,test
是鏡像標(biāo)簽藐守,相當(dāng)于版本號(hào)挪丢。
第一次生成鏡像由于要下載基礎(chǔ)鏡像,速度可能比較慢卢厂,稍等十幾分鐘乾蓬,出去喝杯茶~。
生成成功之后慎恒,運(yùn)行命令:
docker images
//可以看到
REPOSITORY TAG IMAGE ID CREATED SIZE
moyunchen/express-jerrwy test 754d9122fa3e 13 hours ago 663.7 MB
表明你的docker鏡像已經(jīng)生成啦~
其實(shí)任内,現(xiàn)在你就已經(jīng)可以運(yùn)行鏡像,生成容器了巧号。
docker run -itd -p 3000:3000 --name express01 moyunchen/express-jerrwy:test npm start
打開localhost:3000 我們可以看到express歡迎信息族奢。說明我們的exress項(xiàng)目在docker部署成功了。
查看docker容器
docker ps
//可以看到
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b8106d910823 moyunchen/express-jerrwy:test "npm start" 6 seconds ago Up 4 seconds 0.0.0.0:3000->3000/tcp express01
這就是我們正在運(yùn)行中的docker容器丹鸿,里面跑了我們的express服務(wù)越走。
登錄進(jìn)去看看
docker exec -it b8106d910823 bash
//可以看到
root@b8106d910823:/var/workspace# ls
Dockerfile app.js bin node_modules package.json public routes views
這個(gè)就是docker中項(xiàng)目目錄中我們的項(xiàng)目代碼。
push鏡像到docker hub
docker hub就好比github,是官方的鏡像公有倉庫。
我們將鏡像發(fā)布到這個(gè)上面廊敌,其他人就可以直接將你的鏡像pull下來铜跑,然后運(yùn)行。
就不用單獨(dú)的把代碼pull下來骡澈,自己build鏡像了锅纺。
登錄docker賬號(hào)
docker login
//接下來他會(huì)讓你輸入賬號(hào)密碼郵箱
Username: [username]
Password: [password]
Email: xxxx@foxmail.com
WARNING: login credentials saved in /root/.docker/config.json
Login Succeeded
push鏡像到docker hub倉庫
docker push moyunchen/express-jerrwy:test
moyunchen
是你的docker賬號(hào)名,生成鏡像的時(shí)候也必須是 [username]/[imagename]
這種格式
push的過程異常緩慢肋殴。囤锉。。我這里用了幾個(gè)小時(shí)护锤。官地。。只是第一次才慢烙懦,后面是增量更新就會(huì)快很多驱入。。
成功之后氯析,登錄docker hub就可以看到你的鏡像了亏较。
從docker hub拉取鏡像,生成容器
現(xiàn)在掩缓,你的鏡像推送到了docker hub上面了雪情,讓你的項(xiàng)目伙伴拉取項(xiàng)目鏡像,運(yùn)行起來拾因。
拉取鏡像
docker pull moyunchen/express-jerrwy:test
運(yùn)行鏡像旺罢,創(chuàng)建容器的步驟,跟上面一樣绢记。
docker-compose
docker-compose是用于定義和運(yùn)行復(fù)雜Docker應(yīng)用的工具扁达。
你可以在一個(gè)文件中定義一個(gè)多容器的應(yīng)用,然后使用一條命令來啟動(dòng)你的應(yīng)用蠢熄,然后所有相關(guān)的操作都會(huì)被自動(dòng)完成跪解。
在上面過程中,我們運(yùn)行容器的命令過于復(fù)雜签孔,而且一次只能啟動(dòng)一個(gè)docker應(yīng)用叉讥,管理起來也不是很方便。
于是就有懶惰
的程序員創(chuàng)建了docker-compose
安裝
以u(píng)buntu系統(tǒng)舉例
curl -L https://github.com/docker/compose/releases/download/1.3.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
//這個(gè)裝起來也好慢饥追。图仓。。是因?yàn)閴Φ脑虬傻啤救崔!?
安裝完成之后
docker-compose --version
//可以看到
docker-compose 1.8.1
到這里惶看,你的docker-compose就算安裝成功了。
docker-compose.yml
docker-compose.yml文件的目的是定義了一組應(yīng)用六孵,可以很方便的對(duì)多個(gè)應(yīng)用進(jìn)行發(fā)布纬黎。
我的理解是取代了docker run
,因?yàn)閐ocker run 命令使用起來過于繁瑣劫窒。
當(dāng)然本今,如果你不想用docker-compose,你可以將對(duì)于的docker-compose.yml翻譯成docker run語法主巍。
還是以上面的express-jerrwy鏡像為例冠息,對(duì)應(yīng)的 docker-compose.yml文件
version: '2'
services:
express-jerrwy:
ports:
- "3000:3000"
image: "docker.io/moyunchen/express-jerrwy:test"
container_name: "express-jerrwy"
restart: always
command: "npm start"
現(xiàn)在docker-compose.yml寫好了,上面我們只定義了express-jerrwy一個(gè)docker服務(wù),我們完全可以一次定義多個(gè)孕索。
我們現(xiàn)在創(chuàng)建容器
docker-compose up -d
關(guān)閉容器
docker-compose down
以后我們部署項(xiàng)目铐达,就只需要寫好docker-compose.yml文件,就可以利用docker-compose進(jìn)行項(xiàng)目部署檬果。
是不是簡單了很多。
daocloud
上面我們用的docker hub 為公有倉庫唐断。
我們發(fā)布的應(yīng)用鏡像是所有人都可以下載得到的选脊。
如果使我們公司的項(xiàng)目,里面含有一個(gè)不能公開的東西脸甘,那公有倉庫也就不適合我們了恳啥。
所以我們就可以使用私有倉庫,例如 daocloud
使用方法跟公有倉庫區(qū)別不大丹诀。