Dockerfile
Rama main · réplica de lectura del repositorio original.
# syntax=docker/dockerfile:1.7
# ─── Stage 1: builder ──────────────────────────────────────────────
FROM python:3.12-slim@sha256:f77ac9e44ae96ef2c90b8053ea08c31f8be030f824196b0ae4db6d462c84e51f AS builder
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1
WORKDIR /build
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
gettext \
&& rm -rf /var/lib/apt/lists/*
COPY pyproject.toml README.md ./
COPY src/ ./src/
# Compile gettext catalogs (.po → .mo) so setuptools package-data
# `locale/*/LC_MESSAGES/*.mo` finds them at install time.
RUN set -eu; for po in src/parcel_tracker/i18n/locale/*/LC_MESSAGES/messages.po; do \
msgfmt "$po" -o "${po%.po}.mo"; \
done
RUN pip install --prefix=/install --no-warn-script-location .
# ─── Stage 2: runtime ──────────────────────────────────────────────
FROM python:3.12-slim@sha256:f77ac9e44ae96ef2c90b8053ea08c31f8be030f824196b0ae4db6d462c84e51f AS runtime
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PATH="/usr/local/bin:${PATH}"
WORKDIR /app
# Install runtime dependencies only
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/* \
&& useradd --create-home --shell /usr/sbin/nologin --uid 1000 botuser \
&& mkdir -p /app/data /app/plugins \
&& chown botuser:botuser /app/data
COPY --from=builder /install /usr/local
# Inside the container the web dashboard must listen on all interfaces so the
# published port reaches it; docker-compose.yml binds that port to the host's
# loopback only. It is off unless WEB_ENABLED=true.
ENV WEB_BIND_HOST=0.0.0.0 \
WEB_PORT=8080
EXPOSE 8080
USER botuser
# Healthcheck: DB exists and is readable. Opened read-only so a missing
# database fails the check instead of being silently created empty.
HEALTHCHECK --interval=5m --timeout=15s --start-period=30s --retries=3 \
CMD python -c "import os, pathlib, sqlite3; sqlite3.connect(pathlib.Path(os.getenv('DATABASE_PATH','/app/data/bot.db')).absolute().as_uri() + '?mode=ro', uri=True).execute('SELECT 1')" || exit 1
CMD ["parcel-tracker"]