File size: 5,371 Bytes
0c0d5e5
 
7ce37bf
0c0d5e5
 
 
 
 
 
 
 
7ce37bf
0c0d5e5
 
 
 
7e4b3da
b563962
0c0d5e5
116ec26
b563962
 
 
 
4680b44
b563962
7ce37bf
b563962
7ce37bf
b563962
6aed364
b563962
7ce37bf
0c0d5e5
 
 
4680b44
 
0c0d5e5
 
 
 
 
 
 
4680b44
0c0d5e5
 
 
4680b44
0c0d5e5
 
 
a4bef0b
496ca32
443bf8a
 
 
4680b44
 
0c0d5e5
a4bef0b
 
e3e3266
 
 
 
 
e6f660c
0c0d5e5
496ca32
e3e3266
0404cc9
e3e3266
a4bef0b
6856dac
5bef8b0
 
 
 
 
 
 
 
e3e3266
e6f660c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6856dac
443bf8a
 
0404cc9
443bf8a
 
0404cc9
 
 
 
 
e3e3266
 
 
a4bef0b
7ce37bf
 
 
6aed364
7ce37bf
6aed364
7ce37bf
0404cc9
6856dac
 
e3e3266
e6f660c
24a6514
4b5756e
24a6514
 
 
 
 
4b5756e
24a6514
 
 
4b5756e
 
24a6514
4b5756e
 
 
24a6514
 
4b5756e
24a6514
 
4b5756e
24a6514
93dd07b
 
 
 
 
 
 
 
 
 
 
 
 
4b5756e
 
 
 
 
 
 
 
 
 
 
 
 
a4bef0b
443bf8a
 
 
e3e3266
 
a4bef0b
0c0d5e5
0404cc9
 
c7a62ec
0404cc9
a4bef0b
443bf8a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# 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/ .

# 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 \
    curl \
    libgmp-dev \
    libmpfr-dev \
    libmpc-dev \
    fonts-noto-cjk \
    ffmpeg \
    && rm -rf /var/lib/apt/lists/*

# Create app directory structure and storage directory
WORKDIR /app
RUN mkdir -p api web api/storage && chown -R user:user /app

# Install Python packages globally
RUN pip install --no-cache-dir \
    gunicorn \
    gevent \
    flask \
    cloudscraper \
    torch \
    tensorflow \
    flax \
    transformers \
    celery \
    arxiv \
    matplotlib \
    duckduckgo_search \
    jsonpath_ng \
    pydub \
    qrcode \
    twilio \
    vanna \
    wikipedia \
    yfinance \
    scipy \
    nltk \
    unstructured

# Download NLTK data
RUN python -m nltk.downloader punkt averaged_perceptron_tagger

# 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/ /app/api/

# Copy web build artifacts with correct permissions
COPY --from=web-builder --chown=user /app/web/.next /app/web/.next
COPY --from=web-builder --chown=user /app/web/public /app/web/public
COPY --from=web-builder --chown=user /app/web/node_modules /app/web/node_modules
COPY --from=web-builder --chown=user /app/web/package.json /app/web/package.json

# Create persistent storage volume
VOLUME ["/app/api/storage"]

# 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 \
    HOME=/app \
    PATH="/usr/local/bin:${PATH}" \
    PYTHONPATH=/app/api \
    TZ=UTC \
    NLTK_DATA=/usr/local/share/nltk_data \
    # Database configuration
    DB_USERNAME=postgres \
    DB_PASSWORD=difyai123456 \
    DB_HOST=localhost \
    DB_PORT=5432 \
    DB_DATABASE=dify \
    # Redis configuration
    REDIS_HOST=localhost \
    REDIS_PORT=6379 \
    REDIS_DB=0 \
    # Mail configuration - Using resend as default
    MAIL_TYPE=resend \
    MAIL_DEFAULT_SENDER=no[email protected] \
    MAIL_DEFAULT_SENDER_NAME=Dify \
    MAIL_RESEND_API_KEY=null \
    # Storage configuration
    STORAGE_TYPE=local \
    STORAGE_LOCAL_PATH=/app/api/storage \
    # Vector store configuration
    VECTOR_STORE=qdrant \
    QDRANT_URL=http://localhost:6333 \
    # Security configuration
    SECRET_KEY=your-secret-key \
    SECURITY_PASSWORD_SALT=your-password-salt \
    # Core configuration
    EDITION=SELF_HOSTED \
    DEPLOY_ENV=PRODUCTION \
    # Disable telemetry
    DISABLE_TELEMETRY=true \
    # Debug mode
    DEBUG=false \
    # Log level
    LOG_LEVEL=INFO \
    # Allow demo mode
    DEMO_MODE=false \
    # Disable registration
    DISABLE_REGISTRATION=false \
    # Additional required configurations
    CELERY_BROKER_URL=redis://localhost:6379/1 \
    CELERY_RESULT_BACKEND=redis://localhost:6379/2 \
    SENTRY_DSN="" \
    SENTRY_TRACES_SAMPLE_RATE=1.0 \
    SENTRY_PROFILES_SAMPLE_RATE=1.0 \
    OAUTH_REDIRECT_PATH=/console/api/oauth/authorize \
    OAUTH_REDIRECT_INDEX_PATH=/console/api/oauth/callback \
    CONSOLE_URL=http://localhost:3000 \
    SERVICE_API_URL=http://localhost:7860 \
    APP_API_URL=http://localhost:7860 \
    APP_WEB_URL=http://localhost:3000

# Switch to the non-root user
USER user

# Expose all necessary ports based on docker-compose files
EXPOSE 7860 3000 5001

# Setup entrypoint
COPY --chown=user docker/entrypoint.sh /app/entrypoint.sh
RUN chmod +x /app/entrypoint.sh

WORKDIR /app

CMD ["./entrypoint.sh"]