mirror of
https://github.com/morpheus65535/bazarr.git
synced 2026-01-09 02:25:27 +08:00
perf: optimize Docker build with better layer caching
Dockerfile optimizations: - Use BuildKit cache mounts for pip and apt - Reorder COPY instructions: least-changing first, most-changing last - Remove duplicate frontend build stage (use pre-built from workflow) - Separate requirements.txt copy for maximum pip cache hits Workflow optimizations: - Use actions/setup-node built-in npm caching - Add trigger for master branch (not just main) - Use multiple GHA cache scopes for better granularity - Improved release summary output Build order optimized for caching: 1. Python deps (cached by requirements.txt hash) 2. System packages (cached by apt cache mount) 3. Entrypoint + libs (change infrequently) 4. App code (changes most frequently) 5. Frontend build (pre-built artifact from workflow)
This commit is contained in:
parent
91fa5eb6b8
commit
b5f2895157
2 changed files with 64 additions and 56 deletions
60
.github/workflows/build-docker.yml
vendored
60
.github/workflows/build-docker.yml
vendored
|
|
@ -4,6 +4,7 @@ on:
|
|||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
paths-ignore:
|
||||
- '*.md'
|
||||
- 'docs/**'
|
||||
|
|
@ -30,6 +31,9 @@ env:
|
|||
UI_DIRECTORY: ./frontend
|
||||
|
||||
jobs:
|
||||
# ==========================================================================
|
||||
# Build Scraper Image (separate job with its own cache)
|
||||
# ==========================================================================
|
||||
build-scraper:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
|
|
@ -80,23 +84,21 @@ jobs:
|
|||
cache-from: type=gha,scope=scraper
|
||||
cache-to: type=gha,mode=max,scope=scraper
|
||||
|
||||
# ==========================================================================
|
||||
# Build Frontend (cached via GitHub Actions cache)
|
||||
# ==========================================================================
|
||||
build-frontend:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: "${{ env.UI_DIRECTORY }}/node_modules"
|
||||
key: ${{ runner.os }}-modules-${{ hashFiles('**/package-lock.json') }}
|
||||
restore-keys: ${{ runner.os }}-modules-
|
||||
|
||||
- name: Setup NodeJS
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version-file: "${{ env.UI_DIRECTORY }}/.nvmrc"
|
||||
cache: 'npm'
|
||||
cache-dependency-path: "${{ env.UI_DIRECTORY }}/package-lock.json"
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
|
|
@ -113,6 +115,9 @@ jobs:
|
|||
path: ${{ env.UI_DIRECTORY }}/build
|
||||
retention-days: 1
|
||||
|
||||
# ==========================================================================
|
||||
# Build and Push Bazarr Image
|
||||
# ==========================================================================
|
||||
build-and-push:
|
||||
needs: [build-frontend, build-scraper]
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -183,7 +188,7 @@ jobs:
|
|||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
tags: |
|
||||
# Latest tag on main branch
|
||||
# Latest tag on main/master branch
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
# Version tag (e.g., v1.5.3-lavx.20241214)
|
||||
type=raw,value=${{ steps.version.outputs.fork_version }}
|
||||
|
|
@ -207,8 +212,11 @@ jobs:
|
|||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
# Use GHA cache with separate scopes for different layers
|
||||
cache-from: |
|
||||
type=gha,scope=bazarr-deps
|
||||
type=gha,scope=bazarr-main
|
||||
cache-to: type=gha,mode=max,scope=bazarr-main
|
||||
build-args: |
|
||||
BAZARR_VERSION=${{ steps.version.outputs.fork_version }}
|
||||
BUILD_DATE=${{ github.event.repository.updated_at }}
|
||||
|
|
@ -223,28 +231,27 @@ jobs:
|
|||
|
||||
- name: Create Release Summary
|
||||
run: |
|
||||
echo "## 🐳 Docker Image Published" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Pull Commands" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## 🐳 Docker Images Published" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Bazarr (LavX Fork)" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
|
||||
echo "# Latest" >> $GITHUB_STEP_SUMMARY
|
||||
echo "docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "# Specific Version" >> $GITHUB_STEP_SUMMARY
|
||||
echo "docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.fork_version }}" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### OpenSubtitles Scraper" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
|
||||
echo "docker pull ${{ env.REGISTRY }}/${{ env.SCRAPER_IMAGE_NAME }}:latest" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### Image Details" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Digest:** \`${{ steps.push.outputs.digest }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Platforms:** linux/amd64, linux/arm64" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "### 🔌 OpenSubtitles Scraper" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY
|
||||
echo "docker pull ${{ env.REGISTRY }}/${{ env.SCRAPER_IMAGE_NAME }}:latest" >> $GITHUB_STEP_SUMMARY
|
||||
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- **Cache Status:** GHA cache enabled" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
# Optional: Create GitHub Release for tagged versions
|
||||
# ==========================================================================
|
||||
# Create GitHub Release for tagged versions
|
||||
# ==========================================================================
|
||||
create-release:
|
||||
needs: build-and-push
|
||||
runs-on: ubuntu-latest
|
||||
|
|
@ -260,15 +267,20 @@ jobs:
|
|||
with:
|
||||
generate_release_notes: true
|
||||
body: |
|
||||
## 🐳 Docker Image
|
||||
## 🐳 Docker Images
|
||||
|
||||
```bash
|
||||
# Bazarr (LavX Fork)
|
||||
docker pull ghcr.io/${{ github.repository }}:${{ github.ref_name }}
|
||||
|
||||
# OpenSubtitles Scraper
|
||||
docker pull ghcr.io/${{ github.repository_owner }}/opensubtitles-scraper:latest
|
||||
```
|
||||
|
||||
## 📝 Changes
|
||||
|
||||
This release is based on upstream Bazarr with the following custom modifications:
|
||||
- OpenSubtitles.org web scraper provider
|
||||
- OpenSubtitles.org web scraper provider (no VIP API needed)
|
||||
- Auto-sync with upstream daily at 4 AM UTC
|
||||
|
||||
See the auto-generated release notes below for detailed changes.
|
||||
60
Dockerfile
60
Dockerfile
|
|
@ -1,7 +1,7 @@
|
|||
# =============================================================================
|
||||
# Bazarr LavX Fork - Production Docker Image
|
||||
# =============================================================================
|
||||
# Multi-stage build for optimized image size
|
||||
# Multi-stage build optimized for layer caching
|
||||
# Based on Debian Slim for better compatibility (unrar, etc.)
|
||||
# =============================================================================
|
||||
|
||||
|
|
@ -10,22 +10,7 @@ ARG BUILD_DATE
|
|||
ARG VCS_REF
|
||||
|
||||
# =============================================================================
|
||||
# Stage 1: Build Frontend
|
||||
# =============================================================================
|
||||
FROM node:20-slim AS frontend-builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install dependencies first for better caching
|
||||
COPY frontend/package*.json ./frontend/
|
||||
RUN cd frontend && npm ci
|
||||
|
||||
# Copy frontend source and build
|
||||
COPY frontend ./frontend/
|
||||
RUN cd frontend && npm run build
|
||||
|
||||
# =============================================================================
|
||||
# Stage 2: Install Python Dependencies
|
||||
# Stage 1: Install Python Dependencies (cached heavily)
|
||||
# =============================================================================
|
||||
FROM python:3.12-slim-bookworm AS python-builder
|
||||
|
||||
|
|
@ -40,12 +25,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy requirements and install Python packages
|
||||
# Copy ONLY requirements first for maximum caching
|
||||
# This layer will only rebuild when requirements.txt changes
|
||||
COPY requirements.txt ./
|
||||
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
|
||||
|
||||
# Use pip cache mount to avoid re-downloading packages across builds
|
||||
RUN --mount=type=cache,target=/root/.cache/pip \
|
||||
pip install --prefix=/install -r requirements.txt
|
||||
|
||||
# =============================================================================
|
||||
# Stage 3: Production Image
|
||||
# Stage 2: Production Image
|
||||
# =============================================================================
|
||||
FROM python:3.12-slim-bookworm AS production
|
||||
|
||||
|
|
@ -64,7 +53,10 @@ LABEL org.opencontainers.image.title="Bazarr (LavX Fork)" \
|
|||
org.opencontainers.image.licenses="GPL-3.0"
|
||||
|
||||
# Enable non-free repository for unrar and install runtime dependencies
|
||||
RUN sed -i 's/Components: main/Components: main non-free non-free-firmware/' /etc/apt/sources.list.d/debian.sources && \
|
||||
# Use apt cache mount to speed up repeated builds
|
||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||
sed -i 's/Components: main/Components: main non-free non-free-firmware/' /etc/apt/sources.list.d/debian.sources && \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
ffmpeg \
|
||||
libxml2 \
|
||||
|
|
@ -76,31 +68,35 @@ RUN sed -i 's/Components: main/Components: main non-free non-free-firmware/' /et
|
|||
bash \
|
||||
gosu \
|
||||
curl \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& mkdir -p /app/bazarr/bin /config /defaults \
|
||||
&& groupadd -g 1000 bazarr \
|
||||
&& useradd -u 1000 -g bazarr -d /config -s /bin/bash bazarr
|
||||
|
||||
# Copy Python packages from builder
|
||||
# Copy Python packages from builder (changes rarely)
|
||||
COPY --from=python-builder /install /usr/local
|
||||
|
||||
# Copy application code
|
||||
# Copy entrypoint script (changes rarely)
|
||||
COPY docker/entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
# Set work directory
|
||||
WORKDIR /app/bazarr
|
||||
COPY bazarr.py ./
|
||||
|
||||
# Copy libs directories (change less frequently than main app code)
|
||||
COPY libs ./libs
|
||||
COPY custom_libs ./custom_libs
|
||||
COPY bazarr ./bazarr
|
||||
COPY migrations ./migrations
|
||||
|
||||
# Copy main application code (changes most frequently - keep at end)
|
||||
COPY bazarr.py ./
|
||||
COPY bazarr ./bazarr
|
||||
|
||||
# Copy fork identification file (shows "LavX Fork" in System Status)
|
||||
COPY package_info /app/bazarr/package_info
|
||||
|
||||
# Copy frontend build
|
||||
COPY --from=frontend-builder /app/frontend/build ./frontend/build
|
||||
|
||||
# Copy entrypoint script
|
||||
COPY docker/entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
# Copy pre-built frontend (built in GitHub Actions workflow for caching)
|
||||
# This layer only rebuilds when frontend/build changes
|
||||
COPY frontend/build ./frontend/build
|
||||
|
||||
# Set environment variables
|
||||
ENV HOME="/config" \
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue