11ARG PYTHON_VERSION=3.12
22
3- # Stage 1: Build dependencies
4-
5- # Download the OpenTelemetry Layer with AppSignals Support:
3+ # Stage 1: OTEL
4+ # Download the OpenTelemetry layer
5+ # ref: https://github.com/athewsey/opentelemetry-lambda-container/blob/98069d5eb6d812ccd28d5c80e2f9d6c8a8c76fb9/python-example/lambda-function/Dockerfile
66FROM public.ecr.aws/lambda/python:${PYTHON_VERSION} as otel-builder
7- RUN dnf install -y unzip wget && \
8- wget https://github.com/aws-observability/aws-otel-python-instrumentation/releases/latest/download/layer.zip -O /tmp/layer.zip && \
9- mkdir -p /opt-builder && \
10- unzip /tmp/layer.zip -d /opt-builder/
7+ RUN <<EOF
8+ dnf install -y unzip wget
9+ wget https://github.com/aws-observability/aws-otel-python-instrumentation/releases/download/v0.12.1/layer.zip -O /tmp/layer.zip
10+ mkdir -p /opt-builder
11+ unzip /tmp/layer.zip -d /opt-builder/
12+ EOF
1113
12- # install python dependencies
14+ # Stage 2: titiler-multidim application and dependencies
1315FROM public.ecr.aws/lambda/python:${PYTHON_VERSION} AS builder
1416COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
1517
@@ -20,26 +22,16 @@ WORKDIR /build
2022COPY README.md uv.lock .python-version pyproject.toml ./
2123COPY src/titiler/ ./src/titiler/
2224
23- COPY infrastructure/aws/lambda/otel-requirements.txt ./
24-
25- # Install dependencies to temporary directory with Lambda-specific optimizations
26- # Install OTEL packages to /opt/python (where otel-instrument wrapper expects them)
27- RUN uv pip install \
28- --target /opt-python \
29- --no-cache-dir \
30- --disable-pip-version-check \
31- -r otel-requirements.txt
32-
33- # Install app packages (excluding OTEL packages since they're already installed)
34- RUN uv export --locked --no-editable --no-dev --extra lambda --format requirements.txt -o requirements.txt && \
35- uv pip install \
25+ RUN <<EOF
26+ uv export --locked --no-editable --no-dev --extra lambda --format requirements.txt -o requirements.txt
27+ uv pip install \
3628 --compile-bytecode \
3729 --no-binary pydantic \
3830 --target /deps \
3931 --no-cache-dir \
4032 --disable-pip-version-check \
4133 -r requirements.txt
42-
34+ EOF
4335
4436# Aggressive cleanup to minimize size and optimize for Lambda container
4537# Clean up app dependencies in /deps
@@ -62,50 +54,20 @@ find . -name 'README*' -delete
6254find . -name '*.md' -delete
6355# Strip debug symbols from shared libraries (preserve numpy.libs)
6456find . -type f -name '*.so*' -not -path "*/numpy.libs/*" -exec strip --strip-unneeded {} \; 2>/dev/null || true
65- # Create a manifest file for debugging
66- du -sh . > /tmp/package_size.txt
67- EOF
68-
69- # Clean up OTEL dependencies in /opt-python (lighter cleanup to preserve CLI tools)
70- WORKDIR /opt-python
71- RUN <<EOF
72- # Remove test files and docs
73- find . -type d -a -name 'tests' -print0 | xargs -0 rm -rf
74- find . -type d -a -name 'test' -print0 | xargs -0 rm -rf
75- # Keep bin/ directory for opentelemetry-instrument CLI
76- find . -name '*.mo' -delete
77- find . -name '*.po' -delete
78- find . -name 'LICENSE*' -delete
79- find . -name 'README*' -delete
80- find . -name '*.md' -delete
8157EOF
8258
8359# Stage 3: Final runtime stage - minimal Lambda image optimized for container runtime
8460FROM public.ecr.aws/lambda/python:${PYTHON_VERSION}
8561
86- # Set Lambda-specific environment variables for optimal performance
87- # PYTHONPATH includes both /opt/python (OTEL packages) and LAMBDA_RUNTIME_DIR (app packages)
8862ENV PYTHONUNBUFFERED=1 \
8963 PYTHONDONTWRITEBYTECODE=1
9064
91- # Copy OTEL code
9265COPY --from=otel-builder /opt-builder/ /opt/
9366COPY infrastructure/aws/lambda/collector-config.yaml /opt/collector-config/config.yaml
94-
95- # Copy dependencies from builder stage
96- # OTEL packages to /opt/python (includes opentelemetry-instrument CLI)
97- COPY --from=builder /opt-python /opt/python
98-
99- # App packages to LAMBDA_RUNTIME_DIR
10067COPY --from=builder /deps ${LAMBDA_RUNTIME_DIR}/
101-
102- # Copy required system library
10368COPY --from=builder /usr/lib64/libexpat.so.1 ${LAMBDA_RUNTIME_DIR}/
104-
105- # Copy application handler and OpenTelemetry configuration
10669COPY infrastructure/aws/lambda/handler.py ${LAMBDA_RUNTIME_DIR}/
10770
108- # Ensure handler is executable and optimize permissions
10971RUN <<EOF
11072chmod 644 "${LAMBDA_RUNTIME_DIR}" /handler.py
11173chmod -R 755 /opt/
0 commit comments