File size: 6,488 Bytes
6aecb2e | 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 | # LandPPT Docker Image
# Multi-stage build for minimal image size
# Build stage
FROM python:3.11-slim-bookworm AS builder
# Set environment variables for build
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers \
PLAYWRIGHT_SKIP_VALIDATE_HOST_REQUIREMENTS=1
# Install build dependencies
ARG APT_DEBIAN_URL=http://deb.debian.org/debian
ARG APT_SECURITY_URL=http://deb.debian.org/debian-security
RUN set -eux; \
if [ -f /etc/apt/sources.list.d/debian.sources ]; then \
sed -i "s|http://deb.debian.org/debian|${APT_DEBIAN_URL}|g" /etc/apt/sources.list.d/debian.sources; \
sed -i "s|http://deb.debian.org/debian-security|${APT_SECURITY_URL}|g" /etc/apt/sources.list.d/debian.sources; \
elif [ -f /etc/apt/sources.list ]; then \
sed -i "s|http://deb.debian.org/debian|${APT_DEBIAN_URL}|g" /etc/apt/sources.list; \
sed -i "s|http://deb.debian.org/debian-security|${APT_SECURITY_URL}|g" /etc/apt/sources.list; \
fi; \
apt-get -o Acquire::Retries=5 -o Acquire::http::Timeout=30 update; \
apt-get install -y --no-install-recommends \
build-essential \
ca-certificates \
curl \
git \
libpq-dev \
libatomic1 \
; \
rm -rf /var/lib/apt/lists/*
# Install uv for faster dependency management
RUN pip install --no-cache-dir uv
# Create a dedicated virtualenv for runtime dependencies.
# Note: `uv sync` defaults to `.venv`; we explicitly sync to this env via `--active`.
RUN uv venv /opt/venv --python python3.11
ENV VIRTUAL_ENV=/opt/venv \
PATH=/opt/venv/bin:$PATH
# Set work directory and copy dependency files
WORKDIR /app
COPY pyproject.toml uv.lock* uv.toml README.md ./
COPY src/ ./src/
# Install Python dependencies using uv
# uv sync will create venv at UV_PROJECT_ENVIRONMENT and install all dependencies
RUN uv sync --active --no-dev --frozen --extra-index-url=https://pypi.apryse.com && \
# Clean up build artifacts
find /opt/venv -name "*.pyc" -delete && \
find /opt/venv -name "__pycache__" -type d -exec rm -rf {} + 2>/dev/null || true
# Sanity check: fail the build early if core runtime deps are missing.
RUN /opt/venv/bin/python -c "import fastapi, uvicorn, edge_tts; print('Core deps installed')"
# Install Playwright browsers in builder stage
RUN mkdir -p /opt/playwright-browsers && \
/opt/venv/bin/python -m playwright install chromium || \
(echo "Retrying with mirror..." && \
PLAYWRIGHT_DOWNLOAD_HOST=https://npmmirror.com/mirrors/playwright \
/opt/venv/bin/python -m playwright install chromium)
# Production stage
FROM python:3.11-slim-bookworm AS production
# Set environment variables
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONPATH=/app/src:/opt/venv/lib/python3.11/site-packages \
PATH=/opt/venv/bin:$PATH \
PLAYWRIGHT_BROWSERS_PATH=/opt/playwright-browsers \
HOME=/root \
VIRTUAL_ENV=/opt/venv \
PORT=7860 \
WORKERS=4 \
RELOAD=false
# Allow overriding Debian mirrors (useful in restricted networks).
ARG APT_DEBIAN_URL=http://deb.debian.org/debian
ARG APT_SECURITY_URL=http://deb.debian.org/debian-security
# Install essential runtime dependencies
RUN set -eux; \
if [ -f /etc/apt/sources.list.d/debian.sources ]; then \
sed -i "s|http://deb.debian.org/debian|${APT_DEBIAN_URL}|g" /etc/apt/sources.list.d/debian.sources; \
sed -i "s|http://deb.debian.org/debian-security|${APT_SECURITY_URL}|g" /etc/apt/sources.list.d/debian.sources; \
elif [ -f /etc/apt/sources.list ]; then \
sed -i "s|http://deb.debian.org/debian|${APT_DEBIAN_URL}|g" /etc/apt/sources.list; \
sed -i "s|http://deb.debian.org/debian-security|${APT_SECURITY_URL}|g" /etc/apt/sources.list; \
fi; \
apt-get -o Acquire::Retries=5 -o Acquire::http::Timeout=30 update; \
apt-get install -y --no-install-recommends \
ffmpeg \
poppler-utils \
libmagic1 \
libpq5 \
ca-certificates \
curl \
wget \
libgomp1 \
libatomic1 \
fonts-liberation \
fonts-noto-cjk \
fontconfig \
netcat-openbsd \
libjpeg62-turbo \
libxrender1 \
libfontconfig1 \
libx11-6 \
libxext6 \
# Chromium/Playwright runtime dependencies
libnss3 \
libatk1.0-0 \
libatk-bridge2.0-0 \
libcups2 \
libdrm2 \
libxkbcommon0 \
libxcomposite1 \
libxdamage1 \
libxfixes3 \
libxrandr2 \
libgbm1 \
libasound2 \
libpango-1.0-0 \
libcairo2 \
# GPU acceleration support (optional, for NVIDIA containers)
libegl1 \
libgl1 \
libgles2 \
; \
fc-cache -fv; \
apt-get clean; \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /root/.cache
# Create non-root user (for compatibility, but run as root)
RUN groupadd -r landppt && \
useradd -r -g landppt -m -d /home/landppt landppt
# Copy Python packages from builder
COPY --from=builder /opt/venv /opt/venv
# Copy Playwright browsers from builder
COPY --from=builder /opt/playwright-browsers /opt/playwright-browsers
# Sanity check: ensure the copied venv is usable in the runtime image.
RUN /opt/venv/bin/python -c "import fastapi, uvicorn; print('Runtime venv OK')"
# Set permissions for landppt user and playwright browsers
RUN chown -R landppt:landppt /home/landppt && \
chmod -R 755 /opt/playwright-browsers
# Set work directory
WORKDIR /app
# Copy application code (minimize layers)
COPY run.py ./
COPY src/ ./src/
COPY template_examples/ ./template_examples/
COPY docker-healthcheck.sh docker-entrypoint.sh /usr/local/bin/
COPY .env.example ./.env
# Create directories and set permissions in one layer
RUN sed -i 's/\r$//' /usr/local/bin/docker-healthcheck.sh /usr/local/bin/docker-entrypoint.sh && \
chmod +x /usr/local/bin/docker-healthcheck.sh /usr/local/bin/docker-entrypoint.sh && \
mkdir -p temp/ai_responses_cache temp/style_genes_cache temp/summeryanyfile_cache temp/templates_cache \
research_reports lib/Linux lib/MacOS lib/Windows uploads data && \
chown -R landppt:landppt /app /home/landppt && \
chmod -R 755 /app /home/landppt && \
chmod 666 /app/.env
# Expose port
EXPOSE 7860
# Minimal health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=2 \
CMD ["/usr/local/bin/docker-healthcheck.sh"]
# Set entrypoint and command
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
CMD ["/opt/venv/bin/python", "run.py"]
|