本章節會透過一個簡單的backend service來分析如何將其寫成Dockerfile,透過其Dockerfile生成Docker image,希望能拋磚引玉讓各位讀者能一窺其秘辛。
這邊我準備了一個以uwsgi來啟動的flask web service,裡頭包含著一隻health check的api,啟動後路徑會為localhost:8100/v1/hc
所以目前repository的structure會長這樣
.
|____app
| |____app.py
| |____api
| | |____v1
| | | |____health.py
|____requirements.txt
|____Dockerfile
|____README.md
|____docker-entrypoint.sh
|____.gitignore
|____wsgi.py
這部分程式碼分為三部分:
那現在我們來解析目錄下的Dockerfile吧
# Pull base image.
FROM ubuntu:18.04
# Set default WORKDIR in container
WORKDIR /usr/src/app
# Update the repository
COPY . .
# For log message in container
ENV PYTHONUNBUFFERED 1
# Install python 3.7
RUN apt-get update -y && \
apt-get install -y python3.7 python3-pip python3.7-dev
# Install package requirements
COPY requirements.txt requirements.txt
RUN pip3 install --upgrade pip
RUN pip3 install -r requirements.txt
# EXPOSE 8100 port
EXPOSE 8100
ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"]
FROM [repository]/[image]:[version]
這裡指的是我們的Dockerfile所要使用的基礎image為何,基本上我們所撰寫的Dockerfile都會以一個image為基礎迭代而成。由於筆者較偏好於ubuntu作業系統,因此選定該image為base image。
WORKDIR [path]
這邊是用來設定Container內的預設工作路徑,類似於Linux的~。
COPY [file_path] [container_path]
複製本地路徑的file到Container內,這邊我們是將整個web service的所有程式都複製進去。
ENV [key] [value]
設定環境變數 PYTHONUNBUFFERED為1,此環境變數為python log所使用。可依自己喜好給env variable,之後也會教如何去設定整個檔案的變數為Container的環境變數。
RUN [command]
在container內執行commands,這邊筆者是在ubuntu的container內
EXPOSE [port]
Container所要暴露的port,這邊筆者是暴露flask內所啟動的8100port,如此一來目前我們就能透過docker-network來找到container的8100 port。
ENTRYPOINT [command] [params1] [params2]
ENTRYPOINT ["executable", [params1], [params2]]
這邊Entrypoint指令可以支援兩種不同格式,分別是為了直接下command以及執行執行檔
Entrypoint為Dockerfile所定義的指令,指的是在Container啟動時所會自動執行的指令,每個 Dockerfile 中只能有一個 ENTRYPOINT,當指定多個時,只有最後一個會生效。 這裡筆者是用來執行我們的shell script,用來啟動flask web service指令。
docker build -t [image_name] [path]
$ docker build -t ironman .
docker run [image_name]
這邊我們加上了幾個arguments
$ docker run --name ironman -d -p 8100:8100 ironman
運行Container時的使用者名稱或UID,後續運行Container也會使用該使用者。
當你建立起的image,讓其他Image當做基底時,會在最後執行ONBUILD的COMMAND
,就等於是你的image讓人使用時會再多執行onbuild指令。
複製相對路徑的file至Container內,他同時也能接受URL或是tar檔案,但tar檔在複製後會自動解壓縮。
CMD [command] [params1] [params2]
CMD ["executable", [params1], [params2]]
CMD [[params1], [params2]]
有點類似於Entrypoint,但還是有著些許不同。
本篇章所有程式碼將放在下面的github project當中的branch day-5
https://github.com/Neskem/ironman_2020/tree/day-5
往後該系列的展示程式碼,都將放在同一project並以不同branch的形式提供參考。
本篇章透過簡單的python code來展示如何將自己的web service包在Dockerfile之中,
希望能夠拋磚引玉,讓各位讀者嘗試打包自己的服務。也恭喜大家學會了撰寫自己的Dockerfile,讓自己在容器化技術上獲得了一項強力武器!!
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
您好: 目前依據您的做學習中
想請問 命令 粗體字代表意義 ?
$ docker run --name ironman -d -p 8100:8100 ironman
docker run --name <container_name> -d -p 8100:8100 <image_name>
感謝