dify / Dockerfile
Severian's picture
Update Dockerfile for correct directory structure
c7a62ec
raw
history blame
3.52 kB
# Base stage with shared configuration
FROM node:20.11-alpine3.19 AS base
# Configure build environment
ENV NODE_OPTIONS="--max_old_space_size=2048" \
NEXT_TELEMETRY_DISABLED=1 \
NODE_ENV=production \
PYTHONDONTWRITEBYTECODE=1 \
POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_CREATE=false \
POETRY_CACHE_DIR=/cache/poetry
# Web builder stage
FROM base AS web-builder
WORKDIR /app/web
# Copy package files first
COPY web/package.json web/yarn.lock ./
# Install build dependencies globally first
RUN npm install -g code-inspector-plugin autoprefixer postcss tailwindcss
# Install project dependencies
RUN yarn install --frozen-lockfile --network-timeout 300000 && \
yarn add --dev @types/node @types/react code-inspector-plugin autoprefixer postcss tailwindcss
# Copy source files
COPY web/ .
# Create a minimal next.config.js if needed
RUN if [ ! -f next.config.js ]; then \
echo "module.exports = { reactStrictMode: true };" > next.config.js; \
fi
# Build the application with standalone output
RUN NODE_PATH=/usr/local/lib/node_modules yarn build
# Python builder stage
FROM python:3.10-slim-bookworm AS python-builder
# Install build dependencies in a single layer
RUN apt-get update && \
apt-get install -y --no-install-recommends \
build-essential \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app/api
# Install and configure poetry
RUN pip install --no-cache-dir poetry
# Copy Python files and install dependencies
COPY api/pyproject.toml api/poetry.lock ./
RUN poetry config virtualenvs.create false && \
poetry install --no-dev --no-interaction --no-ansi
# Final stage
FROM python:3.10-slim-bookworm
# Set up a new user named "user" with user ID 1000 (required by Hugging Face)
RUN useradd -m -u 1000 user
# Install runtime dependencies in a single layer
RUN apt-get update && \
apt-get install -y --no-install-recommends \
nodejs \
npm \
&& rm -rf /var/lib/apt/lists/*
# Set home to the user's home directory
ENV HOME=/home/user \
PATH=/home/user/.local/bin:$PATH
# Create necessary directories with correct permissions
RUN mkdir -p /home/user/app/api /home/user/app/web && \
chown -R user:user /home/user/app
# Set the working directory
WORKDIR /home/user/app
# Install gunicorn
RUN pip install --no-cache-dir gunicorn gevent
# Copy Python environment and set permissions
COPY --from=python-builder --chown=user /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages
COPY --chown=user api/ /home/user/app/api/
# Copy web build artifacts with correct permissions
COPY --from=web-builder --chown=user /app/web/.next /home/user/app/web/.next
COPY --from=web-builder --chown=user /app/web/public /home/user/app/web/public
COPY --from=web-builder --chown=user /app/web/node_modules /home/user/app/web/node_modules
COPY --from=web-builder --chown=user /app/web/package.json /home/user/app/web/package.json
# Set environment variables
ENV FLASK_APP=app.py \
EDITION=SELF_HOSTED \
DEPLOY_ENV=PRODUCTION \
CONSOLE_API_URL=http://127.0.0.1:7860 \
CONSOLE_WEB_URL=http://127.0.0.1:3000 \
SERVICE_API_URL=http://127.0.0.1:7860 \
APP_WEB_URL=http://127.0.0.1:3000 \
NODE_ENV=production
# Switch to the non-root user
USER user
# Expose port 7860 as required by Hugging Face Spaces
EXPOSE 7860
# Setup entrypoint
COPY --chown=user docker/entrypoint.sh /home/user/app/entrypoint.sh
RUN chmod +x /home/user/app/entrypoint.sh
WORKDIR /home/user/app
CMD ["./entrypoint.sh"]