Files
talemate/Dockerfile
veguAI 856b4011fa Docker: Pi Bridge client + encrypted environment variable store (#105) (#106)
* Docker support for Pi Bridge client + encrypted environment variable store (#105)

* Address PR #106 review: env name validation on backend, add-form value/duplicate guards, stale openrouter convenience docs
2026-07-19 18:13:05 +03:00

138 lines
4.5 KiB
Docker

# Stage 1: Frontend build
FROM node:22-slim AS frontend-build
WORKDIR /app
# Enable pnpm via corepack (version pinned by package.json "packageManager").
ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0
RUN npm install -g corepack@latest && corepack enable
# Copy frontend manifest, lockfile and pnpm settings
COPY talemate_frontend/package.json talemate_frontend/pnpm-lock.yaml talemate_frontend/pnpm-workspace.yaml ./
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy frontend source
COPY talemate_frontend/ ./
# Build frontend
RUN pnpm build
# Stage 2: Backend build
FROM python:3.11-slim AS backend-build
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y \
bash \
gcc \
&& rm -rf /var/lib/apt/lists/*
# Install uv
RUN pip install uv
# Copy installation files
COPY pyproject.toml uv.lock /app/
# Copy the Python source code (needed for editable install)
COPY ./src /app/src
# Create virtual environment and install dependencies (includes CUDA support via pyproject.toml)
RUN uv sync
# Stage 3: Final image
FROM python:3.11-slim
WORKDIR /app
RUN apt-get update && apt-get install -y \
bash \
wget \
tar \
xz-utils \
gettext-base \
libstdc++6 \
&& rm -rf /var/lib/apt/lists/*
# Install uv in the final stage
RUN pip install uv
# Node.js runtime for the pi coding agent (Pi Bridge client), reused from the
# frontend build stage so the final image needs no extra apt source
COPY --from=frontend-build /usr/local/bin/node /usr/local/bin/node
COPY --from=frontend-build /usr/local/lib/node_modules /usr/local/lib/node_modules
RUN ln -sf /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm && \
ln -sf /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx
# Install pi for the Pi Bridge client (override the version via build arg)
ARG PI_VERSION=0.80.10
RUN npm install -g @earendil-works/pi-coding-agent@${PI_VERSION} && \
npm cache clean --force && \
pi --version
# pi config dir (models.json, auth.json) - mounted as a volume in docker-compose
# so it is host-editable and survives container recreation
ENV PI_CODING_AGENT_DIR=/app/pi
RUN mkdir -p /app/pi
# Copy virtual environment from backend-build stage
COPY --from=backend-build /app/.venv /app/.venv
# Download and install FFmpeg 8.0 with shared libraries into .venv (matching Windows installer approach)
# Using BtbN FFmpeg builds which provide shared libraries - verified to work
# Note: We tried using jrottenberg/ffmpeg:8.0-ubuntu image but copying libraries from it didn't work properly,
# so we use the direct download approach which is more reliable and matches the Windows installer
RUN cd /tmp && \
wget -q https://github.com/BtbN/FFmpeg-Builds/releases/download/latest/ffmpeg-master-latest-linux64-gpl-shared.tar.xz -O ffmpeg.tar.xz && \
tar -xf ffmpeg.tar.xz && \
cp -a ffmpeg-master-latest-linux64-gpl-shared/bin/* /app/.venv/bin/ && \
cp -a ffmpeg-master-latest-linux64-gpl-shared/lib/* /app/.venv/lib/ && \
rm -rf ffmpeg-master-latest-linux64-gpl-shared ffmpeg.tar.xz && \
LD_LIBRARY_PATH=/app/.venv/lib /app/.venv/bin/ffmpeg -version | head -n 1
# Set LD_LIBRARY_PATH so torchcodec can find ffmpeg libraries at runtime
ENV LD_LIBRARY_PATH=/app/.venv/lib:${LD_LIBRARY_PATH}
# Copy Python source code
COPY --from=backend-build /app/src /app/src
# Copy Node.js build artifacts from frontend-build stage
COPY --from=frontend-build /app/dist /app/talemate_frontend/dist
# Preserve index.html as template for runtime envsubst substitution
COPY --from=frontend-build /app/dist/index.html /app/talemate_frontend/dist/index.template.html
# Copy the frontend WSGI file if it exists
COPY frontend_wsgi.py /app/frontend_wsgi.py
# Copy base config
COPY config.example.yaml /app/config.yaml
# Copy essentials
COPY scenes/ /app/scenes/
COPY templates/ /app/templates/
COPY chroma* /app/
COPY tts/ /app/tts/
# Copy entrypoint script for runtime environment variable substitution
COPY docker-entrypoint.sh /app/docker-entrypoint.sh
RUN chmod +x /app/docker-entrypoint.sh
# Set PYTHONPATH to include the src directory
ENV PYTHONPATH=/app/src:$PYTHONPATH
# Bind on all interfaces inside the container by default. Ports can be
# overridden with TALEMATE_BACKEND_PORT / TALEMATE_FRONTEND_PORT.
ENV TALEMATE_BACKEND_HOST=0.0.0.0
ENV TALEMATE_FRONTEND_HOST=0.0.0.0
# Make ports available to the world outside this container
EXPOSE 5050
EXPOSE 8082
# Use entrypoint for runtime config, CMD for the actual server
ENTRYPOINT ["/app/docker-entrypoint.sh"]
CMD ["uv", "run", "src/talemate/server/run.py", "runserver"]