-
Notifications
You must be signed in to change notification settings - Fork 32
Expand file tree
/
Copy pathDockerfile
More file actions
119 lines (97 loc) · 5 KB
/
Dockerfile
File metadata and controls
119 lines (97 loc) · 5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# syntax=docker/dockerfile:1.4
# Multi-stage build for smaller image
# Cache bust: 2026-02-27
FROM python:3.12-slim AS builder
# Disable man pages and docs to speed up apt operations
RUN echo 'path-exclude /usr/share/doc/*' > /etc/dpkg/dpkg.cfg.d/01_nodoc && \
echo 'path-exclude /usr/share/man/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
echo 'path-exclude /usr/share/groff/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
echo 'path-exclude /usr/share/info/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
echo 'path-exclude /usr/share/lintian/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
echo 'path-exclude /usr/share/linda/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc
# Install build dependencies in one layer
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
gcc \
libpq-dev \
git
# Install uv (cacheable)
RUN --mount=type=cache,target=/root/.cache/pip \
pip install --no-cache-dir uv
# Set up caching for uv
ENV UV_CACHE_DIR=/cache/uv
ENV UV_TOOL_DIR=/cache/uv-tools
ENV UV_PYTHON_PREFERENCE=only-system
# Copy project files
WORKDIR /app
COPY pyproject.toml uv.lock ./
# Install dependencies with caching and increased timeout
# This layer will be cached as long as pyproject.toml and uv.lock don't change
ENV UV_HTTP_TIMEOUT=300
RUN --mount=type=cache,target=/cache/uv \
--mount=type=cache,target=/root/.cache/pip \
uv sync --frozen
# Runtime stage
FROM python:3.12-slim
# OCI labels for GitHub Container Registry
LABEL org.opencontainers.image.title="AdCP Sales Agent"
LABEL org.opencontainers.image.description="Reference implementation of an AdCP (Ad Context Protocol) Sales Agent. See docs/quickstart.md for deployment options."
LABEL org.opencontainers.image.url="https://github.com/prebid/salesagent"
LABEL org.opencontainers.image.source="https://github.com/prebid/salesagent"
LABEL org.opencontainers.image.documentation="https://github.com/prebid/salesagent/blob/main/docs/quickstart.md"
LABEL org.opencontainers.image.vendor="Agentic Advertising Foundation"
LABEL org.opencontainers.image.licenses="MIT"
# Disable man pages and docs to speed up apt operations
RUN echo 'path-exclude /usr/share/doc/*' > /etc/dpkg/dpkg.cfg.d/01_nodoc && \
echo 'path-exclude /usr/share/man/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
echo 'path-exclude /usr/share/groff/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
echo 'path-exclude /usr/share/info/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
echo 'path-exclude /usr/share/lintian/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc && \
echo 'path-exclude /usr/share/linda/*' >> /etc/dpkg/dpkg.cfg.d/01_nodoc
# Install runtime dependencies including nginx (no gcc/libpq-dev/git — build deps stay in builder)
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
--mount=type=cache,target=/var/lib/apt,sharing=locked \
apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
libpq5 \
curl \
nginx
# Install supercronic for cron jobs (container-friendly cron)
ARG TARGETARCH
RUN SUPERCRONIC_ARCH=$(case "${TARGETARCH}" in "arm64") echo "linux-arm64" ;; *) echo "linux-amd64" ;; esac) && \
curl -fsSL "https://github.com/aptible/supercronic/releases/download/v0.2.41/supercronic-${SUPERCRONIC_ARCH}" \
-o /usr/local/bin/supercronic && \
chmod +x /usr/local/bin/supercronic
WORKDIR /app
# Cache bust for COPY layer - change this value to force rebuild
ARG CACHE_BUST=2026-02-27-GAM-API-BUMP
RUN echo "Cache bust: $CACHE_BUST"
# Copy application code
COPY . .
# Copy pre-built virtual environment from builder stage (contains all compiled deps)
COPY --from=builder /app/.venv /app/.venv
# Copy nginx configs - run_all_services.py selects based on ADCP_MULTI_TENANT
# Default: single-tenant (path-based routing, localhost upstreams)
# ADCP_MULTI_TENANT=true: multi-tenant (subdomain routing)
# Development config included for docker-compose.yml multi-container setup
COPY config/nginx/nginx-single-tenant.conf /etc/nginx/nginx-single-tenant.conf
COPY config/nginx/nginx-multi-tenant.conf /etc/nginx/nginx-multi-tenant.conf
COPY config/nginx/nginx-development.conf /etc/nginx/nginx-development.conf
# Create nginx directories with proper permissions
RUN mkdir -p /var/log/nginx /var/run && \
chown -R www-data:www-data /var/log/nginx /var/run
# Add .venv to PATH and set PYTHONPATH for module imports
ENV PATH="/app/.venv/bin:$PATH"
ENV PYTHONPATH="/app"
ENV PYTHONUNBUFFERED=1
# Default port
ENV ADCP_PORT=8080
ENV ADCP_HOST=0.0.0.0
# Expose port 8000 (nginx proxy - the only external-facing port)
# Internal services (MCP:8080, Admin:8001, A2A:8091) are accessed via nginx
EXPOSE 8000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# Use venv Python directly as entrypoint (prepares for hardened images that lack bash)
ENTRYPOINT ["/app/.venv/bin/python", "scripts/deploy/run_all_services.py"]