Browse Source

- Improved Docker environment

maziggy 4 months ago
parent
commit
29f1fa9732
4 changed files with 39 additions and 17 deletions
  1. 10 4
      Dockerfile
  2. 2 0
      README.md
  3. 5 5
      docker-compose.yml
  4. 22 8
      docker-publish.sh

+ 10 - 4
Dockerfile

@@ -3,8 +3,12 @@ FROM node:22-bookworm-slim AS frontend-builder
 
 
 WORKDIR /app/frontend
 WORKDIR /app/frontend
 
 
+# Copy package files first for better caching
 COPY frontend/package*.json ./
 COPY frontend/package*.json ./
-RUN npm ci
+
+# Use cache mount for npm
+RUN --mount=type=cache,target=/root/.npm \
+    npm ci
 
 
 COPY frontend/ ./
 COPY frontend/ ./
 RUN npm run build
 RUN npm run build
@@ -21,9 +25,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
     ffmpeg \
     ffmpeg \
     && rm -rf /var/lib/apt/lists/*
     && rm -rf /var/lib/apt/lists/*
 
 
-# Install Python dependencies
+# Install Python dependencies with cache mount
 COPY requirements.txt ./
 COPY requirements.txt ./
-RUN pip install --no-cache-dir --root-user-action=ignore -r requirements.txt
+RUN --mount=type=cache,target=/root/.cache/pip \
+    pip install --root-user-action=ignore -r requirements.txt
 
 
 # Copy backend
 # Copy backend
 COPY backend/ ./backend/
 COPY backend/ ./backend/
@@ -46,4 +51,5 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
     CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
     CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
 
 
 # Run the application
 # Run the application
-CMD ["uvicorn", "backend.app.main:app", "--host", "0.0.0.0", "--port", "8000"]
+# Use standard asyncio loop (uvloop has permission issues in some Docker environments)
+CMD ["uvicorn", "backend.app.main:app", "--host", "0.0.0.0", "--port", "8000", "--loop", "asyncio"]

+ 2 - 0
README.md

@@ -255,6 +255,8 @@ Open **http://localhost:8000** in your browser.
 
 
 > **Multi-architecture support:** Pre-built images are available for `linux/amd64` and `linux/arm64` (Raspberry Pi 4/5).
 > **Multi-architecture support:** Pre-built images are available for `linux/amd64` and `linux/arm64` (Raspberry Pi 4/5).
 
 
+> **macOS/Windows users:** Docker Desktop doesn't support `network_mode: host`. Edit docker-compose.yml: comment out `network_mode: host` and uncomment the `ports:` section. Printer discovery won't work - add printers manually by IP.
+
 <details>
 <details>
 <summary><strong>Docker Configuration & Commands</strong></summary>
 <summary><strong>Docker Configuration & Commands</strong></summary>
 
 

+ 5 - 5
docker-compose.yml

@@ -6,13 +6,13 @@ services:
     #   docker compose up -d          → pulls pre-built image from ghcr.io
     #   docker compose up -d          → pulls pre-built image from ghcr.io
     #   docker compose up -d --build  → builds locally from source
     #   docker compose up -d --build  → builds locally from source
     container_name: bambuddy
     container_name: bambuddy
-    # Network mode options:
-    # - Default (bridge): Works for basic usage, but printer discovery and
-    #   camera streaming may not work since container can't reach LAN directly.
-    # - Host mode: Required for printer discovery scanning and camera streaming.
-    #   Uncomment "network_mode: host" and remove "ports:" section below.
     #
     #
+    # LINUX: Use host mode for printer discovery and camera streaming
     network_mode: host
     network_mode: host
+    #
+    # macOS/WINDOWS: Docker Desktop doesn't support host mode.
+    # Comment out "network_mode: host" above and uncomment "ports:" below.
+    # Note: Printer discovery won't work - add printers manually by IP.
     #ports:
     #ports:
     #  - "8000:8000"
     #  - "8000:8000"
     volumes:
     volumes:

+ 22 - 8
docker-publish.sh

@@ -91,13 +91,18 @@ fi
 # Setup buildx builder if not exists
 # Setup buildx builder if not exists
 echo -e "${BLUE}[1/4] Setting up Docker Buildx...${NC}"
 echo -e "${BLUE}[1/4] Setting up Docker Buildx...${NC}"
 if ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then
 if ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then
-    echo "Creating new buildx builder: $BUILDER_NAME"
+    echo "Creating new buildx builder: $BUILDER_NAME (optimized for ${CPU_COUNT} cores)"
     docker buildx create \
     docker buildx create \
         --name "$BUILDER_NAME" \
         --name "$BUILDER_NAME" \
         --driver docker-container \
         --driver docker-container \
         --driver-opt network=host \
         --driver-opt network=host \
-        --buildkitd-flags '--allow-insecure-entitlement network.host' \
-        --bootstrap
+        --driver-opt "env.BUILDKIT_STEP_LOG_MAX_SIZE=10000000" \
+        --buildkitd-flags "--allow-insecure-entitlement network.host --oci-worker-gc=false" \
+        --config /dev/stdin <<EOF
+[worker.oci]
+  max-parallelism = ${CPU_COUNT}
+EOF
+    docker buildx inspect --bootstrap "$BUILDER_NAME"
 fi
 fi
 docker buildx use "$BUILDER_NAME"
 docker buildx use "$BUILDER_NAME"
 
 
@@ -117,9 +122,13 @@ else
     echo -e "${BLUE}[3/4] Building and pushing (version only, no latest)...${NC}"
     echo -e "${BLUE}[3/4] Building and pushing (version only, no latest)...${NC}"
 fi
 fi
 
 
+# Common build args for speed
+BUILD_ARGS="--provenance=false --sbom=false"
+CACHE_ARGS="--cache-from type=registry,ref=${FULL_IMAGE}:buildcache --cache-to type=registry,ref=${FULL_IMAGE}:buildcache,mode=max"
+
 if [ "$PARALLEL" = true ]; then
 if [ "$PARALLEL" = true ]; then
     # Parallel build: Build each architecture separately then combine
     # Parallel build: Build each architecture separately then combine
-    echo -e "${YELLOW}Building amd64 and arm64 in parallel...${NC}"
+    echo -e "${YELLOW}Building amd64 and arm64 in parallel (${CPU_COUNT} cores each)...${NC}"
 
 
     # Build amd64 in background
     # Build amd64 in background
     (
     (
@@ -127,7 +136,9 @@ if [ "$PARALLEL" = true ]; then
         docker buildx build \
         docker buildx build \
             --platform linux/amd64 \
             --platform linux/amd64 \
             -t "${FULL_IMAGE}:${VERSION}-amd64" \
             -t "${FULL_IMAGE}:${VERSION}-amd64" \
-            --provenance=false \
+            ${BUILD_ARGS} \
+            --cache-from type=registry,ref=${FULL_IMAGE}:cache-amd64 \
+            --cache-to type=registry,ref=${FULL_IMAGE}:cache-amd64,mode=max \
             --push \
             --push \
             . 2>&1 | sed 's/^/[amd64] /'
             . 2>&1 | sed 's/^/[amd64] /'
         echo -e "${GREEN}[amd64] Complete!${NC}"
         echo -e "${GREEN}[amd64] Complete!${NC}"
@@ -140,7 +151,9 @@ if [ "$PARALLEL" = true ]; then
         docker buildx build \
         docker buildx build \
             --platform linux/arm64 \
             --platform linux/arm64 \
             -t "${FULL_IMAGE}:${VERSION}-arm64" \
             -t "${FULL_IMAGE}:${VERSION}-arm64" \
-            --provenance=false \
+            ${BUILD_ARGS} \
+            --cache-from type=registry,ref=${FULL_IMAGE}:cache-arm64 \
+            --cache-to type=registry,ref=${FULL_IMAGE}:cache-arm64,mode=max \
             --push \
             --push \
             . 2>&1 | sed 's/^/[arm64] /'
             . 2>&1 | sed 's/^/[arm64] /'
         echo -e "${GREEN}[arm64] Complete!${NC}"
         echo -e "${GREEN}[arm64] Complete!${NC}"
@@ -167,10 +180,11 @@ if [ "$PARALLEL" = true ]; then
     fi
     fi
 else
 else
     # Sequential build (default): Build both platforms in one command
     # Sequential build (default): Build both platforms in one command
+    echo -e "${YELLOW}Building sequentially with ${CPU_COUNT} cores...${NC}"
     DOCKER_BUILDKIT=1 docker buildx build \
     DOCKER_BUILDKIT=1 docker buildx build \
         --platform "$PLATFORMS" \
         --platform "$PLATFORMS" \
-        --build-arg BUILDKIT_INLINE_CACHE=1 \
-        --provenance=false \
+        ${BUILD_ARGS} \
+        ${CACHE_ARGS} \
         $TAGS \
         $TAGS \
         --push \
         --push \
         .
         .