The deploy failed:
dockerfile parse error on line 50: unknown instruction: BOQ_BUILD_SHA=dev
I appended BOQ_BUILD_SHA=dev after an ENV block that had no trailing
continuation, so it became a standalone Dockerfile instruction. It was also
wrong-headed: it would have overridden the real SHA baked in by ARG with the
literal string 'dev'. The ARG/ENV pair further up already does the job.
This one is on me. I changed a Dockerfile, pushed it, and told the user to
redeploy, without ever building the image. The earlier deploy was fine
precisely because that image HAD been built and run first.
Verified before pushing this time:
docker build --build-arg BUILD_SHA=51e4600 -> ok
container reports BOQ_BUILD_SHA=51e4600
/_stcore/health -> ok
Central Towers converts inside the image: 192 written, 167 correct,
23 unplaced, 0 formulas clobbered, gate not blocked
65 lines
2.2 KiB
Docker
65 lines
2.2 KiB
Docker
# syntax=docker/dockerfile:1
|
|
#
|
|
# MEGA INFRA · BOQ Converter
|
|
# Streamlit web app. Single process, no database, no build step.
|
|
|
|
FROM python:3.12-slim
|
|
|
|
# libGL/libglib are what pdfplumber -> pdfminer.six -> Wand/OpenCV chain in;
|
|
# without them the container starts and then dies on the first PDF.
|
|
RUN apt-get update \
|
|
&& apt-get install -y --no-install-recommends \
|
|
libglib2.0-0 libgl1 curl \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
ENV PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
PIP_NO_CACHE_DIR=1 \
|
|
PIP_DISABLE_PIP_VERSION_CHECK=1
|
|
|
|
WORKDIR /app
|
|
|
|
# Which build is this? Baked in at image build time so "what am I looking at?"
|
|
# is answerable from the page, not by digging through Coolify's log.
|
|
ARG BUILD_SHA=dev
|
|
ENV BOQ_BUILD_SHA=$BUILD_SHA
|
|
|
|
# Dependencies first, so a code change does not reinstall the world.
|
|
COPY requirements.txt .
|
|
RUN pip install --no-cache-dir -r requirements.txt
|
|
|
|
COPY app.py run.py ./
|
|
COPY boq_engine/ ./boq_engine/
|
|
COPY static/ ./static/
|
|
COPY .streamlit/ ./.streamlit/
|
|
|
|
# Run as a non-root user. UID 1000 matches the usual Coolify/Docker convention.
|
|
RUN useradd --create-home --uid 1000 --shell /bin/bash megainfra \
|
|
&& mkdir -p /data/profiles /app/out \
|
|
&& chown -R megainfra:megainfra /app /data
|
|
USER megainfra
|
|
|
|
ENV HOME=/home/megainfra \
|
|
BOQ_PROFILES=/data/profiles \
|
|
STREAMLIT_BROWSER_GATHER_USAGE_STATS=false \
|
|
MPLCONFIGDIR=/tmp/mpl
|
|
|
|
EXPOSE 8501
|
|
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
|
CMD curl -fsS http://localhost:8501/_stcore/health || exit 1
|
|
|
|
# Flags here deliberately override .streamlit/config.toml:
|
|
# --server.address 0.0.0.0 the config binds 127.0.0.1 for local dev, which
|
|
# is unreachable from outside the container
|
|
# --server.enableXsrfProtection false
|
|
# Coolify's Traefik sits in front and rewrites the
|
|
# origin; Streamlit's origin check then rejects
|
|
# the rewritten POST as a forged request
|
|
CMD ["streamlit", "run", "app.py", \
|
|
"--server.port=8501", \
|
|
"--server.address=0.0.0.0", \
|
|
"--server.headless=true", \
|
|
"--server.enableCORS=false", \
|
|
"--server.enableXsrfProtection=false", \
|
|
"--browser.gatherUsageStats=false"]
|