溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么用Dockerfile定義一個(gè)鏡像

發(fā)布時(shí)間:2021-12-13 14:13:24 來(lái)源:億速云 閱讀:127 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“怎么用Dockerfile定義一個(gè)鏡像”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

容器

準(zhǔn)備工作

  • 安裝Docker,版本為1.13或者1.13之上。


  • 給你的Docker環(huán)境一個(gè)快速的測(cè)試,確保所有的工作準(zhǔn)備就緒:

docker run hello-world

你的新的開發(fā)環(huán)境

在過(guò)去,如果你寫一個(gè)pyhton的應(yīng)用,你的第一步是在你的機(jī)器上安裝python的開發(fā)環(huán)境。但是需要你的機(jī)器上的運(yùn)行環(huán)境與應(yīng)用程序完美適合,并且也需要匹配生產(chǎn)環(huán)境。

利用docker,你能移植一個(gè)便捷的python的運(yùn)行庫(kù)作為鏡像,無(wú)需安裝。然后,通過(guò)構(gòu)建包含python運(yùn)行環(huán)境和你的應(yīng)用代碼一起的鏡像,能夠確保你的代碼和運(yùn)行環(huán)境完美結(jié)合并運(yùn)行。

這些便捷的鏡像通過(guò)被稱作DockeFile的文件定義。

通過(guò)Dockerfile定義一個(gè)鏡像

dockerfile定義了在容器內(nèi)部跑什么運(yùn)行環(huán)境。訪問(wèn)網(wǎng)絡(luò)接口和磁盤驅(qū)動(dòng)器等資源是在此環(huán)境中虛擬化的,與系統(tǒng)其余部分隔離,因此你需要將端口映射到外部世界,并明確要將哪些文件“復(fù)制”到 運(yùn)行的環(huán)境。 然而,在完成這些之后,你可以預(yù)期,在此Dockerfile中定義的應(yīng)用程序的構(gòu)建在運(yùn)行時(shí)的行為完全相同。

Dockerfile

創(chuàng)建一個(gè)空的文件夾。通過(guò)cd命令進(jìn)入到新創(chuàng)建的文件夾,創(chuàng)建一個(gè)文件取名Dockerfile,復(fù)制以下內(nèi)容到文件中,并保存。

# 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"]

這個(gè)Dockerfile關(guān)聯(lián)了2個(gè)我們還沒(méi)有創(chuàng)建的文件,,即app.py和requirements.txt。下面我們來(lái)創(chuàng)建。

應(yīng)用程序部分

創(chuàng)建2個(gè)文件,requirements.txt和app.py,并且將它們放到和Dockerfile放進(jìn)同一個(gè)文件夾中。這就完成了我們的應(yīng)用,你可以發(fā)現(xiàn)用創(chuàng)建應(yīng)用很簡(jiǎn)單。當(dāng)上面的Dockerfile構(gòu)建成鏡像,app.py和requirements.txt通過(guò)Add命令加入到鏡像去了,Expose命令能夠暴露端口,可以通過(guò)http訪問(wèn)。

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 = "<h4>Hello {name}!</h4>" \
           "<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)

現(xiàn)在我們看到pip install -r requirements.txt為Python安裝Flask和Redis庫(kù),并且該應(yīng)用程序打印環(huán)境變量NAME以及調(diào)用socket.gethostname()的輸出。 最后,因?yàn)镽edis沒(méi)有運(yùn)行(因?yàn)槲覀冎话惭b了Python庫(kù),而不是Redis本身),所以我們應(yīng)該期望在這里嘗試使用它會(huì)失敗并產(chǎn)生錯(cuò)誤消息。

那正是要點(diǎn)! 您的系統(tǒng)上不需要Python或任何requirements.txt文件,也不需要在您的系統(tǒng)上安裝或運(yùn)行此映像??雌饋?lái)你并沒(méi)有真正用Python和Flask建立一個(gè)環(huán)境,但是你已經(jīng)擁有了。

構(gòu)建應(yīng)用

我們已經(jīng)為構(gòu)建應(yīng)用做好了準(zhǔn)備。確保你對(duì)新建的文件與最高的權(quán)限。下面是通過(guò)ls命令,應(yīng)該顯示以下內(nèi)容:

$ ls
Dockerfile        app.py            requirements.txt

現(xiàn)在運(yùn)行構(gòu)建命令。創(chuàng)建一個(gè)Docker鏡像,通過(guò)-t標(biāo)記,從而使鏡像有一個(gè)友好的名字。

docker build -t friendlyhello .

你構(gòu)建的鏡像在哪里?在你的機(jī)器的本地Docker鏡像注冊(cè)庫(kù)“

$ docker image ls

REPOSITORY            TAG                 IMAGE ID
friendlyhello         latest              326387cea398

運(yùn)行應(yīng)用

運(yùn)行應(yīng)用程序,使用-p將機(jī)器的端口4000映射到容器的已發(fā)布端口80:

docker run -p 4000:80 friendlyhello

你應(yīng)該在http://0.0.0.0:80看到一條消息,Python正在為你的應(yīng)用程序提供服務(wù)。 但是該消息來(lái)自容器內(nèi)部,它不知道將該容器的端口80映射到4000,

在瀏覽器中http://localhost:4000 可以查看網(wǎng)頁(yè)上顯示的顯示內(nèi)容。

怎么用Dockerfile定義一個(gè)鏡像

你也可以通過(guò)curl命令查看相同的內(nèi)容:

$ curl http://localhost:4000

<h4>Hello World!</h4><b>Hostname:</b> 8fc990912a14<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>

這個(gè)4000:80的端口重映射是為了演示Dockerfile中的EXPOSE與使用docker run -p發(fā)布的內(nèi)容之間的區(qū)別。 在后面的步驟中,我們只需將主機(jī)上的端口80映射到容器中的端口80并使用http:// localhost。

按CTRL+C結(jié)束進(jìn)程。

現(xiàn)在可以讓應(yīng)用程序在后端進(jìn)程中運(yùn)行,用detached 模式。

docker run -d -p 4000:80 friendlyhello

你可以獲取應(yīng)用的容器ID,通過(guò)容器ID將應(yīng)用程序停止。 容器正在后臺(tái)運(yùn)行。 可以使用docker container ls命令查看縮寫的容器ID:

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED
1fa4ab2cf395        friendlyhello       "python app.py"     28 seconds ago

現(xiàn)在用docker containner stop 命令結(jié)束進(jìn)程,需要用到 container id,如下:

docker container stop 1fa4ab2cf395

分享你的鏡像:

為了演示我們剛才創(chuàng)建的容器具有可移植性,我們上傳我們構(gòu)建的映像并可以在其他的任何地方運(yùn)行。 畢竟,當(dāng)你想要將容器部署到生產(chǎn)環(huán)境時(shí),弄需要知道如何推送注冊(cè)倉(cāng)庫(kù)。

注冊(cè)倉(cāng)庫(kù)是存儲(chǔ)庫(kù)的集合,而存儲(chǔ)庫(kù)是圖像的集合 - 有點(diǎn)像GitHub存儲(chǔ)庫(kù),但代碼已經(jīng)創(chuàng)建。 注冊(cè)倉(cāng)庫(kù)上的帳戶可以創(chuàng)建許多存儲(chǔ)庫(kù)。 docker CLI默認(rèn)使用Docker的公共注冊(cè)庫(kù)。

登錄dokcer Id

如果你還沒(méi)有Docker帳戶,請(qǐng)?jiān)诰W(wǎng)站cloud.docker.com注冊(cè)一個(gè)帳戶。 記下你的用戶名。

登錄到本地計(jì)算機(jī)上的Docker公共注冊(cè)庫(kù)。

$ docker login

標(biāo)記鏡像

將本地映像與注冊(cè)庫(kù)中的存儲(chǔ)庫(kù)相關(guān)聯(lián)的命令是username / repository:tag。 該標(biāo)簽是可選的,但建議使用,因?yàn)樗亲?cè)管理機(jī)構(gòu)用于為Docker鏡像提供版本的機(jī)制。 為該上下文提供存儲(chǔ)庫(kù)并標(biāo)記有意義的名稱,例如get-started:part2。 這將圖像放入啟動(dòng)存儲(chǔ)庫(kù)并將其標(biāo)記為part2。

現(xiàn)在,把它放在一起來(lái)標(biāo)記圖像。使用你的用戶名,存儲(chǔ)庫(kù)和標(biāo)簽名稱運(yùn)行碼頭標(biāo)簽圖像,以便將圖像上傳到您想要的目的地。 該命令的語(yǔ)法是:

docker tag image username/repository:tag

比如:

docker tag friendlyhello john/get-started:part2

運(yùn)行 docker image ls 命令去查看你的新的標(biāo)記的鏡像。

$ 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
...

推送鏡像

上傳你的標(biāo)記的鏡像去倉(cāng)庫(kù)

docker push username/repository:tag

完成后,此上傳的結(jié)果將公開發(fā)布。 如果你登錄到Docker Hub,則可以通過(guò)其pull命令在那里看到新映像。

從遠(yuǎn)程倉(cāng)庫(kù)獲取并運(yùn)行鏡像

從現(xiàn)在起,你可以使用docker run并使用此命令在任何機(jī)器上運(yùn)行你的應(yīng)用程序:

docker run -p 4000:80 username/repository:tag

如果鏡像在本地機(jī)器沒(méi)有,docker 從倉(cāng)庫(kù)中拉取。

$ 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)

無(wú)論docker run在哪里執(zhí)行,它都會(huì)將你的鏡像以及Python和requirements.txt中的所有依賴關(guān)系一起提取出來(lái),并運(yùn)行你的代碼。 它們都在一個(gè)整潔的小包中,并且您不需要在主機(jī)上安裝任何Docker

命令復(fù)習(xí)

這里列出了這個(gè)頁(yè)面的基本Docker命令,以及一些相關(guān)的命令,如果你想在繼續(xù)之前探索一下。

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

“怎么用Dockerfile定義一個(gè)鏡像”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI