Skip to content

Commit cc0689e

Browse files
committed
feat(agents): enhance Dockerfile templates with comprehensive documentation
- Add multi-stage build optimization guidance with examples - Add system package documentation for common use cases - Add detailed PyAudio installation guide with sounddevice alternative - Add troubleshooting sections for some common build/runtime issues - Improve comments explaining each Dockerfile command and best practices - Fix pip Dockerfile order (USER after chown for proper permissions) - Add Node.js native module compilation guidanc
1 parent 1917120 commit cc0689e

File tree

3 files changed

+428
-20
lines changed

3 files changed

+428
-20
lines changed
Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,126 @@
1-
# This is an example Dockerfile that builds a minimal container for running LK Agents
1+
# This Dockerfile creates a production-ready container for a LiveKit Node.js agent
2+
# It uses a multi-stage build to minimize the final image size
23
# syntax=docker/dockerfile:1
4+
5+
# === MULTI-STAGE BUILD STRUCTURE ===
6+
# Stage 1 (base): Sets up Node.js environment with pnpm
7+
# Stage 2 (build): Installs dependencies and builds the application
8+
# Stage 3 (final): Copies only necessary files for runtime
9+
#
10+
# Benefits: Smaller final image without build tools and source files
11+
# Final image contains only: compiled JS, node_modules, and runtime dependencies
12+
313
FROM node:20-slim AS base
414

15+
# Set the working directory where our application will live
516
WORKDIR /app
617

18+
# Install pnpm globally for faster, more efficient package management
19+
# pnpm uses a content-addressable storage for packages, saving disk space
720
RUN npm install -g [email protected]
821

9-
# Throw away build stage to reduce size of final image
22+
# === BUILD STAGE ===
23+
# This stage is discarded after building, keeping the final image small
1024
FROM base AS build
1125

26+
# Install CA certificates for HTTPS connections during package installation
27+
# --no-install-recommends keeps the image smaller by avoiding suggested packages
1228
RUN apt-get update -qq && apt-get install --no-install-recommends -y ca-certificates
29+
30+
# Copy all application files into the build container
31+
# --link creates a separate layer that can be reused if files haven't changed
1332
COPY --link . .
1433

34+
# Install dependencies using pnpm
35+
# --frozen-lockfile ensures exact versions from pnpm-lock.yaml are used
36+
# This provides reproducible builds across different environments
1537
RUN pnpm install --frozen-lockfile
38+
39+
# Build the TypeScript application
40+
# This compiles TypeScript to JavaScript and prepares for production
1641
RUN pnpm run build
1742

43+
# === FINAL PRODUCTION STAGE ===
44+
# Start from the base image without build tools
1845
FROM base
46+
47+
# Copy the built application from the build stage
48+
# This includes node_modules and compiled JavaScript files
1949
COPY --from=build /app /app
50+
51+
# Copy SSL certificates for HTTPS connections at runtime
2052
COPY --from=build /etc/ssl/certs /etc/ssl/certs
2153

22-
# Start the server by default, this can be overwritten at runtime
54+
# Expose the healthcheck port
55+
# This allows Docker and orchestration systems to check if the container is healthy
2356
EXPOSE 8081
2457

58+
# Run the application
59+
# The "start" command tells the agent to connect to LiveKit and begin waiting for jobs
60+
# Modify the path if your entry point is different (e.g., ./dist/index.js)
2561
CMD [ "node", "./dist/agent.js", "start" ]
2662

63+
# === COMMON CUSTOMIZATIONS ===
64+
#
65+
# 1. Using npm or yarn instead of pnpm:
66+
# Replace pnpm commands with npm or yarn equivalents:
67+
# - npm: RUN npm ci (instead of pnpm install --frozen-lockfile)
68+
# - yarn: RUN yarn install --frozen-lockfile
69+
#
70+
# 2. Installing system dependencies for native modules:
71+
# Some Node.js packages require system libraries. Add before COPY in build stage:
72+
#
73+
# # For packages with native C++ addons:
74+
# RUN apt-get update -qq && apt-get install --no-install-recommends -y \
75+
# ca-certificates \
76+
# python3 \
77+
# make \
78+
# g++ \
79+
# && rm -rf /var/lib/apt/lists/*
80+
#
81+
# 3. Different entry point locations:
82+
# - If using src/index.js: CMD ["node", "./src/index.js", "start"]
83+
# - If using dist/main.js: CMD ["node", "./dist/main.js", "start"]
84+
# - For development: CMD ["npm", "run", "dev"]
85+
#
86+
# 4. Environment variables:
87+
# Set Node.js environment for production:
88+
# ENV NODE_ENV=production
89+
#
90+
# 5. Running as non-root user (recommended for security):
91+
# Add before the final CMD:
92+
# RUN adduser --disabled-password --gecos "" --uid 10001 appuser
93+
# USER appuser
94+
#
95+
# === TROUBLESHOOTING COMMON ISSUES ===
96+
#
97+
# 1. "Module not found" errors:
98+
# - Ensure all dependencies are in package.json
99+
# - Check that build output is in the expected location
100+
# - Verify node_modules are copied correctly
101+
#
102+
# 2. "EACCES: permission denied" errors:
103+
# - Add a non-root user (see example above)
104+
# - Ensure files have correct permissions
105+
#
106+
# 3. Large image sizes:
107+
# - Use node:20-alpine instead of node:20-slim for smaller base
108+
# - Ensure .dockerignore excludes unnecessary files
109+
# - Consider using npm prune --production after build
110+
#
111+
# 4. Slow builds:
112+
# - Use Docker BuildKit: DOCKER_BUILDKIT=1 docker build
113+
# - Order COPY commands from least to most frequently changed
114+
# - Copy package.json and lock file before source code for better caching
115+
#
116+
# 5. Native module compilation issues:
117+
# - Install build tools in the build stage (see customization #2)
118+
# - For node-gyp: apt-get install python3 make g++
119+
# - Consider using prebuilt binaries when available
120+
#
121+
# 6. Runtime connection issues:
122+
# - Verify the agent can reach the LiveKit server
123+
# - Check that required environment variables are set
124+
# - Ensure the healthcheck endpoint (8081) is accessible
125+
#
126+
# For more help: https://docs.livekit.io/agents/

pkg/agentfs/examples/python.pip.Dockerfile

Lines changed: 179 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
1-
# This is an example Dockerfile that builds a minimal container for running LK Agents
1+
# This Dockerfile creates a production-ready container for a LiveKit agent using pip
22
# syntax=docker/dockerfile:1
3+
#
4+
# === MULTI-STAGE BUILD OPTIMIZATION ===
5+
# For smaller production images, consider using a multi-stage build:
6+
# Stage 1: Build dependencies and compile packages
7+
# Stage 2: Copy only the compiled packages to a clean runtime image
8+
#
9+
# Example multi-stage build structure:
10+
# FROM python:3.11-slim AS builder
11+
# [install build tools, compile packages]
12+
# FROM python:3.11-slim AS runtime
13+
# COPY --from=builder /home/appuser/.local /home/appuser/.local
14+
# [runtime setup only]
15+
#
16+
# Benefits: 30-50% smaller final image size
17+
# Trade-offs: Longer build time, more complex debugging
18+
# Use when: Image size is critical (e.g., serverless, edge deployment)
19+
320
ARG PYTHON_VERSION=3.11.6
421
FROM python:${PYTHON_VERSION}-slim
522

@@ -21,32 +38,182 @@ RUN adduser \
2138
--uid "${UID}" \
2239
appuser
2340

24-
25-
# Install gcc and other build dependencies.
41+
# Install build dependencies required for Python packages with native extensions
42+
#
43+
# Common system packages you might need (uncomment and modify as needed):
44+
#
45+
# === Core Build Tools ===
46+
# - gcc/g++: C/C++ compilers for building packages with native extensions
47+
# - python3-dev: Python development headers needed for compilation
48+
# - build-essential: Essential build tools (includes gcc, make, etc.)
49+
# - pkg-config: Tool for managing library compilation/linking flags
50+
#
51+
# === Audio Processing ===
52+
# For audio agents (pyaudio, soundfile, librosa):
53+
# - libasound2-dev: ALSA development headers
54+
# - libportaudio2: Cross-platform audio I/O library
55+
# - libsndfile1-dev: Library for reading/writing audio files
56+
# - ffmpeg: Audio/video processing (for format conversion)
57+
#
58+
# === Computer Vision ===
59+
# For image/video processing (opencv, pillow):
60+
# - libopencv-dev: OpenCV development headers
61+
# - libjpeg-dev: JPEG image format support
62+
# - libpng-dev: PNG image format support
63+
# - libwebp-dev: WebP image format support
64+
# - libtiff5-dev: TIFF image format support
65+
#
66+
# === Machine Learning ===
67+
# For ML/AI packages (scipy, numpy, scikit-learn):
68+
# - libblas-dev: Basic Linear Algebra Subprograms
69+
# - liblapack-dev: Linear Algebra Package
70+
# - libatlas-base-dev: Automatically Tuned Linear Algebra Software
71+
# - gfortran: Fortran compiler (needed for some numerical libraries)
72+
#
73+
# === Database & Networking ===
74+
# - libpq-dev: PostgreSQL development headers
75+
# - libmysqlclient-dev: MySQL development headers
76+
# - libssl-dev: SSL/TLS support for cryptographic packages
77+
# - libffi-dev: Foreign Function Interface library for cffi
78+
# - libcurl4-openssl-dev: HTTP client library
79+
#
80+
# === Examples for Common Use Cases ===
81+
#
82+
# Audio Processing Agent:
83+
# RUN apt-get update && \
84+
# apt-get install -y \
85+
# gcc python3-dev \
86+
# libasound2-dev libportaudio2 libsndfile1-dev \
87+
# ffmpeg \
88+
# && rm -rf /var/lib/apt/lists/*
89+
#
90+
# Computer Vision Agent:
91+
# RUN apt-get update && \
92+
# apt-get install -y \
93+
# gcc python3-dev \
94+
# libopencv-dev libjpeg-dev libpng-dev libwebp-dev \
95+
# && rm -rf /var/lib/apt/lists/*
96+
#
97+
# Machine Learning Agent:
98+
# RUN apt-get update && \
99+
# apt-get install -y \
100+
# gcc g++ gfortran python3-dev \
101+
# libblas-dev liblapack-dev libatlas-base-dev \
102+
# && rm -rf /var/lib/apt/lists/*
103+
#
104+
# === SPECIAL CASE: PyAudio Installation Guide ===
105+
# PyAudio is a common audio library that requires special attention.
106+
# If you need PyAudio, use this complete setup:
107+
#
108+
# RUN apt-get update && \
109+
# apt-get install -y \
110+
# gcc python3-dev \
111+
# libasound2-dev libportaudio2 portaudio19-dev \
112+
# && rm -rf /var/lib/apt/lists/*
113+
#
114+
# Important notes for PyAudio:
115+
# 1. Install system packages BEFORE installing Python packages
116+
# 2. Use portaudio19-dev (not just libportaudio2) for full compatibility
117+
# 3. Some systems may also need: libportaudiocpp0 libportaudio0
118+
# 4. For production use, consider using sounddevice instead of pyaudio
119+
# (sounddevice is more modern and has better error handling)
120+
#
121+
# Alternative for audio: Use soundfile + sounddevice instead of pyaudio:
122+
# RUN apt-get update && \
123+
# apt-get install -y \
124+
# gcc python3-dev \
125+
# libasound2-dev libsndfile1-dev \
126+
# && rm -rf /var/lib/apt/lists/*
127+
#
128+
# Then in your requirements: soundfile sounddevice (instead of pyaudio)
129+
#
130+
# Minimal setup (works for most pure Python packages):
26131
RUN apt-get update && \
27132
apt-get install -y \
28133
gcc \
29134
python3-dev \
30135
&& rm -rf /var/lib/apt/lists/*
31136

32-
USER appuser
33-
34-
RUN mkdir -p /home/appuser/.cache
35-
RUN chown -R appuser /home/appuser/.cache
36-
137+
# Set the working directory to the user's home directory
138+
# This is where our application code will live
37139
WORKDIR /home/appuser
38140

141+
# Copy requirements first for better Docker layer caching
142+
# If requirements don't change, Docker can reuse the pip install layer
39143
COPY requirements.txt .
40-
RUN python -m pip install --user --no-cache-dir -r requirements.txt
41144

145+
# Install Python dependencies as root (needed for system-wide packages)
146+
# --no-cache-dir reduces image size by not caching pip downloads
147+
RUN python -m pip install --no-cache-dir -r requirements.txt
148+
149+
# Copy all application files into the container
150+
# This includes source code, configuration files, etc.
151+
# (Excludes files specified in .dockerignore)
42152
COPY . .
43153

44-
# ensure that any dependent models are downloaded at build-time
154+
# Change ownership of all app files to the non-privileged user
155+
# This ensures the application can read/write files as needed
156+
RUN chown -R appuser:appuser /home/appuser
157+
158+
# Switch to the non-privileged user for all subsequent operations
159+
# This improves security by not running as root
160+
USER appuser
161+
162+
# Create a cache directory for the user
163+
# This is used by pip and Python for caching packages and bytecode
164+
RUN mkdir -p /home/appuser/.cache
165+
166+
# Pre-download any ML models or files the agent needs
167+
# This ensures the container is ready to run immediately without downloading
168+
# dependencies at runtime, which improves startup time and reliability
45169
RUN python "$PROGRAM_MAIN" download-files
46170

47-
# expose healthcheck port
171+
# Expose the healthcheck port
172+
# This allows Docker and orchestration systems to check if the container is healthy
48173
EXPOSE 8081
49174

50-
# Run the application.
175+
# Run the application
176+
# The "start" command tells the worker to connect to LiveKit and begin waiting for jobs
51177
CMD ["python", "$PROGRAM_MAIN", "start"]
52178

179+
# === TROUBLESHOOTING COMMON BUILD ISSUES ===
180+
#
181+
# 1. "Package not found" or compilation errors:
182+
# - Check that required system packages are installed (see examples above)
183+
# - Ensure packages are installed BEFORE Python package installation
184+
# - For C extensions: you need gcc and python3-dev
185+
#
186+
# 2. "Permission denied" errors:
187+
# - Verify USER appuser comes after chown commands
188+
# - Check that working directory is /home/appuser
189+
# - Make sure all files are owned by appuser:appuser
190+
#
191+
# 3. "requirements.txt not found" or install errors:
192+
# - Ensure requirements.txt is in your project root
193+
# - Check that requirements.txt is not in .dockerignore
194+
# - Pin package versions for reproducible builds (e.g., flask==2.3.0)
195+
#
196+
# 4. Large image sizes:
197+
# - Consider multi-stage builds for production
198+
# - Remove unnecessary packages after installation
199+
# - Use .dockerignore to exclude large files
200+
# - Consider switching to Alpine Linux for smaller base image
201+
#
202+
# 5. Slow builds:
203+
# - Consider switching to UV for faster dependency resolution
204+
# - Use Docker BuildKit for better caching: DOCKER_BUILDKIT=1 docker build
205+
# - Order Dockerfile commands from least to most frequently changed
206+
# - Copy requirements.txt before other files for better layer caching
207+
#
208+
# 6. Runtime issues:
209+
# - Check healthcheck endpoint (port 8081)
210+
# - Verify environment variables are set
211+
# - Ensure agent can connect to LiveKit server
212+
# - Check that required models/files are downloaded
213+
#
214+
# 7. Audio/video issues:
215+
# - Install required system libraries (see PyAudio guide above)
216+
# - Test with minimal audio setup first
217+
# - Consider using sounddevice instead of pyaudio
218+
#
219+
# For more help: https://docs.livekit.io/agents/

0 commit comments

Comments
 (0)