原文連結:https://blog.csdn.net/forezp/article/details/80158062
容器
準備工作
- 安裝Docker,版本為1.13或者1.13之上。
- 閱讀第一篇文章的內容
- 給你的Docker環境一個快速的測試,確保所有的工作準備就緒:
docker run hello-world
介紹
是時候以Docker的方式開始構建一個應用程式了。我們從這個層次結構的底部開始,即它是一個容器,這是我們在這個介面上介紹的。在這個層次(容器?)之上是一個服務,它定義了容器在生產環境中的表現行為,在下一篇文章中我們會進行探討。最後,在頂層是堆疊,定義了第5篇文章中介紹的所有服務的互動。
- 堆疊(第五篇文章介紹)
- 服務(第三篇文章介紹)
- 容器(這篇文章介紹,you are here)
你的新的開發環境
在過去,如果你寫一個pyhton的應用,你的第一步是在你的機器上安裝python的開發環境。但是需要你的機器上的執行環境與應用程式完美適合,並且也需要匹配生產環境。
利用docker,你能移植一個便捷的python的執行庫作為映象,無需安裝。然後,通過構建包含python執行環境和你的應用程式碼一起的映象,能夠確保你的程式碼和執行環境完美結合並執行。
這些便捷的映象通過被稱作DockeFile的檔案定義。
通過Dockerfile定義一個映象
dockerfile定義了在容器內部跑什麼執行環境。訪問網路介面和磁碟驅動器等資源是在此環境中虛擬化的,與系統其餘部分隔離,因此你需要將埠對映到外部世界,並明確要將哪些檔案“複製”到 執行的環境。 然而,在完成這些之後,你可以預期,在此Dockerfile中定義的應用程式的構建在執行時的行為完全相同。
Dockerfile
建立一個空的資料夾。通過cd命令進入到新建立的資料夾,建立一個檔案取名Dockerfile,複製以下內容到檔案中,並儲存。
# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
複製程式碼
這個Dockerfile關聯了2個我們還沒有建立的檔案,,即app.py和requirements.txt。下面我們來建立。
應用程式部分
建立2個檔案,requirements.txt和app.py,並且將它們放到和Dockerfile放進同一個資料夾中。這就完成了我們的應用,你可以發現用建立應用很簡單。當上面的Dockerfile構建成映象,app.py和requirements.txt通過Add命令加入到映象去了,Expose命令能夠暴露埠,可以通過http訪問。
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, socket_connect_timeout=2, socket_timeout=2)
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 -r requirements.txt為Python安裝Flask和Redis庫,並且該應用程式列印環境變數NAME以及呼叫socket.gethostname()的輸出。 最後,因為Redis沒有執行(因為我們只安裝了Python庫,而不是Redis本身),所以我們應該期望在這裡嘗試使用它會失敗併產生錯誤訊息。
那正是要點! 您的系統上不需要Python或任何requirements.txt檔案,也不需要在您的系統上安裝或執行此映像。看起來你並沒有真正用Python和Flask建立一個環境,但是你已經擁有了。
構建應用
我們已經為構建應用做好了準備。確保你對新建的檔案與最高的許可權。下面是通過ls命令,應該顯示以下內容:
$ ls
Dockerfile app.py requirements.txt
複製程式碼
現在執行構建命令。建立一個Docker映象,通過-t標記,從而使映象有一個友好的名字。
docker build -t friendlyhello .
複製程式碼
你構建的映象在哪裡?在你的機器的本地Docker映象註冊庫“
$ docker image ls
REPOSITORY TAG IMAGE ID
friendlyhello latest 326387cea398
複製程式碼
執行應用
執行應用程式,使用-p將機器的埠4000對映到容器的已釋出埠80:
docker run -p 4000:80 friendlyhello
複製程式碼
你應該在http://0.0.0.0:80看到一條訊息,Python正在為你的應用程式提供服務。 但是該訊息來自容器內部,它不知道將該容器的埠80對映到4000,
在瀏覽器中http://localhost:4000 可以檢視網頁上顯示的顯示內容。
你也可以通過curl命令檢視相同的內容:
$ curl http://localhost:4000
<h3>Hello World!</h3><b>Hostname:</b> 8fc990912a14<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>
複製程式碼
這個4000:80的埠重對映是為了演示Dockerfile中的EXPOSE與使用docker run -p釋出的內容之間的區別。 在後面的步驟中,我們只需將主機上的埠80對映到容器中的埠80並使用http:// localhost。
按CTRL+C結束程式。
現在可以讓應用程式在後端程式中執行,用detached 模式。
docker run -d -p 4000:80 friendlyhello
複製程式碼
你可以獲取應用的容器ID,通過容器ID將應用程式停止。 容器正在後臺執行。 可以使用docker container ls命令檢視縮寫的容器ID:
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED
1fa4ab2cf395 friendlyhello "python app.py" 28 seconds ago
複製程式碼
現在用docker containner stop 命令結束程式,需要用到 container id,如下:
docker container stop 1fa4ab2cf395
複製程式碼
分享你的映象:
為了演示我們剛才建立的容器具有可移植性,我們上傳我們構建的映像並可以在其他的任何地方執行。 畢竟,當你想要將容器部署到生產環境時,弄需要知道如何推送註冊倉庫。
註冊倉庫是儲存庫的集合,而儲存庫是影象的集合 - 有點像GitHub儲存庫,但程式碼已經建立。 註冊倉庫上的帳戶可以建立許多儲存庫。 docker CLI預設使用Docker的公共註冊庫。
登入dokcer Id
如果你還沒有Docker帳戶,請在網站cloud.docker.com註冊一個帳戶。 記下你的使用者名稱。
登入到本地計算機上的Docker公共註冊庫。
$ docker login
複製程式碼
標記映象
將本地映像與註冊庫中的儲存庫相關聯的命令是username / repository:tag。 該標籤是可選的,但建議使用,因為它是註冊管理機構用於為Docker映象提供版本的機制。 為該上下文提供儲存庫並標記有意義的名稱,例如get-started:part2。 這將影象放入啟動儲存庫並將其標記為part2。
現在,把它放在一起來標記影象。使用你的使用者名稱,儲存庫和標籤名稱執行碼頭標籤影象,以便將影象上傳到您想要的目的地。 該命令的語法是:
docker tag image username/repository:tag
複製程式碼
比如:
docker tag friendlyhello john/get-started:part2
複製程式碼
執行 docker image ls 命令去檢視你的新的標記的映象。
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest d9e555c53008 3 minutes ago 195MB
john/get-started part2 d9e555c53008 3 minutes ago 195MB
python 2.7-slim 1c7128a655f6 5 days ago 183MB
...
複製程式碼
推送映象
上傳你的標記的映象去倉庫
docker push username/repository:tag
複製程式碼
完成後,此上傳的結果將公開發布。 如果你登入到Docker Hub,則可以通過其pull命令在那裡看到新映像。
從遠端倉庫獲取並執行映象
從現在起,你可以使用docker run並使用此命令在任何機器上執行你的應用程式:
docker run -p 4000:80 username/repository:tag
複製程式碼
如果映象在本地機器沒有,docker 從倉庫中拉取。
$ docker run -p 4000:80 john/get-started:part2
Unable to find image 'john/get-started:part2' locally
part2: Pulling from john/get-started
10a267c67f42: Already exists
f68a39a6a5e4: Already exists
9beaffc0cf19: Already exists
3c1fe835fb6b: Already exists
4c9f1fa8fcb8: Already exists
ee7d8f576a14: Already exists
fbccdcced46e: Already exists
Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068
Status: Downloaded newer image for john/get-started:part2
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
複製程式碼
無論docker run在哪裡執行,它都會將你的映象以及Python和requirements.txt中的所有依賴關係一起提取出來,並執行你的程式碼。 它們都在一個整潔的小包中,並且您不需要在主機上安裝任何Docker。
總結
這就是這個頁面的內容。 在下一節中,我們將學習如何通過在服務中執行此容器來擴充套件我們的應用程式。
命令複習
這裡列出了這個頁面的基本Docker命令,以及一些相關的命令,如果你想在繼續之前探索一下。
ocker build -t friendlyhello . # Create image using this directory's Dockerfile
docker run -p 4000:80 friendlyhello # Run "friendlyname" mapping port 4000 to 80
docker run -d -p 4000:80 friendlyhello # Same thing, but in detached mode
docker container ls # List all running containers
docker container ls -a # List all containers, even those not running
docker container stop <hash> # Gracefully stop the specified container
docker container kill <hash> # Force shutdown of the specified container
docker container rm <hash> # Remove specified container from this machine
docker container rm $(docker container ls -a -q) # Remove all containers
docker image ls -a # List all images on this machine
docker image rm <image id> # Remove specified image from this machine
docker image rm $(docker image ls -a -q) # Remove all images from this machine
docker login # Log in this CLI session using your Docker credentials
docker tag <image> username/repository:tag # Tag <image> for upload to registry
docker push username/repository:tag # Upload tagged image to registry
docker run username/repository:tag
複製程式碼