mirror of
https://github.com/wizarrrr/wizarr.git
synced 2026-07-31 07:17:10 -04:00
- 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.
125 lines
4.3 KiB
Docker
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"] |