dify-api的Dockerfile分析

一.dify-api的Dockerfile文件

dify-api的Dockerfile文件如下所示:

markdown 复制代码
# base image
FROM python:3.10-slim-bookworm AS base

LABEL maintainer="takatost@gmail.com"

# install packages
FROM base as packages

RUN apt-get update \
    && apt-get install -y --no-install-recommends gcc g++ libc-dev libffi-dev libgmp-dev libmpfr-dev libmpc-dev

COPY requirements.txt /requirements.txt

RUN --mount=type=cache,target=/root/.cache/pip \
    pip install --prefix=/pkg -r requirements.txt

# production stage
FROM base AS production

ENV 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:3000

EXPOSE 5001

# set timezone
ENV TZ UTC

WORKDIR /app/api

RUN 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.sh

ARG COMMIT_SHA
ENV COMMIT_SHA ${COMMIT_SHA}

ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]

二.Dockerfile文件分析

这个 Dockerfile 设计用于构建基于 Python 的 Flask 应用。将逐行解释这个文件:

1.基础镜像阶段

dockerfile 复制代码
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.安装依赖包阶段

dockerfile 复制代码
FROM base as packages

RUN apt-get update \
    && apt-get install -y --no-install-recommends gcc g++ libc-dev libffi-dev libgmp-dev libmpfr-dev libmpc-dev

COPY requirements.txt /requirements.txt

RUN --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.生产阶段设置

dockerfile 复制代码
FROM base AS production

ENV FLASK_APP app.py
...
EXPOSE 5001
...
WORKDIR /app/api

RUN 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.sh

ARG 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_SHAENV COMMIT_SHA ${COMMIT_SHA}:接收并设置构建参数,用于标记版本。

  • ENTRYPOINT ["/bin/bash", "/entrypoint.sh"]:设置容器启动时执行的命令。

整个 Dockerfile 的设计旨在确保从依赖安装到应用部署的每个步骤都优化和安全,同时也支持构建缓存以加速多次构建过程。

三.dify\api\docker\entrypoint.sh文件分析

markdown 复制代码
#!/bin/bash

set -e

if [[ "${MIGRATION_ENABLED}" == "true" ]]; then
  echo "Running migrations"
  flask db upgrade
fi

if [[ "${MODE}" == "worker" ]]; then
  celery -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" ]]; then
  celery -A app.celery beat --loglevel INFO
else
  if [[ "${DEBUG}" == "true" ]]; then
    flask run --host=${DIFY_BIND_ADDRESS:-0.0.0.0} --port=${DIFY_PORT:-5001} --debug
  else
    gunicorn \
      --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:app
  fi
fi

这是一个 Bash 脚本,通常用于容器入口点(entrypoint)来启动 Flask 应用及相关服务。以下是脚本中每一行代码的中文解释:

bash 复制代码
#!/bin/bash
  • 这一行是 Shebang 行,指示操作系统使用 Bash 解释器执行此脚本。
bash 复制代码
set -e
  • 这一行设置了 Bash 的 -e 选项,意味着如果脚本中任何命令执行失败(返回非零状态),脚本将立即退出。
bash 复制代码
if [[ "${MIGRATION_ENABLED}" == "true" ]]; then
  echo "Running migrations"
  flask db upgrade
fi
  • 这个 if 语句检查环境变量 MIGRATION_ENABLED 是否设置为 "true"。如果是,执行数据库迁移命令 flask db upgrade,并在执行前打印 "Running migrations"。
bash 复制代码
if [[ "${MODE}" == "worker" ]]; then
  celery -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" ]]; then
  celery -A app.celery beat --loglevel INFO
  • 这段代码根据环境变量 MODE 的值启动 Celery。如果 MODE"worker",则启动 Celery worker,并配置相关的选项(如并发方式、日志级别等)。如果 MODE"beat",则启动 Celery beat 进程。
bash 复制代码
else
  if [[ "${DEBUG}" == "true" ]]; then
    flask run --host=${DIFY_BIND_ADDRESS:-0.0.0.0} --port=${DIFY_PORT:-5001} --debug
  else
    gunicorn \
      --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:app
  fi
fi
  • 这部分代码决定如何启动 Flask 应用。如果 DEBUG 环境变量被设置为 "true",则使用 Flask 的开发服务器启动应用。否则,使用 Gunicorn 作为 WSGI HTTP 服务器来运行应用,配置包括绑定的 IP 和端口、工作进程数量、工作进程类型、超时设置等。

整体上,这个脚本提供了灵活的启动配置,使得根据不同的环境需求(开发、生产、任务执行等)可以灵活地启动相应的服务。

相关推荐
谷莠子9051 小时前
hadoop实验之创业有感
hadoop·docker·团队开发
G丶AEOM1 小时前
Docker快速入门
docker
大熊程序猿2 小时前
airflow docker 安装
运维·docker·容器
带电的小王3 小时前
Docker在Ubuntu上安装
ubuntu·docker
fanruitian3 小时前
docker 为单个容器设置代理
运维·docker·容器
梁萌3 小时前
Docker快速安装Tomcat
docker·容器·tomcat·镜像
Doker 多克5 小时前
IntelliJ IDEA Docker集成
spring cloud·docker·intellij-idea
Json_181790144805 小时前
淘系商品评论json数据示例参考,API接口系列
大数据·json·api
筏镜11 小时前
调整docker bridge地址冲突,通过bip调整 bridge地址
java·docker·eureka
Heartsuit15 小时前
LLM大语言模型私有化部署-使用Dify的工作流编排打造专属AI搜索引擎
人工智能·dify·ollama·qwen2.5·ai搜索引擎·tavily search·工作流编排