# ============================================================================= # Dify on HuggingFace Spaces - Single Container with Persistent Storage at /data # ============================================================================= ARG DIFY_VERSION=1.14.2 # Stage 1: Clone source FROM alpine/git:latest AS source ARG DIFY_VERSION RUN git clone --depth 1 --branch ${DIFY_VERSION} https://github.com/langgenius/dify.git /dify # Stage 2: Build API Python dependencies FROM python:3.12-slim-bookworm AS api-builder WORKDIR /app/api ENV UV_VERSION=0.8.9 RUN pip install --no-cache-dir uv==${UV_VERSION} RUN apt-get update && apt-get install -y --no-install-recommends g++ libmpfr-dev libmpc-dev && rm -rf /var/lib/apt/lists/* COPY --from=source /dify/api/pyproject.toml /dify/api/uv.lock ./ COPY --from=source /dify/api/providers ./providers RUN uv sync --frozen --no-dev # Stage 3: Build web frontend FROM node:22-alpine AS web-builder RUN corepack enable WORKDIR /dify COPY --from=source /dify/package.json /dify/pnpm-lock.yaml /dify/pnpm-workspace.yaml ./ COPY --from=source /dify/web/package.json ./web/ COPY --from=source /dify/e2e/package.json ./e2e/ COPY --from=source /dify/sdks/nodejs-client/package.json ./sdks/nodejs-client/ COPY --from=source /dify/packages ./packages RUN corepack install RUN VITE_GIT_HOOKS=0 pnpm install --frozen-lockfile COPY --from=source /dify/ . WORKDIR /dify/web ENV NODE_OPTIONS="--max-old-space-size=4096" ENV pnpm_config_verify_deps_before_run=false RUN pnpm build # Stage 4: Final runtime image FROM python:3.12-slim-bookworm ENV DEBIAN_FRONTEND=noninteractive \ TZ=UTC \ LANG=C.UTF-8 \ LC_ALL=C.UTF-8 \ PYTHONIOENCODING=utf-8 # Dify environment ENV FLASK_APP=app.py \ EDITION=SELF_HOSTED \ DEPLOY_ENV=PRODUCTION \ SECRET_KEY=sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U \ INIT_PASSWORD=dify123456 \ CONSOLE_API_URL="" \ CONSOLE_WEB_URL="" \ SERVICE_API_URL="" \ APP_API_URL="" \ APP_WEB_URL="" \ LOG_LEVEL=INFO \ DB_USERNAME=postgres \ DB_PASSWORD=difyai123456 \ DB_HOST=localhost \ DB_PORT=5432 \ DB_DATABASE=dify \ REDIS_HOST=localhost \ REDIS_PORT=6379 \ REDIS_PASSWORD=difyai123456 \ REDIS_DB=0 \ CELERY_BROKER_URL=redis://:difyai123456@localhost:6379/1 \ STORAGE_TYPE=local \ STORAGE_LOCAL_PATH=/data/storage \ MIGRATION_ENABLED=true \ SERVER_WORKER_AMOUNT=1 \ CELERY_WORKER_AMOUNT=1 ARG NODE_MAJOR=22 # Install system packages RUN apt-get update && apt-get install -y --no-install-recommends \ postgresql \ redis-server \ nginx \ supervisor \ curl \ gnupg \ ca-certificates \ libgmp-dev libmpfr-dev libmpc-dev \ fonts-noto-cjk \ media-types \ libmagic1 \ && mkdir -p /etc/apt/keyrings \ && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \ | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_MAJOR}.x nodistro main" \ > /etc/apt/sources.list.d/nodesource.list \ && apt-get update \ && apt-get install -y --no-install-recommends nodejs \ && apt-get autoremove -y \ && rm -rf /var/lib/apt/lists/* # Copy API virtual environment ENV VIRTUAL_ENV=/app/api/.venv COPY --from=api-builder /app/api/.venv ${VIRTUAL_ENV} ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" # Download NLTK data RUN mkdir -p /usr/local/share/nltk_data \ && python -c "import nltk; nltk.download('punkt'); nltk.download('averaged_perceptron_tagger'); nltk.download('stopwords')" \ && chmod -R 755 /usr/local/share/nltk_data ENV NLTK_DATA=/usr/local/share/nltk_data # Download tiktoken cache ENV TIKTOKEN_CACHE_DIR=/app/api/.tiktoken_cache RUN python -c "import tiktoken; tiktoken.encoding_for_model('gpt2')" # Copy API source code COPY --from=source /dify/api /app/api # Copy web frontend (Next.js standalone build) COPY --from=web-builder /dify/web/public /app/web/public COPY --from=web-builder /dify/web/.next/standalone /app/web-standalone COPY --from=web-builder /dify/web/.next/static /app/web-standalone/web/.next/static # Create directories RUN mkdir -p /data/postgres /data/redis /data/storage /var/log/supervisor /run/nginx \ /var/run/postgresql && chown postgres:postgres /var/run/postgresql # Copy config files COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY nginx.conf /etc/nginx/nginx.conf COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh EXPOSE 7860 ENTRYPOINT ["/entrypoint.sh"]