1+ # Stage 1: Compile and build code
2+ FROM python:3.11 AS builder
3+
4+ # Add poetry to the image
5+ RUN pip install --no-cache-dir poetry
6+
7+ # Copy pyproject.toml and poetry.lock
8+ ADD pyproject.toml /pyproject.toml
9+ ADD poetry.lock /poetry.lock
10+
11+ # Install dependencies
12+ RUN poetry config virtualenvs.create false
13+ RUN poetry install --no-root --no-dev --no-interaction --no-ansi
14+ RUN poetry install --only server --no-root --no-dev --no-interaction --no-ansi
15+
16+ # Download nltk and spacy data
17+ RUN mkdir -p /usr/local/share/nltk_data/tokenizers
18+ RUN mkdir -p /usr/local/share/nltk_data/taggers
19+
20+ ENV NLTK_DATA=/usr/local/share/nltk_data
21+ ARG UNIQUE_IDENTIFIER=promptly
22+
23+ # Install processors
24+ RUN poetry install --no-root --with processors
25+
26+ RUN python -m nltk.downloader -d /usr/local/share/nltk_data 'punkt'
27+ RUN python -m nltk.downloader -d /usr/local/share/nltk_data 'averaged_perceptron_tagger'
28+ RUN python -m spacy download en_core_web_sm
29+
30+ # Hack for installing chromadb embedding models
31+ RUN python -c "from chromadb.utils import embedding_functions as f; f.DefaultEmbeddingFunction()(['a'])"
32+
33+ RUN mkdir /code/
34+ WORKDIR /code/
35+ ADD ./manage.py /code/manage.py
36+ ADD ./llmstack /code/llmstack
37+ ADD ./docker /code/docker
38+
39+ # Environment variables
40+ ENV DJANGO_SETTINGS_MODULE=llmstack.server.settings
41+
42+ # Call collectstatic
43+ RUN python manage.py collectstatic --noinput --clear
44+
45+ # Stage 2: Build final image
46+ FROM python:3.11-slim
47+
48+ ARG APP_USER=appuser
49+ RUN groupadd -r ${APP_USER} && useradd --no-log-init -r -g ${APP_USER} ${APP_USER} \
50+ && mkdir -p /home/${APP_USER} \
51+ && mkdir -p /home/${APP_USER}/.cache/chroma \
52+ && chown -R ${APP_USER}:${APP_USER} /home/${APP_USER} \
53+ && chown -R ${APP_USER}:${APP_USER} /home/${APP_USER}/.cache/chroma
54+
55+ # Install runtime dependencies
56+ RUN set -ex \
57+ && RUN_DEPS=" \
58+ libpcre3 \
59+ mime-support \
60+ ffmpeg \
61+ postgresql-client \
62+ gstreamer1.0-libav \
63+ libnss3-tools \
64+ libatk-bridge2.0-0 \
65+ libcups2-dev \
66+ libxkbcommon-x11-0 \
67+ libxcomposite-dev \
68+ libxdamage-dev \
69+ tesseract-ocr \
70+ libtesseract-dev \
71+ tesseract-ocr-eng \
72+ tesseract-ocr-chi-sim \
73+ tesseract-ocr-script-latn \
74+ tesseract-ocr-script-deva \
75+ poppler-utils \
76+ " \
77+ && seq 1 8 | xargs -I{} mkdir -p /usr/share/man/man{} \
78+ && apt-get update && apt-get install -y --no-install-recommends $RUN_DEPS \
79+ && rm -rf /var/lib/apt/lists/*
80+
81+ # Copy application code
82+ COPY --from=builder /code/llmstack/client/build/index.html /code/client/build/index.html
83+ COPY --from=builder /code/llmstack/client/build/static /code/client/build/static
84+ COPY --from=builder /code/llmstack/contrib/apps /code/llmstack/contrib/apps
85+ COPY --from=builder /code/llmstack /code/llmstack
86+ COPY --from=builder /code/llmstack/static /code/llmstack/static
87+ COPY --from=builder /code/manage.py /code/manage.py
88+ COPY --from=builder /code/docker/api/docker-entrypoint.sh /code/docker-entrypoint.sh
89+
90+ COPY --from=builder /root/.cache/pip /root/.cache/pip
91+ COPY --from=builder /root/.cache/chroma /home/${APP_USER}/.cache/chroma
92+ COPY --from=builder /usr/local/lib/python3.11/site-packages/ /usr/local/lib/python3.11/site-packages/
93+ COPY --from=builder /usr/local/bin/ /usr/local/bin/
94+ COPY --from=builder /usr/local/share/nltk_data /usr/local/share/nltk_data
95+
96+ RUN chown -R ${APP_USER}:${APP_USER} /home/${APP_USER}/.cache/chroma
97+ RUN chown -R ${APP_USER}:${APP_USER} /code
98+
99+ WORKDIR /code/
100+
101+ ENV DJANGO_SETTINGS_MODULE=llmstack.server.settings
102+
103+ EXPOSE 9000
104+
105+ USER ${APP_USER}:${APP_USER}
106+
107+ ENV PATH="/home/${APP_USER}/.local/bin:${PATH}"
108+
109+ ENTRYPOINT ["/code/docker-entrypoint.sh" ]
110+
111+ CMD ["/usr/local/bin/gunicorn" , "llmstack.server.asgi:application" , "-w" , "2" , "-t" , "120" , "-b" , ":9000" , "-k" , "uvicorn.workers.UvicornWorker" ]
0 commit comments