Some checks failed
Lint & Test / test (push) Failing after 48s
Security: tighten CORS defaults, add webhook rate limiting, fix XSS in automations, guard WebSocket JSON.parse, validate ADB address input, seal debug exception leak, URL-encode WS tokens, CSS.escape in selectors. Code quality: add Pydantic models for brightness/power endpoints, fix thread safety and name uniqueness in DeviceStore, immutable update pattern, split 6 oversized files into 16 focused modules, enable TypeScript strictNullChecks (741→102 errors), type state variables, add dom-utils helper, migrate 3 modules from inline onclick to event delegation, ProcessorDependencies dataclass. Performance: async store saves, health endpoint log level, command palette debounce, optimized entity-events comparison, fix service worker precache list. Testing: expand from 45 to 293 passing tests — add store tests (141), route tests (25), core logic tests (42), E2E flow tests (33), organize into tests/api/, tests/storage/, tests/core/, tests/e2e/. DevOps: CI test pipeline, pre-commit config, Dockerfile multi-stage build with non-root user and health check, docker-compose improvements, version bump to 0.2.0. Docs: rewrite CLAUDE.md (202→56 lines), server/CLAUDE.md (212→76), create contexts/server-operations.md, fix .js→.ts references, fix env var prefix in README, rewrite INSTALLATION.md, add CONTRIBUTING.md and .env.example.
68 lines
2.4 KiB
Docker
68 lines
2.4 KiB
Docker
## Stage 1: Build frontend bundle
|
|
FROM node:20.18-slim AS frontend
|
|
WORKDIR /build
|
|
COPY package.json package-lock.json* ./
|
|
RUN npm ci --ignore-scripts
|
|
COPY esbuild.mjs tsconfig.json ./
|
|
COPY src/wled_controller/static/ ./src/wled_controller/static/
|
|
RUN npm run build
|
|
|
|
## Stage 2: Python application
|
|
FROM python:3.11.11-slim AS runtime
|
|
|
|
LABEL maintainer="Alexei Dolgolyov <dolgolyov.alexei@gmail.com>"
|
|
LABEL org.opencontainers.image.title="LED Grab"
|
|
LABEL org.opencontainers.image.description="Ambient lighting system that captures screen content and drives LED strips in real time"
|
|
LABEL org.opencontainers.image.version="0.2.0"
|
|
LABEL org.opencontainers.image.url="https://git.dolgolyov-family.by/alexei.dolgolyov/wled-screen-controller-mixed"
|
|
LABEL org.opencontainers.image.source="https://git.dolgolyov-family.by/alexei.dolgolyov/wled-screen-controller-mixed"
|
|
LABEL org.opencontainers.image.licenses="MIT"
|
|
|
|
WORKDIR /app
|
|
|
|
# Install system dependencies for screen capture and health check
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
curl \
|
|
libxcb1 \
|
|
libxcb-randr0 \
|
|
libxcb-shm0 \
|
|
libxcb-xfixes0 \
|
|
libxcb-shape0 \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Install Python dependencies first (layer caching optimization).
|
|
# Copy pyproject.toml with a minimal package stub so pip can resolve deps.
|
|
# The real source is copied afterward, keeping the dep layer cached.
|
|
COPY pyproject.toml .
|
|
RUN mkdir -p src/wled_controller && touch src/wled_controller/__init__.py \
|
|
&& pip install --no-cache-dir ".[notifications]" \
|
|
&& rm -rf src/wled_controller
|
|
|
|
# Copy source code and config (invalidates cache only when source changes)
|
|
COPY src/ ./src/
|
|
COPY config/ ./config/
|
|
|
|
# Copy built frontend bundle from stage 1
|
|
COPY --from=frontend /build/src/wled_controller/static/dist/ ./src/wled_controller/static/dist/
|
|
|
|
# Create non-root user for security
|
|
RUN groupadd --gid 1000 ledgrab \
|
|
&& useradd --uid 1000 --gid ledgrab --shell /bin/bash --create-home ledgrab \
|
|
&& mkdir -p /app/data /app/logs \
|
|
&& chown -R ledgrab:ledgrab /app
|
|
|
|
USER ledgrab
|
|
|
|
# Expose API port
|
|
EXPOSE 8080
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
|
CMD curl -f http://localhost:8080/health || exit 1
|
|
|
|
# Set Python path
|
|
ENV PYTHONPATH=/app/src
|
|
|
|
# Run the application
|
|
CMD ["uvicorn", "wled_controller.main:app", "--host", "0.0.0.0", "--port", "8080"]
|