現在docker已經升級了很多版本了,而我目前的docker版本仍然是1.12.5
,比較老的版本,所以現在我們需要升級我們的docker版本,首先是如何查看我們系統中的docker版本呢?
運行命令docker --version
即可查看。
(一)、Docker新版本介紹及安裝
目前,Docker分爲了兩個可用的版本,分別爲Docker企業版
和Docker社區版
,故名思議,Docker EE
,即Docker企業版是專門爲企業開發和IT團隊構建,部署商業應用所設計的,而Docker CE
,即Docker社區本是爲開發者和剛開始使用Docker的小團隊開發設計的。在這裏我們使用Docker CE
。
卸載老版本
Docker的老版本被稱爲docker
或者是docker engine
,如果安裝過,先把他們卸載掉。
sudo apt-get remove docker docker-engine
如果卸載成功,apt-get
將會報出沒有安裝包被安裝。
位於目錄/var/lib/docker/
中的鏡像,容器,卷和網絡被保留。Docker CE包現在被稱爲docker-ce
,Docker EE包現在被稱爲docker-ee
。
爲Trusty 14.04推薦的額外的包
如果沒有其他原因,推薦您安裝linux-image-extra-*
這些包,這些允許Docker使用aufs
存儲驅動。
$ sudo apt-get update
$ sudo apt-get install \
linux-image-extra-$(uname -r) \
linux-image-extra-virtual
安裝Docker
有兩種安裝方式,一個是通過倉庫安裝,一個是通過包安裝,在這裏我們選擇使用包安裝。
我們需要下載.deb
文件來安裝docker。這裏有一個麻煩的地方就是,每次我們想要更新docker的話,就需要下載一個新的文件,無所謂了,我們選擇包安裝。
Docker CE
和Docker EE
的安裝步驟也是不一樣的,我們只關注Docker CE
。進入下載地址
,選擇我們的ubuntu版本,瀏覽pool/stable
,選擇amd64
或者是armhf
,然後下載相應你想要安裝的的.deb
文件。
下載完成之後,使用下面的命令來安裝你所下載的安裝包。
dpkg -i /path/to/package.deb
安裝完成之後,我們通過運行hello-world
鏡像來驗證Docker CE是否安裝完成。
卸載Docker
我們可以使用下面的命令來卸載Docker包。
sudo apt-get purge docker-ce
但是鏡像,容器,卷或者是定製的配置文件將不會自動被刪除,我們可以通過下面的命令來移走:
sudo rm -rf /var/lib/docker
(二)、構建新的app
你的新的開發環境
在過去,如果你想要開始編寫一個Python應用,第一步工作便是在你的機器上安裝一個Python運行時環境,但是這樣便會導致一個問題是,如果想要你的應用如期運行你的機器環境在哪裏,還有運行你的應用的app在哪裏。
使用Docker,你僅僅需要抓取一個輕便的Python運行時作爲一個鏡像,不必安裝。然後,你的構建需要包括基本的Python鏡像和你的app代碼,確保你的app,他的依賴和運行時都在一塊。
這些輕便的鏡像被定義稱爲Dockerfile
。
使用Dockerfile
定義一個容器
Dockerfile
將會定義在你的容器環境中什麼將會運行。訪問的資源例如網絡接口和磁盤驅動在環境中都被虛擬出來了,這個是和你係統中的其他事物隔離的,所以你必須映射端口到外面的世界,並且必須要指定那些文件你想要複製到那個環境中。然後,完成那些操作之後,你可能希望定義在這個Dockerfile
中的app的構建在任何地方運行都一樣的。
Dockerfile
創建一個空的目錄然後把這個名稱爲Dockerfile
的文件放進去。注意每一行的註釋。
# 使用一個官方的Python運行時作爲一個鏡像
FROM python:2.7-slim
# 設置工作目錄到/app
WORKDIR /app
# 複製當前目錄內容到/app的容器中
ADD . /app
# 安裝指定在requirements.txt文件中的所有的包
RUN pip install -r requirements.txt
# 使80端口在容器外能夠被訪問
EXPOSE 80
# 定義環境變量
ENV NAME World
# 當容器啓動的時候運行app.py
CMD ["python", "app.py"]
這個Dockerfile
引用了一些我們沒有創建的文件,app.py
和requirements.txt
。在下面我們獲取這些文件。
app本身
獲取這兩個文件並放到和Dockerfile
相同的目錄中。這樣就完成了我們的app,看上去是很簡單的。當上述的Dockerfile
被構建進入鏡像的時候,app.py
和requirements.txt
也將會存在,因爲Dockerfile
的ADD
命令,app.py
的輸出將通過HTTP被訪問,因爲EXPOSE
命令。
requirements.txt
Flask
Redis
app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr('counter')
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv('NAME', "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
現在我們可以看到pip install requirements.txt
安裝了Flask和Redis庫,並且app打印出了環境變量NAME
,和socker.gethoustname()
調用後的輸出是一樣的。最後,因爲Redis並沒有運行(因爲我們僅僅安裝了Python庫,而不是Redis本身),所以我們得到的結果將會是嘗試使用它但是失敗了,並且產生一個錯誤信息。
構建app
就是這樣,在你的系統中,你不需要Python或者是requirements.txt
文件中的任何東西,你也不需要構建或者是運行這個景象安裝到你的系統中。看上去好像是你設置了Python或者是Flask的環境變量,實際上並沒有。下面是ls
應該顯示的:
$ ls
Dockerfile app.py requirements.txt
現在運行build命令。這將會創建一個Docker鏡像,該鏡像我們使用-t
選項來標記他,這樣他就有了一個友好的名稱。
docker build -t friendlyhello .
你構建的鏡像在哪呢?他在你的機器的本地Docker鏡像條目中。
$ docker images
REPOSITORY TAG IMAGE ID
friendlyhello latest 326387cea398
運行app
運行app,使用-p
選項映射你的機器的端口4000到容器的EXPOSE
的端口80。
docker run -p 4000:80 friendlyhello
你應該看到一個提醒,Python正在http://0.0.0.0:80
服務你的app。但是那個信息是來自內部容器的,他並不知道你映射了端口80到4000了,使得當前的URL http://localhost:4000
。到這裏,你將會看到Hello World
文本,容器ID和Redis錯誤信息。
注意:這個端口映射`4000:80`是爲了證明在`Dockerfile`中你的`EXPOSE`和你使用`docker run -p`發佈的不同的。在後面的步驟中,我們僅僅映射端口80到端口80,這樣就可以使用`http://localhost`。
在你的終端中使用CTRL+C
來退出。
現在我們在後臺運行該app,使用分離的模式:
docker run -d -p 4000:80 friendlyhello
你獲取到了一個長得容器ID並且然後被踢回到你的終端中。你的容器正在後臺運行。你可以使用docker ps
來看到一個簡便的容器ID.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
1fa4ab2cf395 friendlyhello "python app.py" 28 seconds ago
你將看到CONTAINER ID
和http://localhost:4000
中的是相匹配的。
現在使用docker stop
來結束進程,使用CONTAINER ID
,就像下面這樣:
docker stop 1fa4ab2cf395
共享你的鏡像
後面我們學習如何共享我們的鏡像。
docker login
docker tag friendlyhello username/repository:tag
docker push username/repository:tag
docker run -p 4000:80 username/repository:tag