Skip to content

Commit 095273f

Browse files
committed
Attempt to improve image build space use
1 parent 4cdbe73 commit 095273f

File tree

3 files changed

+80
-39
lines changed

3 files changed

+80
-39
lines changed

.github/workflows/publish-docker.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,18 @@ jobs:
6262
type=raw,value=latest,enable=${{ github.event.inputs.push_latest }}
6363
type=sha,prefix={{branch}}-
6464
65+
- name: Free Disk Space (Ubuntu)
66+
uses: jlumbroso/free-disk-space@main
67+
with:
68+
# Effectively free up ~30GB of space
69+
tool-cache: true
70+
android: true
71+
dotnet: true
72+
haskell: true
73+
large-packages: true
74+
docker-images: true
75+
swap-storage: true
76+
6577
- name: Build and push Docker image
6678
uses: docker/build-push-action@v5
6779
with:

Dockerfile

Lines changed: 67 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,94 @@
1-
FROM python:3.12-slim
1+
# STAGE 1: Builder
2+
# We use a separate stage to compile dependencies and build artifacts.
3+
# This allows us to discard build tools and caches in the final image.
4+
FROM python:3.12-slim AS builder
5+
6+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
27

3-
# Set working directory
48
WORKDIR /app
59

6-
# Install system dependencies including Docker CLI and Redis CLI
10+
# Set uv environment variables for optimization
11+
ENV UV_COMPILE_BYTECODE=1
12+
ENV UV_LINK_MODE=copy
13+
14+
# Install system dependencies required ONLY for building/fetching (like git)
15+
# We don't need Docker CLI here unless your build script relies on it.
716
RUN apt-get update && apt-get install -y \
817
git \
18+
curl \
19+
&& rm -rf /var/lib/apt/lists/*
20+
21+
# Install dependencies
22+
# 1. Copy only dependency files first to leverage Docker layer caching
23+
COPY pyproject.toml uv.lock ./
24+
25+
# 2. Install dependencies using cache mount.
26+
# --mount=type=cache prevents the uv cache (~GBs) from being saved to the image layer,
27+
# directly solving your "ResourceExhausted" error.
28+
RUN --mount=type=cache,target=/root/.cache/uv \
29+
uv sync --frozen --no-dev --no-install-project
30+
31+
# 3. Copy application code
32+
COPY . .
33+
34+
# 4. Install the project itself and generate artifacts
35+
RUN --mount=type=cache,target=/root/.cache/uv \
36+
uv sync --frozen --no-dev && \
37+
mkdir -p /app/artifacts && \
38+
# Attempt to build artifacts, but don't fail build if it requires runtime services
39+
(uv run --no-sync redis-sre-agent pipeline prepare-sources \
40+
--source-dir /app/source_documents \
41+
--prepare-only \
42+
--artifacts-path /app/artifacts || \
43+
echo "Warning: Could not prepare source documents at build time")
44+
45+
46+
# STAGE 2: Runtime
47+
# This is the final image. It will be much smaller.
48+
FROM python:3.12-slim
49+
50+
WORKDIR /app
51+
52+
# Install ONLY runtime system dependencies
53+
# We repeat the Docker/Redis install here because they are needed at runtime.
54+
RUN apt-get update && apt-get install -y \
955
curl \
1056
ca-certificates \
57+
redis-tools \
1158
gnupg \
1259
lsb-release \
13-
redis-tools \
1460
&& mkdir -p /etc/apt/keyrings \
1561
&& curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \
1662
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
1763
&& apt-get update \
1864
&& apt-get install -y docker-ce-cli \
19-
&& apt-get purge -y gnupg lsb-release git \
20-
&& apt-get autoremove -y \
65+
&& apt-get clean \
2166
&& rm -rf /var/lib/apt/lists/*
2267

23-
# Install uv
24-
COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin/uv
25-
26-
# Copy dependency files and project metadata required at build time
27-
28-
COPY pyproject.toml uv.lock ./
29-
COPY README.md ./
30-
31-
# Install dependencies
32-
RUN uv sync --frozen --no-dev
33-
34-
# Copy application code
35-
COPY . .
68+
# Copy the virtual environment from the builder stage
69+
COPY --from=builder /app/.venv /app/.venv
70+
COPY --from=builder /app/artifacts /app/artifacts
71+
COPY --from=builder /app /app
3672

73+
# Add the virtual environment to PATH
74+
# This allows us to run "uvicorn" or "python" directly without "uv run"
75+
ENV PATH="/app/.venv/bin:$PATH"
3776

38-
# Pre-build knowledge base artifacts for faster production startup
39-
# This prepares batch artifacts from source documents without requiring Redis at build time
40-
RUN mkdir -p /app/artifacts && \
41-
uv run redis-sre-agent pipeline prepare-sources \
42-
--source-dir /app/source_documents \
43-
--prepare-only \
44-
--artifacts-path /app/artifacts || \
45-
echo "Warning: Could not prepare source documents at build time"
46-
47-
# Copy and setup entrypoint script
77+
# Setup permissions
4878
COPY scripts/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
49-
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
79+
RUN chmod +x /usr/local/bin/docker-entrypoint.sh && \
80+
useradd --create-home --shell /bin/bash app && \
81+
groupadd -g 999 docker || true && \
82+
usermod -aG docker app && \
83+
chown -R app:app /app
5084

51-
# Create non-root user and add to docker group
52-
RUN useradd --create-home --shell /bin/bash app \
53-
&& groupadd -g 999 docker || true \
54-
&& usermod -aG docker app \
55-
&& chown -R app:app /app
5685
USER app
5786

58-
# Health check
5987
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
6088
CMD curl -f http://localhost:8000/api/v1/health || exit 1
6189

62-
# Use entrypoint for initialization
6390
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
6491

65-
# Default command (can be overridden)
66-
CMD ["uv", "run", "uvicorn", "redis_sre_agent.api.app:app", "--host", "0.0.0.0", "--port", "8000"]
92+
# Optimized CMD: Call uvicorn directly from the venv.
93+
# We don't need 'uv run' overhead in production.
94+
CMD ["uvicorn", "redis_sre_agent.api.app:app", "--host", "0.0.0.0", "--port", "8000"]

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ include = [
7676
]
7777

7878
[tool.uv]
79+
default-groups = []
7980
dev-dependencies = [
8081
"pytest>=7.0.0",
8182
"pytest-asyncio>=0.21.0",

0 commit comments

Comments
 (0)