Dockerfile 語法教程
文章目錄
- Dockerfile 語法教程
- Dockerfile 語法教程
- 基礎概念
- Dockerfile 簡介
- 鏡像、容器、倉庫的概念
- Dockerfile 基本語法
- Dockerfile 基本語法
- Dockerfile 的基本結構
- 注釋的使用
- 指令的格式
- 指令的執行順序
- Dockerfile 常用指令
- FROM 指令
- RUN 指令
- CMD 指令
- ENTRYPOINT 指令
- ENV 指令
- ARG 指令
- 構建鏡像
- 使用 Dockerfile 構建鏡像
- .dockerignore 文件的使用
- 多階段構建
- Dockerfile 最佳實踐
- 1. 編寫可復用的 Dockerfile
- 2. 避免使用 root 用戶
- 3. 優化鏡像大小
Dockerfile 語法教程
基礎概念
Dockerfile 簡介
Dockerfile 是一個文本文件,其內包含了一系列用戶可以調用docker build命令自動構建 Docker 鏡像的指令。每一條指令都會在鏡像上創建一個新的層,因此每一條指令的內容,都會作為下一次創建新的層的基礎。
鏡像、容器、倉庫的概念
-
鏡像:Docker 鏡像是一個只讀的模板,包含了創建 Docker 容器(可以運行應用程序)和 Docker 鏡像(可以運行容器)所需的所有內容。例如,一個鏡像可能包含已安裝的應用程序、系統工具、庫和配置文件。
-
容器:Docker 容器是鏡像的一個運行實例。您可以使用 Docker API 或 CLI 來創建、啟動、停止、移動或刪除容器。每個容器都是獨立和安全的應用平臺。
-
倉庫:Docker 倉庫是用來存儲和管理 Docker 鏡像的地方。您可以通過 Docker Hub 或其他公開的倉庫來獲取別人共享的鏡像,也可以將自己的鏡像推送到公開或私有的倉庫中供他人使用。
Dockerfile 基本語法
Dockerfile 由一系列的指令組成,每一條指令對應一條命令。下面是一些常用的 Dockerfile 指令:
FROM
:指定基礎鏡像。RUN
:在鏡像內部執行命令。CMD
:提供默認的命令,當容器啟動時會自動執行。ENTRYPOINT
:配置容器啟動時運行的命令,與 CMD 不同的是,使用 ENTRYPOINT 指定的命令不會被 shell 覆蓋,而 CMD 指定的命令會被 shell 覆蓋。ENV
:設置環境變量。ADD
/COPY
:將本地文件添加到鏡像中。WORKDIR
:設置工作目錄。EXPOSE
:聲明運行時容器提供服務端口。VOLUME
:創建一個可以從宿主主機或其他容器掛載的掛載點,一般用來存放數據庫和需要保持的數據。
Dockerfile 基本語法
Dockerfile 的基本結構
Dockerfile 是一個文本文件,其內包含了一系列用戶可以調用 docker 命令自動構建鏡像的指令。一個基礎的 Dockerfile 文件通常包括:一個基礎鏡像信息、維護者信息、鏡像操作指令等。
# 基礎鏡像信息
FROM ubuntu:18.04
# 維護者信息
MAINTAINER Your Name <your.email@example.com>
# 鏡像操作指令
RUN apt-get update && apt-get install -y python3
注釋的使用
在 Dockerfile 中,可以使用 #
來添加注釋。單行注釋以 #
開頭,直到該行的結束。多行注釋使用 /*
和 */
包圍起來。
# 這是一個單行注釋
RUN echo "Hello, World!" > /tmp/hello.txt # 這是一行注釋內容/*
這是一個多行注釋
可以跨越多行
*/
指令的格式
Dockerfile 的每一行都是一個指令,格式為 instruction argument
。例如,RUN
指令用于執行命令,CMD
指令用于指定容器啟動時要運行的命令。
RUN apt-get update && apt-get install -y python3 # 更新并安裝 Python3
CMD ["python3", "app.py"] # 運行 app.py 腳本
指令的執行順序
Dockerfile 中的指令按照從上到下的順序執行。用戶可以通過 docker build
命令來構建鏡像,這個過程中,Docker會按照 Dockerfile 中指令的順序來執行。
Dockerfile 常用指令
Dockerfile 是用于構建 Docker 鏡像的文本文件,它包含了一系列的指令和參數。以下是一些常用的 Dockerfile 指令:
FROM 指令
FROM
指令用于指定基礎鏡像。例如,如果我們想要基于 ubuntu:18.04
鏡像來構建我們的應用,我們可以這樣寫:
FROM ubuntu:18.04
RUN 指令
RUN
指令用于在鏡像中執行命令。例如,我們可以使用 RUN
指令來安裝一些必要的軟件包:
RUN apt-get update && apt-get install -y curl
CMD 指令
CMD
指令用于指定容器啟動時默認執行的命令。例如,我們可以使用 CMD
指令來啟動一個 web 服務器:
CMD ["service", "nginx", "start"]
ENTRYPOINT 指令
ENTRYPOINT
指令用于指定容器啟動時的入口點。與 CMD
不同的是,ENTRYPOINT
指定的命令不會被 docker run
命令后面的參數所覆蓋。例如,我們可以使用 ENTRYPOINT
指令來啟動一個 web 服務器:
ENTRYPOINT ["service", "nginx", "start"]
ENV 指令
ENV
指令用于設置環境變量。例如,我們可以使用 ENV
指令來設置數據庫連接字符串:
ENV DB_CONNECTION_STRING="server=db;user id=myuser;password=mypassword;database=mydb"
ARG 指令
ARG
指令用于定義可以在構建過程中使用的變量。例如,我們可以使用 ARG
指令來定義版本號:
ARG VERSION=1.0.0
構建鏡像
使用 Dockerfile 構建鏡像
Dockerfile 是一個文本文件,其包含了一系列用戶可以調用 docker build 命令自動執行的命令。以下是一個基本的 Dockerfile 示例:
# 使用官方 Python 運行時作為父鏡像
FROM python:3.7-slim# 設置工作目錄
WORKDIR /app# 將當前目錄內容復制到容器的 /app 目錄
ADD . /app# 使用 pip 安裝任何需要的包
RUN pip install --no-cache-dir -r requirements.txt# 使端口 80 可用于此應用程序
EXPOSE 80# 定義環境變量
ENV NAME World# 在容器啟動時運行 app.py
CMD ["python", "app.py"]
.dockerignore 文件的使用
.dockerignore
文件用于排除不需要的文件和目錄。以下是一個 .dockerignore
文件的示例:
# 忽略所有 .pyc 文件和文件夾
*.pyc
__pycache__/# 忽略所有 .log 文件和文件夾
*.log
logs/
多階段構建
多階段構建允許你將構建過程分為多個階段,每個階段都有自己的輸出。以下是一個多階段構建的示例:
# 第一階段:獲取依賴項并編譯源代碼
FROM node:14 as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build# 第二階段:使用 Nginx 運行應用
FROM nginx:1.19-alpine as production
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Dockerfile 最佳實踐
在編寫 Dockerfile 時,遵循一些最佳實踐可以幫助我們編寫出更高效、可復用和安全的鏡像。本教程將介紹以下三個最佳實踐:編寫可復用的 Dockerfile、避免使用 root 用戶和優化鏡像大小。
1. 編寫可復用的 Dockerfile
為了提高開發效率,我們可以編寫一個通用的 Dockerfile,然后在需要的時候繼承它。這樣可以避免重復編寫相同的基礎設置。例如,我們可以創建一個名為 base
的 Dockerfile,包含所有通用設置,然后在其他 Dockerfile 中通過 FROM base
指令繼承它。
# base Dockerfile
FROM alpine:latest
RUN apk update && apk add --no-cache git
WORKDIR /app
在其他 Dockerfile 中,我們可以這樣繼承 base
Dockerfile:
# app Dockerfile
FROM base
COPY . /app
RUN make build
CMD ["./app"]
2. 避免使用 root 用戶
在容器中以 root 用戶身份運行進程可能會導致安全風險。因此,建議在容器中以非 root 用戶身份運行進程。可以通過以下方式實現:
- 在 Dockerfile 中使用
USER
指令切換到非 root 用戶。 - 確保應用程序在運行時以非 root 用戶身份運行。
例如,我們可以在 base
Dockerfile 中添加以下內容:
USER nobody
然后,在需要使用非 root 用戶的應用程序的 Dockerfile 中,確保應用程序以非 root 用戶身份運行。例如:
# app Dockerfile
FROM base
COPY . /app
RUN chown -R nobody:nobody /app && make build
USER nobody
CMD ["./app"]
3. 優化鏡像大小
為了減少鏡像的大小,我們可以采取以下措施:
- 使用多階段構建。多階段構建可以將多個構建階段合并到一個鏡像中,從而減少層數和大小。例如:
# multi-stage build example
FROM node:14 as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run buildFROM alpine:latest as production
WORKDIR /app
COPY --from=builder /app/build ./build
CMD ["./build"]
- 清理不必要的文件。在構建過程中,可能會生成一些臨時文件或緩存文件。可以使用
RUN
指令刪除這些文件,以減小鏡像大小。例如:
# remove unnecessary files example
RUN apk del gcc musl-dev && rm -rf /var/cache/apk/* && adduser -D user && mkdir -p /home/user/app && chown -R user:user /home/user/app && mv /app/* /home/user/app/ && rm -rf /app/* && chown -R user:user /home/user/app && mv /home/user/app/* /app/ && rm -rf /home/user/app/* && rm -rf /var/cache/apk/* && rm -rf /tmp/* && apk update && apk add --no-cache libc6-compat && apk add --no-cache libstdc++6 && apk add --no-cache zlib && apk add --no-cache libgcc-s.so.1 && apk add --no-cache libssl1.1 && apk add --no-cache libffi-dev && apk add --no-cache openssl-dev && apk add --no-cache python3 && apk add --no-cache py3-pip && pip3 install --upgrade pip setuptools wheel && pip3 install uwsgi==2.0.19 && pip3 install psutil==5.7.0 && pip3 install requests==2.25.1 && pip3 install httpie==1.0.3 && pip3 install boto3==1.16.48 && pip3 install botocore==1.19.48 && pip3 install cryptography==3.4.7 && pip3 install grpcio==1.34.0 && pip3 install google-api-python-client==1.7.12 && pip3 install google-auth==1.23.0 && pip3 install google-auth-httplib2==0.0.4 && pip3 install google-cloud-core==1.4.1 && pip3 install google-resumable-media==0.5.2 && pip3 install idna==2.10 && pip3 install PyNaCl==1.4.0 && pip3 install six==1.15.0 && pip3 install twilio==6.64.0 && pip3 install validate-email==2020.10.26 && rm -rf /var/cache/apk/* && apk del gcc musl-dev python3 py3-pip build-base && adduser -D user && mkdir -p /home/user/app && chown -R user:user /home/user/app && mv /app/* /home/user/app/ && rm -rf /app/* && chown -R user:user /home/user/app && mv /home/user/app/* /app/ && rm -rf /home/user/app/* && apk update && apk add --no-cache libc6-compat libstdc++6 zlib libgcc-s.so.1 libssl1.1 libffi-dev openssl-dev python3 py3-pip build-base uwsgi==2.0.19 psutil==5.7.0 requests==2.25.1 httpie==1.0.3 boto3==1.16.48 botocore==1.19.48 cryptography==3.4.7 grpcio==1.34.0 google-api-python-client==1.7.12 google-auth==1.23.0 google-auth-httplib2==0.0