| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| FROM node:20-slim AS web-builder |
|
|
| RUN apt-get update && apt-get install -y --no-install-recommends \ |
| git ca-certificates \ |
| && rm -rf /var/lib/apt/lists/* |
|
|
| RUN git clone --depth 1 --branch 1.14.2 \ |
| https://github.com/langgenius/dify.git /tmp/dify \ |
| && cp -r /tmp/dify/web /app/web \ |
| && rm -rf /tmp/dify |
|
|
| WORKDIR /app/web |
| RUN npm install -g pnpm \ |
| && pnpm install --frozen-lockfile \ |
| && pnpm build |
|
|
| |
| FROM python:3.12-slim-bookworm |
|
|
| |
| |
| |
| RUN apt-get update && apt-get install -y --no-install-recommends \ |
| git curl ca-certificates gnupg \ |
| nginx supervisor \ |
| libpq-dev libmagic1 libcairo2 libglib2.0-0 \ |
| poppler-utils tesseract-ocr \ |
| && curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \ |
| && apt-get install -y nodejs \ |
| && rm -rf /var/lib/apt/lists/* |
|
|
| |
| |
| |
| RUN git clone --depth 1 --branch 1.14.2 \ |
| https://github.com/langgenius/dify.git /tmp/dify \ |
| && cp -r /tmp/dify/api /app/api \ |
| && rm -rf /tmp/dify |
|
|
| WORKDIR /app/api |
| RUN pip install --no-cache-dir uv==0.6.14 \ |
| && uv sync --frozen --no-dev |
|
|
| |
| |
| |
| RUN curl -L \ |
| "https://github.com/langgenius/dify-plugin-daemon/releases/download/0.1.0/dify-plugin-daemon-linux-amd64" \ |
| -o /app/plugin_daemon \ |
| && chmod +x /app/plugin_daemon |
|
|
| |
| |
| |
| COPY --from=web-builder /app/web/.next/standalone /app/web |
| COPY --from=web-builder /app/web/.next/static /app/web/.next/static |
| COPY --from=web-builder /app/web/public /app/web/public |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| ENV \ |
| |
| PYTHONUNBUFFERED=1 \ |
| PYTHONDONTWRITEBYTECODE=1 \ |
| MALLOC_ARENA_MAX=2 \ |
| \ |
| |
| NODE_OPTIONS="--max-old-space-size=2048" \ |
| \ |
| |
| DB_HOST=aws-1-eu-central-1.pooler.supabase.com \ |
| DB_PORT=6543 \ |
| DB_USERNAME=postgres.bumhiinnvlbrpmvjpuwu \ |
| DB_DATABASE=postgres \ |
| \ |
| |
| PGVECTOR_HOST=db.bumhiinnvlbrpmvjpuwu.supabase.co \ |
| PGVECTOR_PORT=5432 \ |
| PGVECTOR_USER=postgres \ |
| PGVECTOR_DATABASE=postgres \ |
| VECTOR_STORE=pgvector \ |
| \ |
| |
| REDIS_HOST=fitting-wildcat-109052.upstash.io \ |
| REDIS_PORT=6379 \ |
| REDIS_USERNAME=default \ |
| REDIS_USE_SSL=true \ |
| \ |
| |
| SERVER_WORKER_AMOUNT=1 \ |
| CELERY_WORKER_AMOUNT=1 \ |
| \ |
| |
| STORAGE_TYPE=local \ |
| STORAGE_LOCAL_PATH=/app/api/storage \ |
| \ |
| |
| PLUGIN_DAEMON_URL=http://127.0.0.1:5002 \ |
| \ |
| |
| CODE_EXECUTION_ENABLED=false \ |
| \ |
| |
| MIGRATION_ENABLED=true \ |
| \ |
| |
| LOG_LEVEL=INFO \ |
| LOG_FILE=/app/logs/server.log \ |
| \ |
| |
| DEPLOY_ENV=PRODUCTION \ |
| FLASK_APP=app.py \ |
| \ |
| |
| TZ=Europe/Berlin \ |
| GENERIC_TIMEZONE=Europe/Berlin |
|
|
| |
| |
| |
| RUN mkdir -p /app/api/storage /app/logs /var/log/supervisor /run/nginx |
|
|
| |
| |
| |
| RUN cat > /etc/nginx/nginx.conf << 'EOF' |
| user www-data; |
| worker_processes 1; |
| pid /run/nginx.pid; |
| events { worker_connections 512; } |
| http { |
| include /etc/nginx/mime.types; |
| default_type application/octet-stream; |
| sendfile on; |
| keepalive_timeout 65; |
| client_max_body_size 100M; |
| server { |
| listen 7860; |
| server_name _; |
| location ~ ^/(console/api|api|v1|files|explore) { |
| proxy_pass http://127.0.0.1:5001; |
| proxy_set_header Host $host; |
| proxy_set_header X-Real-IP $remote_addr; |
| proxy_read_timeout 300s; |
| proxy_buffering off; |
| proxy_cache off; |
| } |
| location / { |
| proxy_pass http://127.0.0.1:3000; |
| proxy_set_header Host $host; |
| proxy_http_version 1.1; |
| proxy_set_header Upgrade $http_upgrade; |
| proxy_set_header Connection "upgrade"; |
| } |
| } |
| } |
| EOF |
|
|
| |
| |
| |
| RUN cat > /etc/supervisor/conf.d/dify.conf << 'EOF' |
| [supervisord] |
| nodaemon=true |
| logfile=/var/log/supervisor/supervisord.log |
| childlogdir=/var/log/supervisor |
|
|
| [program:nginx] |
| command=nginx -g "daemon off;" |
| autostart=true |
| autorestart=true |
| priority=10 |
| stdout_logfile=/var/log/supervisor/nginx.log |
| stderr_logfile=/var/log/supervisor/nginx.err.log |
|
|
| [program:plugin_daemon] |
| command=/app/plugin_daemon |
| directory=/app |
| autostart=true |
| autorestart=true |
| priority=20 |
| stdout_logfile=/var/log/supervisor/plugin_daemon.log |
| stderr_logfile=/var/log/supervisor/plugin_daemon.err.log |
|
|
| [program:api] |
| command=uv run gunicorn \ |
| --bind 127.0.0.1:5001 \ |
| --workers 1 \ |
| --worker-class geventwebsocket.gunicorn.workers.GeventWebSocketWorker \ |
| --timeout 200 \ |
| app:app |
| directory=/app/api |
| autostart=true |
| autorestart=true |
| priority=30 |
| stdout_logfile=/var/log/supervisor/api.log |
| stderr_logfile=/var/log/supervisor/api.err.log |
|
|
| [program:worker] |
| command=uv run celery \ |
| -A app.celery worker \ |
| --concurrency 1 \ |
| --loglevel INFO \ |
| -Q dataset,generation,mail,ops_trace,app_deletion |
| directory=/app/api |
| autostart=true |
| autorestart=true |
| priority=30 |
| stdout_logfile=/var/log/supervisor/worker.log |
| stderr_logfile=/var/log/supervisor/worker.err.log |
|
|
| [program:web] |
| command=node server.js |
| directory=/app/web |
| autostart=true |
| autorestart=true |
| priority=40 |
| environment=PORT="3000",HOSTNAME="127.0.0.1" |
| stdout_logfile=/var/log/supervisor/web.log |
| stderr_logfile=/var/log/supervisor/web.err.log |
| EOF |
|
|
| |
| |
| |
| RUN cat > /entrypoint.sh << 'EOF' |
| |
| set -e |
| echo "ββββββββββββββββββββββββββββββββββββββββ" |
| echo " Dify 1.14.2 β dΓ©marrage" |
| echo "ββββββββββββββββββββββββββββββββββββββββ" |
| cd /app/api |
| for i in 1 2 3 4 5; do |
| uv run flask db upgrade && break |
| echo "[init] Tentative $i Γ©chouΓ©e, retry dans 5s..." |
| sleep 5 |
| done |
| echo "[init] Migrations OK" |
| exec supervisord -c /etc/supervisor/conf.d/dify.conf |
| EOF |
| RUN chmod +x /entrypoint.sh |
|
|
| EXPOSE 7860 |
| CMD ["/entrypoint.sh"] |
|
|