剛接觸Docker的時候,覺得只是用來作運維。後來真正用的時候才發覺,這個Docker簡直是個神器。無論什麼開發場景都能輕鬆應付。想要什麼環境都能隨意生成,並且靈活性更高,更輕量,完美實現微服務
的概念。python
Docker
Docker
是一個開源的應用容器引擎,基於Go
語言 並聽從Apache2.0協議開源。傳統虛擬機技術是虛擬出一套硬件後,在其上運行一個完整操做系統,在該系統上再運行所需應用進程;而容器內的應用進程直接運行於宿主的內核,容器內沒有本身的內核,並且也沒有進行硬件虛擬。它佔用的資源更少,能作到的事更多。linux
特性 | 容器 | 虛擬機 |
---|---|---|
啓動 | 秒級 | 分鐘級 |
硬盤啓動 | 通常爲MB | 通常爲GB |
性能 | 接近原生 | 弱於 |
系統支持量 | 單機支持上千個容器 | 通常幾十個 |
Docker
安裝的方法都挺簡單的,我用的是mac,直接經過Docker官網下載軟件安裝,全程無障礙。nginx
Docker
概念images
):Docker鏡像是一個特殊的文件系統,除了提供容器運行時所需的程序、庫、資源、配置等文件外,還包含了一些爲運行時準備的一些配置參數(如匿名卷、環境變量、用戶等)。鏡像不包含任何動態數據,其內容在構建以後也不會被改變。(直白點能夠理解爲系統安裝包)container
):鏡像和容器的關係,就像是面向對象程序設計中的類
和實例
同樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器能夠被建立、啓動、中止、刪除、暫停等。(能夠理解爲安裝好的系統)大概瞭解了Docker的概念之後,咱們就嘗試拉取flask鏡像使用一下。 查找鏡像能夠經過hub.docker.com/網站來搜索,或者經過命令搜索。web
docker search flask
複製代碼
alpine
是精簡版的linux,體積更小、運行的資源消耗更少。
# 拉取鏡像
docker pull tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8
# 下載好可查看鏡像列表是否存在
docker images
複製代碼
下載鏡像之後,就開始運行下試試,感覺一下Docker的輕量、快捷。 首先建立個flask運行文件來,在這裏,我建立了/docker/flask
做爲項目文件,而後在根目錄下再建立個app
文件夾來存放main.py
文件,代碼以下:redis
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World from Flask!"
if __name__ == "__main__":
# 測試環境下才開啓debug模式
app.run(host='0.0.0.0', debug=True, port=80)
複製代碼
如今的文件結構:docker
flask
└── app
└── main.py
複製代碼
運行命令數據庫
docker run -it --name test -p 8080:80 -v /docker/flask/app:/app -w /app tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8 python main.py
複製代碼
這裏說明一下命令的參數含義: -it
是將-i -t合併起來,做用是能夠用指定終端對容器執行命令交互。 --name
對容器進行命名。 -p
將主機的8080端口映射到容器的80端口。 -v
將主機的/docker/flask/app文件掛載到容器的/app文件,若是容器內沒有的話會自動建立。 -w
將/app文件做爲工做區,後面的執行命令都默認在該文件路徑下執行。 tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8
鏡像名跟標籤。 python main.py
經過python來運行工做區的main.py文件。 運行結果:flask
在使用別人定製的鏡像時老是不能盡善盡美的,若是在本身項目裏面,不能每次都是拉取下來從新配置一下。像上面的鏡像,我可不喜歡這麼長的名字,想一想每次要敲這麼長的名字都頭疼(tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8)。vim
打開咱們剛纔的/docker/flask路徑,在根目錄下建立Dockerfile文件,內容以下。瀏覽器
# 基礎鏡像
FROM tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8
# 沒有vim來查看文件很不習慣,利用alpine的包管理安裝一個來
RUN apk add vim
# 順便用pip安裝個redis包,後面用得上
RUN pip3 install redis
# 將咱們的app文件加入到自定義鏡像裏面去
COPY ./app /app 複製代碼
如今咱們的文件結構是:
flask
├── app
│ └── main.py
└── Dockerfile
複製代碼
剩下的就跑一遍就OK啦!記得必定要在Dockerfile
文件同級目錄下執行build命令。
docker build -t myflask .
Sending build context to Docker daemon 4.608kB
Step 1/4 : FROM tiangolo/uwsgi-nginx-flask:python3.7-alpine3.8
---> c69984ff0683
Step 2/4 : RUN apk add vim
---> Using cache
---> ebe2947fcf89
Step 3/4 : RUN pip3 install redis
---> Running in aa774ba9030e
Collecting redis
Downloading https://files.pythonhosted.org/packages/f5/00/5253aff5e747faf10d8ceb35fb5569b848cde2fdc13685d42fcf63118bbc/redis-3.0.1-py2.py3-none-any.whl (61kB)
Installing collected packages: redis
Successfully installed redis-3.0.1
Removing intermediate container aa774ba9030e
---> 47a0f1ce8ea2
Step 4/4 : COPY ./app /app
---> 50908f081641
Successfully built 50908f081641
Successfully tagged myflask:latest
複製代碼
-t
指定要建立的目標路徑。 .
這裏有個點記住啦,表示是當前路徑下的Dockerfile文件,能夠指定爲絕對路徑。 編譯完後就經過docker images
查看一下,就能看到myflask鏡像了,裏面能直接運行python main.py
來啓動flask,而且內置了vim和redis包。
Docker Compose
讓多容器成爲一個總體咱們的每一個容器都負責一個服務,這樣容器多的時候一個個手動啓動的話是不現實的。在這種狀況咱們能夠經過Docker Compose
來關聯每一個容器,組成一個完整的項目。
Compose
項目由Python
編寫,實現上調用了Docker
服務提供的 API 來對容器進行管理。
# 安裝docker-compose
sudo pip3 install docker-compose
複製代碼
在這裏,咱們經過docker-compose.yml
文件來啓動flask
容器和redis
容器,並將兩個不一樣容器相互關聯起來。 首先在/docker/flask目錄下建立docker-compose.yml
文件,內容以下:
version: '3'
services:
flask:
image: myflask
container_name: myflask
ports:
- 8080:80
volumes:
- /docker/flask/app:/app
working_dir: /app
# 運行後執行的命令
command: python main.py
redis:
# 若是沒有這個鏡像的話會自動下載
image: "redis:latest"
container_name: myredis
複製代碼
而後咱們把上面的main.py
代碼修改一下,鏈接redis數據庫並記錄網站訪問次數。main.py
修改後內容以下:
from flask import Flask
from redis import Redis
app = Flask(__name__)
redis = Redis(host='redis', port=6379)
@app.route("/")
def hello():
count = redis.incr('visit')
return f"Hello World from Flask! 該頁面已被訪問{count}次。"
if __name__ == "__main__":
# Only for debugging while developing
app.run(host='0.0.0.0', debug=True, port=80)
複製代碼
目前的文件結構是:
flask
├── app
│ └── main.py
└── Dockerfile
└── docker-compose.yml
複製代碼
這些編排的文件參數都是取自於Docker
,基本都能看懂,其它就沒啥啦,直接命令行跑起來:
docker-compose up
複製代碼
就辣麼簡單!如今咱們在瀏覽器上訪問http://localhost:8080/
就能看到結果了,而且每訪問一次這頁面都會自動增長訪問次數.
docker ps
命令查看運行中的容器:
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
66133318452d redis:latest "docker-entrypoint.s…" 13 seconds ago Up 12 seconds 6379/tcp myredis
0956529c3c9c myflask "/entrypoint.sh pyth…" 13 seconds ago Up 11 seconds 443/tcp, 0.0.0.0:8080->80/tcp myflask
複製代碼
有了Docker Compose
的Docker
纔是完整的Docker
,有了這些之後開發簡直不要太爽,每一個容器只要維護本身的服務環境就ok了。
# 下載鏡像
docker pull name
# 列出本地鏡像
docker images
# 使用鏡像運行生成容器
docker run name:tag
# 刪除鏡像
docker rmi id/name
複製代碼
能夠經過容器的id或者容器別名來啓動、中止、重啓。
# 查看運行中的容器
docker ps
# 查看全部生成的容器
docker ps -a
# 開始容器
docker start container
# 中止容器
docker stop container
# 重啓容器
docker restart container
# 移除不須要的容器(移除前容器必需要處於中止狀態)
docker rm container
# 進入後臺運行的容器
docker exec -it container /bin/sh
# 打印容器內部的信息(-f參數能實時觀察內部信息)
docker logs -f container
複製代碼
經過-i -t
進來容器的,能夠先按ctrl + p
, 而後按ctrl + q
來退出交互界面組,這樣退出不會關閉容器。
# 自動完成包括構建鏡像,(從新)建立服務,啓動服務,並關聯服務相關容器的一系列操做。
docker-compose up
# 此命令將會中止 up 命令所啓動的容器,並移除網絡
docker-compose down
# 啓動已經存在的服務容器。
docker-compose start
# 中止已經處於運行狀態的容器,但不刪除它。經過start能夠再次啓動這些容器。
docker-compose stop
# 重啓項目中的服務
docker-compose restart
複製代碼
默認狀況,docker-compose up
啓動的容器都在前臺,控制檯將會同時打印全部容器的輸出信息,能夠很方便進行調試。當經過Ctrl-C
中止命令時,全部容器將會中止。
此次接觸Docker
的時間雖然不長,可是這種微服務細分的架構真的是驚豔到我了。之前玩過VM虛擬機,那個使用成本過高,不夠靈活,用過一段時間就放棄了,老老實實維護本身的本機環境。有了這個Docker
之後,想要什麼測試環境都行,直接幾行代碼生成就好,一種爲所欲爲的自由。 上面寫的那些都是平常使用的命令,能應付基本的需求了,真要深刻的話建議去找詳細的文檔,我就不寫太累贅了,但願你們都能去接觸一下這個Docker
,怎麼都不虧,大家也會喜歡上這小鯨魚的。