Skip to content

Commit 8011f4d

Browse files
authored
Make some more updates to the dockerfiles (#646)
* Make some more updates to the dockerfiles * node * Update node.Dockerfile * Update python.pip.Dockerfile * Update python.uv.Dockerfile * Add g++
1 parent f44e205 commit 8011f4d

File tree

5 files changed

+202
-88
lines changed

5 files changed

+202
-88
lines changed
Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,77 @@
11
# This is an example Dockerfile that builds a minimal container for running LK Agents
2+
# For more information on the build process, see https://docs.livekit.io/agents/ops/deployment/builds/
23
# syntax=docker/dockerfile:1
3-
FROM node:20-slim AS base
44

5-
WORKDIR /app
5+
# Use the official Node.js v22 base image with Node.js 22.10.0
6+
# We use the slim variant to keep the image size smaller while still having essential tools
7+
ARG NODE_VERSION=22
8+
FROM node:${NODE_VERSION}-slim AS base
9+
10+
# Configure pnpm installation directory and ensure it is on PATH
11+
ENV PNPM_HOME="/pnpm"
12+
ENV PATH="$PNPM_HOME:$PATH"
613

7-
RUN npm install -g [email protected]
14+
# Install required system packages and pnpm, then clean up the apt cache for a smaller image
15+
# ca-certificates: enables TLS/SSL for securely fetching dependencies and calling HTTPS services
16+
# --no-install-recommends keeps the image minimal
17+
RUN apt-get update -qq && apt-get install --no-install-recommends -y ca-certificates && rm -rf /var/lib/apt/lists/*
818

9-
# Throw away build stage to reduce size of final image
19+
# Pin pnpm version for reproducible builds
20+
RUN npm install -g [email protected]
21+
22+
# Create a new directory for our application code
23+
# And set it as the working directory
24+
WORKDIR /app
25+
26+
# Build stage
27+
# We use a multi-stage build to keep the runtime image minimal
1028
FROM base AS build
1129

12-
RUN apt-get update -qq && apt-get install --no-install-recommends -y ca-certificates
13-
COPY --link . .
30+
# Copy just the dependency files first, for more efficient layer caching
31+
COPY package.json pnpm-lock.yaml ./
1432

33+
# Install dependencies using pnpm
34+
# --frozen-lockfile ensures we use exact versions from pnpm-lock.yaml for reproducible builds
1535
RUN pnpm install --frozen-lockfile
36+
37+
# Copy all remaining pplication files into the container
38+
# This includes source code, configuration files, and dependency specifications
39+
# (Excludes files specified in .dockerignore)
40+
COPY . .
41+
42+
# Build the project
1643
RUN pnpm run build
1744

18-
FROM base
45+
# Remove development-only dependencies to reduce the runtime image size
46+
RUN pnpm prune --prod
47+
48+
# Create the runtime image
49+
FROM base AS runtime
50+
51+
# Create a non-privileged user that the app will run under
52+
# See https://docs.docker.com/develop/develop-images/dockerfile_best_practices/#user
53+
ARG UID=10001
54+
RUN adduser \
55+
--disabled-password \
56+
--gecos "" \
57+
--home "/app" \
58+
--shell "/sbin/nologin" \
59+
--uid "${UID}" \
60+
appuser
61+
62+
# Copy built application and production dependencies from the build stage
1963
COPY --from=build /app /app
64+
65+
# Copy system CA certificates to ensure HTTPS works correctly at runtime
2066
COPY --from=build /etc/ssl/certs /etc/ssl/certs
2167

22-
# Start the server by default, this can be overwritten at runtime
23-
EXPOSE 8081
68+
# Ensure ownership of app files and drop privileges for better security
69+
RUN chown -R appuser:appuser /app
70+
USER appuser
2471

25-
CMD [ "node", "./dist/agent.js", "start" ]
72+
# Set Node.js to production mode
73+
ENV NODE_ENV=production
2674

75+
# Run the application
76+
# The "start" command tells the worker to connect to LiveKit and begin waiting for jobs.
77+
CMD [ "node", "./dist/agent.js", "start" ]
Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,70 @@
11
# This is an example Dockerfile that builds a minimal container for running LK Agents
2+
# For more information on the build process, see https://docs.livekit.io/agents/ops/deployment/builds/
23
# syntax=docker/dockerfile:1
3-
ARG PYTHON_VERSION=3.11.6
4-
FROM python:${PYTHON_VERSION}-slim
4+
5+
# Use the official Python base image with Python 3.11
6+
# We use the slim variant to keep the image size smaller while still having essential tools
7+
ARG PYTHON_VERSION=3.11
8+
FROM python:${PYTHON_VERSION}-slim AS base
59

610
# Keeps Python from buffering stdout and stderr to avoid situations where
711
# the application crashes without emitting any logs due to buffering.
812
ENV PYTHONUNBUFFERED=1
913

10-
# Define the program entrypoint file where your agent is started.
11-
ARG PROGRAM_MAIN="{{.ProgramMain}}"
14+
# Disable pip version check to speed up builds
15+
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
1216

1317
# Create a non-privileged user that the app will run under.
1418
# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
1519
ARG UID=10001
1620
RUN adduser \
1721
--disabled-password \
1822
--gecos "" \
19-
--home "/home/appuser" \
23+
--home "/app" \
2024
--shell "/sbin/nologin" \
2125
--uid "${UID}" \
2226
appuser
2327

24-
25-
# Install gcc and other build dependencies.
26-
RUN apt-get update && \
27-
apt-get install -y \
28+
# Install build dependencies required for Python packages with native extensions
29+
# gcc: C compiler needed for building Python packages with C extensions
30+
# g++: C++ compiler needed for building Python packages with C++ extensions
31+
# python3-dev: Python development headers needed for compilation
32+
# We clean up the apt cache after installation to keep the image size down
33+
RUN apt-get update && apt-get install -y \
2834
gcc \
35+
g++ \
2936
python3-dev \
30-
&& rm -rf /var/lib/apt/lists/*
31-
32-
USER appuser
37+
&& rm -rf /var/lib/apt/lists/*
3338

34-
RUN mkdir -p /home/appuser/.cache
35-
RUN chown -R appuser /home/appuser/.cache
39+
# Create a new directory for our application code
40+
# And set it as the working directory
41+
WORKDIR /app
3642

37-
WORKDIR /home/appuser
43+
# Copy just the dependency files first, for more efficient layer caching
44+
COPY requirements.txt ./
3845

39-
COPY requirements.txt .
40-
RUN python -m pip install --user --no-cache-dir -r requirements.txt
46+
# Install Python dependencies using pip
47+
# --no-cache-dir ensures we don't use the system cache
48+
RUN pip install --no-cache-dir -r requirements.txt
4149

50+
# Copy all remaining pplication files into the container
51+
# This includes source code, configuration files, and dependency specifications
52+
# (Excludes files specified in .dockerignore)
4253
COPY . .
4354

44-
# ensure that any dependent models are downloaded at build-time
45-
RUN python "$PROGRAM_MAIN" download-files
55+
# Change ownership of all app files to the non-privileged user
56+
# This ensures the application can read/write files as needed
57+
RUN chown -R appuser:appuser /app
58+
59+
# Switch to the non-privileged user for all subsequent operations
60+
# This improves security by not running as root
61+
USER appuser
4662

47-
# expose healthcheck port
48-
EXPOSE 8081
63+
# Pre-download any ML models or files the agent needs
64+
# This ensures the container is ready to run immediately without downloading
65+
# dependencies at runtime, which improves startup time and reliability
66+
RUN python "{{.ProgramMain}}" download-files
4967

50-
# Run the application.
68+
# Run the application
5169
# The "start" command tells the worker to connect to LiveKit and begin waiting for jobs.
5270
CMD ["python", "{{.ProgramMain}}", "start"]
Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,48 @@
1-
# Python artifacts
2-
venv/
1+
# Python bytecode and artifacts
32
__pycache__/
3+
*.py[cod]
4+
*.pyo
5+
*.pyd
6+
*.egg-info/
7+
dist/
8+
build/
49

5-
# Local environment & config files
6-
.env
7-
.env.local
8-
.DS_Store
10+
# Virtual environments
11+
.venv/
12+
venv/
913

10-
# Logs & temp files
14+
# Caches and test output
15+
.cache/
16+
.pytest_cache/
17+
.ruff_cache/
18+
coverage/
19+
20+
# Logs and temp files
1121
*.log
1222
*.gz
1323
*.tgz
1424
.tmp
1525
.cache
1626

17-
# Docker artifacts
18-
Dockerfile*
19-
.dockerignore
27+
# Environment variables
28+
.env
29+
.env.*
2030

21-
# Git & Editor files
31+
# VCS, editor, OS
2232
.git
2333
.gitignore
24-
.idea
25-
.vscode
34+
.gitattributes
35+
.github/
36+
.idea/
37+
.vscode/
38+
.DS_Store
39+
40+
# Project docs and misc
41+
README.md
42+
LICENSE
2643

44+
# Project tests
45+
test/
46+
tests/
47+
eval/
48+
evals/
Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,72 @@
1-
# This sample Dockerfile creates a production-ready container for a LiveKit voice AI agent
1+
# This is an example Dockerfile that builds a minimal container for running LK Agents
2+
# For more information on the build process, see https://docs.livekit.io/agents/ops/deployment/builds/
23
# syntax=docker/dockerfile:1
34

45
# Use the official UV Python base image with Python 3.11 on Debian Bookworm
56
# UV is a fast Python package manager that provides better performance than pip
67
# We use the slim variant to keep the image size smaller while still having essential tools
7-
FROM ghcr.io/astral-sh/uv:python3.11-bookworm-slim
8+
ARG PYTHON_VERSION=3.11
9+
FROM ghcr.io/astral-sh/uv:python${PYTHON_VERSION}-bookworm-slim AS base
810

911
# Keeps Python from buffering stdout and stderr to avoid situations where
1012
# the application crashes without emitting any logs due to buffering.
1113
ENV PYTHONUNBUFFERED=1
1214

13-
# Define the program entrypoint file where your agent is started.
14-
ARG PROGRAM_MAIN="{{.ProgramMain}}"
15-
1615
# Create a non-privileged user that the app will run under.
1716
# See https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
1817
ARG UID=10001
1918
RUN adduser \
2019
--disabled-password \
2120
--gecos "" \
22-
--home "/home/appuser" \
21+
--home "/app" \
2322
--shell "/sbin/nologin" \
2423
--uid "${UID}" \
2524
appuser
2625

2726
# Install build dependencies required for Python packages with native extensions
2827
# gcc: C compiler needed for building Python packages with C extensions
28+
# g++: C++ compiler needed for building Python packages with C++ extensions
2929
# python3-dev: Python development headers needed for compilation
3030
# We clean up the apt cache after installation to keep the image size down
31-
RUN apt-get update && \
32-
apt-get install -y \
31+
RUN apt-get update && apt-get install -y \
3332
gcc \
33+
g++ \
3434
python3-dev \
35-
&& rm -rf /var/lib/apt/lists/*
35+
&& rm -rf /var/lib/apt/lists/*
36+
37+
# Create a new directory for our application code
38+
# And set it as the working directory
39+
WORKDIR /app
3640

37-
# Set the working directory to the user's home directory
38-
# This is where our application code will live
39-
WORKDIR /home/appuser
41+
# Copy just the dependency files first, for more efficient layer caching
42+
COPY pyproject.toml uv.lock ./
43+
RUN mkdir -p src
4044

41-
# Copy all application files into the container
45+
# Install Python dependencies using UV's lock file
46+
# --locked ensures we use exact versions from uv.lock for reproducible builds
47+
# This creates a virtual environment and installs all dependencies
48+
# Ensure your uv.lock file is checked in for consistency across environments
49+
RUN uv sync --locked
50+
51+
# Copy all remaining pplication files into the container
4252
# This includes source code, configuration files, and dependency specifications
4353
# (Excludes files specified in .dockerignore)
4454
COPY . .
4555

4656
# Change ownership of all app files to the non-privileged user
4757
# This ensures the application can read/write files as needed
48-
RUN chown -R appuser:appuser /home/appuser
58+
RUN chown -R appuser:appuser /app
4959

5060
# Switch to the non-privileged user for all subsequent operations
5161
# This improves security by not running as root
5262
USER appuser
5363

54-
# Create a cache directory for the user
55-
# This is used by UV and Python for caching packages and bytecode
56-
RUN mkdir -p /home/appuser/.cache
57-
58-
# Install Python dependencies using UV's lock file
59-
# --locked ensures we use exact versions from uv.lock for reproducible builds
60-
# This creates a virtual environment and installs all dependencies
61-
# Ensure your uv.lock file is checked in for consistency across environments
62-
RUN uv sync --locked
63-
6464
# Pre-download any ML models or files the agent needs
6565
# This ensures the container is ready to run immediately without downloading
6666
# dependencies at runtime, which improves startup time and reliability
67-
RUN uv run "$PROGRAM_MAIN" download-files
68-
69-
# Expose the healthcheck port
70-
# This allows Docker and orchestration systems to check if the container is healthy
71-
EXPOSE 8081
67+
RUN uv run "{{.ProgramMain}}" download-files
7268

7369
# Run the application using UV
7470
# UV will activate the virtual environment and run the agent.
7571
# The "start" command tells the worker to connect to LiveKit and begin waiting for jobs.
7672
CMD ["uv", "run", "{{.ProgramMain}}", "start"]
77-

0 commit comments

Comments
 (0)