Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 33 additions & 26 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,34 +1,50 @@
FROM cgr.dev/chainguard/wolfi-base:latest@sha256:003627df3c1e1bba0c4116afcddb314aca9594ee2328c7e876a8081a6c988b2e AS base

ARG PYTHON_VERSION=3.14

ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1

# Install runtime dependencies. Versions deliberately unpinned: Wolfi rolls
# forward and garbage-collects old versions, so an "=<version>" pin breaks the
# build within days. The guardrails are the version-scoped names plus the
# digest above. No pip: uv (below) installs everything.
# libstdc++ NOT optional: the rasterio/pyproj/duckdb manylinux wheels list
# libstdc++.so.6 in DT_NEEDED and auditwheel does not vendor it.
# bash, tzdata, curl parity with the old Debian base: /bin/sh is busybox,
# Wolfi ships no /usr/share/zoneinfo, curl is for in-pod debugging.
RUN apk add --no-cache \
python-${PYTHON_VERSION} \
libstdc++ bash tzdata curl libexpat1

# uv as a pass-through stage rather than a direct COPY --from=<image>:
# Dependabot only parses FROM lines (dependabot/dependabot-core#5103), so this
# keeps the version pinned *and* auto-updated by the docker ecosystem.
FROM ghcr.io/astral-sh/uv:0.12.5@sha256:e85be844203885286c60ffad8a858d48afb6c5a5c237ca0e67f12e74b8f174b1 AS uv

FROM python:${PYTHON_VERSION} AS builder
# Build stage
FROM base AS builder

ARG PYTHON_VERSION

# Set build labels
LABEL stage=builder
LABEL org.opencontainers.image.source="https://github.com/developmentseed/titiler-stacapi"
LABEL org.opencontainers.image.description="TiTiler STAC API"
LABEL org.opencontainers.image.licenses="MIT"

# Set environment variables
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1

# Install build dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libexpat1 curl && \
rm -rf /var/lib/apt/lists/*

# Install uv
COPY --from=uv /uv /uvx /usr/local/bin/

# Configure uv-managed virtual environment
# UV_PYTHON: the apk python above, so the venv's interpreter symlinks resolve
# against the same path in the runtime stage
# UV_COMPILE_BYTECODE: .pyc at install time, as pip did, so cold starts
# don't pay the compile on first import
ENV UV_LINK_MODE=copy \
UV_PROJECT_ENVIRONMENT=/opt/venv \
UV_PYTHON=python${PYTHON_VERSION} \
UV_COMPILE_BYTECODE=1 \
PATH="/opt/venv/bin:${PATH}"

WORKDIR /tmp/app
Expand All @@ -42,32 +58,23 @@ COPY titiler/ titiler/
RUN uv pip install --no-deps .

# Runtime stage
FROM python:${PYTHON_VERSION}-slim
FROM base

# Set runtime labels
LABEL org.opencontainers.image.source="https://github.com/developmentseed/titiler-stacapi"
LABEL org.opencontainers.image.description="TiTiler STAC API"
LABEL org.opencontainers.image.licenses="MIT"

# Set environment variables
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PATH="/opt/venv/bin:$PATH"

# Install runtime dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
libexpat1 fonts-dejavu \
curl && \
rm -rf /var/lib/apt/lists/*
# The chart execs `command: ["uvicorn"]` — a bare binary, resolved against the
# image's PATH.
ENV PATH="/opt/venv/bin:${PATH}"

# Copy virtual environment from builder
COPY --from=builder /opt/venv /opt/venv

RUN groupadd -g 1000 user && \
useradd -u 1000 -g user -s /bin/bash -m user
WORKDIR /tmp

USER user
USER nonroot

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lhoupert I see you didn't use nonroot user in titiler-eopf repo

@lhoupert lhoupert Aug 20, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true I should do the same as you here! The titiler-eopf was using root so I didnt change that ...

@lhoupert lhoupert Aug 20, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: I tested USER nonroot on titiler-eopf and it works fine


###################################################
# For compatibility (might be removed at one point)
Expand Down
Loading
Loading