一.dify-api的Dockerfile文件
dify-api的Dockerfile文件如下所示:
# base image
FROM python:3.10-slim-bookworm AS baseLABEL maintainer="takatost@gmail.com"# install packages
FROM base as packagesRUN apt-get update \&& apt-get install -y --no-install-recommends gcc g++ libc-dev libffi-dev libgmp-dev libmpfr-dev libmpc-devCOPY requirements.txt /requirements.txtRUN --mount=type=cache,target=/root/.cache/pip \pip install --prefix=/pkg -r requirements.txt# production stage
FROM base AS productionENV FLASK_APP app.py
ENV EDITION SELF_HOSTED
ENV DEPLOY_ENV PRODUCTION
ENV CONSOLE_API_URL http://127.0.0.1:5001
ENV CONSOLE_WEB_URL http://127.0.0.1:3000
ENV SERVICE_API_URL http://127.0.0.1:5001
ENV APP_WEB_URL http://127.0.0.1:3000EXPOSE 5001# set timezone
ENV TZ UTCWORKDIR /app/apiRUN apt-get update \&& apt-get install -y --no-install-recommends curl wget vim nodejs ffmpeg libgmp-dev libmpfr-dev libmpc-dev \&& apt-get autoremove \&& rm -rf /var/lib/apt/lists/*COPY --from=packages /pkg /usr/local
COPY . /app/api/COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.shARG COMMIT_SHA
ENV COMMIT_SHA ${COMMIT_SHA}ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
二.Dockerfile文件分析
這個 Dockerfile 設計用于構建基于 Python 的 Flask 應用。將逐行解釋這個文件:
1.基礎鏡像階段
FROM python:3.10-slim-bookworm AS base
LABEL maintainer="takatost@gmail.com"
-
FROM python:3.10-slim-bookworm AS base:這一行設置了基礎鏡像為 Python 3.10 版本的 slim 版本,基于 Debian bookworm。這種鏡像較小,適合生產環境使用。并將此階段命名為
base
。 -
LABEL maintainer=“takatost@gmail.com”:給鏡像添加維護者的標簽,方便聯系和識別。
2.安裝依賴包階段
FROM base as packagesRUN apt-get update \&& apt-get install -y --no-install-recommends gcc g++ libc-dev libffi-dev libgmp-dev libmpfr-dev libmpc-devCOPY requirements.txt /requirements.txtRUN --mount=type=cache,target=/root/.cache/pip \pip install --prefix=/pkg -r requirements.txt
-
FROM base as packages:從基礎鏡像
base
開始新的構建階段,命名為packages
。 -
RUN apt-get update…:安裝 Python 應用構建和運行時可能需要的系統依賴包,包括編譯器和庫文件。
-
COPY requirements.txt /requirements.txt:復制包含 Python 依賴的
requirements.txt
文件到容器中。 -
RUN --mount=type=cache,target=/root/.cache/pip…:利用 Docker 的構建緩存特性,安裝
requirements.txt
中列出的 Python 依賴到/pkg
目錄,以提高后續構建的速度。
3.生產階段設置
FROM base AS productionENV FLASK_APP app.py
...
EXPOSE 5001
...
WORKDIR /app/apiRUN apt-get update \&& apt-get install -y --no-install-recommends curl wget vim nodejs ffmpeg libgmp-dev libmpfr-dev libmpc-dev \&& apt-get autoremove \&& rm -rf /var/lib/apt/lists/*COPY --from=packages /pkg /usr/local
COPY . /app/api/COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.shARG COMMIT_SHA
ENV COMMIT_SHA ${COMMIT_SHA}ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]
-
FROM base AS production:從基礎鏡像
base
開始新的構建階段,命名為production
。 -
ENV FLASK_APP app.py 和其他
ENV
:設置 Flask 環境變量和其他運行時環境變量。 -
EXPOSE 5001:聲明容器將在端口 5001 上運行服務。
-
WORKDIR /app/api:設置工作目錄。
-
RUN apt-get update…:更新包索引并安裝生產環境所需的其他系統依賴,最后清理不再需要的包和臨時文件。
-
COPY --from=packages /pkg /usr/local:從
packages
階段復制安裝好的 Python 依賴。 -
COPY . /app/api/:復制當前目錄下所有文件到工作目錄。
-
COPY docker/entrypoint.sh /entrypoint.sh:復制入口腳本到容器。
-
RUN chmod +x /entrypoint.sh:賦予入口腳本執行權限。
-
ARG COMMIT_SHA 和 ENV COMMIT_SHA ${COMMIT_SHA}:接收并設置構建參數,用于標記版本。
-
ENTRYPOINT [“/bin/bash”, “/entrypoint.sh”]:設置容器啟動時執行的命令。
整個 Dockerfile 的設計旨在確保從依賴安裝到應用部署的每個步驟都優化和安全,同時也支持構建緩存以加速多次構建過程。
三.dify\api\docker\entrypoint.sh文件分析
#!/bin/bashset -eif [[ "${MIGRATION_ENABLED}" == "true" ]]; thenecho "Running migrations"flask db upgrade
fiif [[ "${MODE}" == "worker" ]]; thencelery -A app.celery worker -P ${CELERY_WORKER_CLASS:-gevent} -c ${CELERY_WORKER_AMOUNT:-1} --loglevel INFO \-Q ${CELERY_QUEUES:-dataset,generation,mail}
elif [[ "${MODE}" == "beat" ]]; thencelery -A app.celery beat --loglevel INFO
elseif [[ "${DEBUG}" == "true" ]]; thenflask run --host=${DIFY_BIND_ADDRESS:-0.0.0.0} --port=${DIFY_PORT:-5001} --debugelsegunicorn \--bind "${DIFY_BIND_ADDRESS:-0.0.0.0}:${DIFY_PORT:-5001}" \--workers ${SERVER_WORKER_AMOUNT:-1} \--worker-class ${SERVER_WORKER_CLASS:-gevent} \--timeout ${GUNICORN_TIMEOUT:-200} \--preload \app:appfi
fi
這是一個 Bash 腳本,通常用于容器入口點(entrypoint)來啟動 Flask 應用及相關服務。以下是腳本中每一行代碼的中文解釋:
#!/bin/bash
- 這一行是 Shebang 行,指示操作系統使用 Bash 解釋器執行此腳本。
set -e
- 這一行設置了 Bash 的
-e
選項,意味著如果腳本中任何命令執行失敗(返回非零狀態),腳本將立即退出。
if [[ "${MIGRATION_ENABLED}" == "true" ]]; thenecho "Running migrations"flask db upgrade
fi
- 這個 if 語句檢查環境變量
MIGRATION_ENABLED
是否設置為"true"
。如果是,執行數據庫遷移命令flask db upgrade
,并在執行前打印 “Running migrations”。
if [[ "${MODE}" == "worker" ]]; thencelery -A app.celery worker -P ${CELERY_WORKER_CLASS:-gevent} -c ${CELERY_WORKER_AMOUNT:-1} --loglevel INFO \-Q ${CELERY_QUEUES:-dataset,generation,mail}
elif [[ "${MODE}" == "beat" ]]; thencelery -A app.celery beat --loglevel INFO
- 這段代碼根據環境變量
MODE
的值啟動 Celery。如果MODE
是"worker"
,則啟動 Celery worker,并配置相關的選項(如并發方式、日志級別等)。如果MODE
是"beat"
,則啟動 Celery beat 進程。
elseif [[ "${DEBUG}" == "true" ]]; thenflask run --host=${DIFY_BIND_ADDRESS:-0.0.0.0} --port=${DIFY_PORT:-5001} --debugelsegunicorn \--bind "${DIFY_BIND_ADDRESS:-0.0.0.0}:${DIFY_PORT:-5001}" \--workers ${SERVER_WORKER_AMOUNT:-1} \--worker-class ${SERVER_WORKER_CLASS:-gevent} \--timeout ${GUNICORN_TIMEOUT:-200} \--preload \app:appfi
fi
- 這部分代碼決定如何啟動 Flask 應用。如果
DEBUG
環境變量被設置為"true"
,則使用 Flask 的開發服務器啟動應用。否則,使用 Gunicorn 作為 WSGI HTTP 服務器來運行應用,配置包括綁定的 IP 和端口、工作進程數量、工作進程類型、超時設置等。
整體上,這個腳本提供了靈活的啟動配置,使得根據不同的環境需求(開發、生產、任務執行等)可以靈活地啟動相應的服務。