Files
wizarr/Dockerfile.plus
Matthieu B 813601d37b feat: Add Wizarr Plus licensing and historical data import features
- Implemented LicenseValidationMiddleware for periodic license validation and feature protection.
- Created HistoricalDataService for importing historical viewing data from Plex into the ActivitySession model.
- Added KeygenLicenseService for runtime license verification and machine fingerprinting.
- Introduced new Jinja filters for built-in functions max and min.
- Updated settings UI to include a tab for Plus features.
- Added Docker support for Wizarr Plus with a dedicated docker-compose file.
- Created entrypoint script for license verification and initialization of the Wizarr Plus container.
- Added wrapper scripts for building, verifying licenses, and setting up Wizarr Plus.
- Updated dependencies in pyproject.toml to include websocket-client for Plus features.
2025-10-09 12:14:27 +02:00

125 lines
4.3 KiB
Docker

# ─── Stage 1: Dependencies ───────────────────────────────────────────────
FROM ghcr.io/astral-sh/uv:python3.13-alpine AS deps
# Install system dependencies including build tools for Cython
RUN apk add --no-cache nodejs npm gcc musl-dev python3-dev
# Set working directory
WORKDIR /app
# Enable bytecode compilation for faster startup
ENV UV_COMPILE_BYTECODE=1
# Use copy link mode to avoid warnings with cache mounts
ENV UV_LINK_MODE=copy
# Copy dependency files first for better caching
COPY pyproject.toml uv.lock ./
# Install Python dependencies including Cython and cryptography for compilation
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-install-project --no-dev && \
uv pip install cython pycryptodome requests
# Copy npm dependency files and install with cache
COPY app/static/package*.json ./app/static/
RUN npm --prefix app/static/ ci --cache /tmp/npm-cache
# ─── Stage 2: Build assets + Compile Cython ───────────────────────────────
FROM deps AS builder
# Copy source files needed for building
COPY app/ ./app/
COPY babel.cfg ./
# Copy plus submodule with build tools and source
COPY plus/ ./plus/
# Install the project now that we have source code
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
# Build translations
RUN uv run --frozen --no-dev pybabel compile -d app/translations
# Ensure static directories exist and build static assets
RUN mkdir -p app/static/js app/static/css && npm --prefix app/static/ run build
# Compile templates into Python module
RUN uv run python plus/build_tools/compile_plus_templates.py
# Compile plus module to Cython (including embedded templates)
RUN uv run python plus/build_tools/setup_plus.py build_ext --inplace
# Remove original source files and templates from plus directory
RUN find plus/ -name "*.py" -not -name "__init__.py" -delete && \
find plus/ -name "*.c" -delete && \
find plus/ -name "*.html" -delete && \
find plus/ -name "*.jinja2" -delete
# ─── Stage 3: Runtime ─────────────────────────────────────────────────────
FROM ghcr.io/astral-sh/uv:python3.13-alpine
# Set default environment variables for user/group IDs
ENV PUID=1000
ENV PGID=1000
# Install runtime dependencies only
RUN apk add --no-cache curl tzdata su-exec
# Set application working directory
WORKDIR /app
# Copy Python environment from builder stage (includes project)
COPY --chown=1000:1000 --from=builder /app/.venv /app/.venv
# Copy application code and built assets
COPY --chown=1000:1000 --from=builder /app/app /app/app
# Copy compiled plus module (only .so files and __init__.py)
COPY --chown=1000:1000 --from=builder /app/plus /app/plus
# Copy license verification script from plus submodule
COPY --chown=1000:1000 --from=builder /app/plus/build_tools/verify_plus_license.py /usr/local/bin/verify_plus_license.py
RUN chmod +x /usr/local/bin/verify_plus_license.py
# Copy rest of application
COPY --chown=1000:1000 . /app
# Create data directory for database (backward compatibility)
RUN mkdir -p /data/database
# Create wizard steps config directory
RUN mkdir -p /etc/wizarr/wizard_steps
# Create directories that need to be writable
RUN mkdir -p /.cache
ARG APP_VERSION=dev
ENV APP_VERSION=${APP_VERSION}
# Set environment variable to indicate this is the plus edition
ENV WIZARR_PLUS_COMPILED=1
# Healthcheck: curl to localhost:5690/health
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD curl -fs http://localhost:5690/health || exit 1
# Expose port 5690
EXPOSE 5690
# Copy any wizard steps into /opt
COPY wizard_steps /opt/default_wizard_steps
# Copy Plus-specific entrypoint script and make it executable
COPY docker-entrypoint-plus.sh /usr/local/bin/docker-entrypoint.sh
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
# Entrypoint and default CMD
ENTRYPOINT ["docker-entrypoint.sh"]
# By default we run Gunicorn under wizarruser
CMD ["uv", "run", "--frozen", "--no-dev", "gunicorn", \
"--config", "gunicorn.conf.py", \
"--bind", "0.0.0.0:5690", \
"--umask", "007", \
"run:app"]