diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..33373d9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,44 @@ +# Keep the build context small. The dashboard needs dashboard.py, +# datasets_info.py and results/ — everything below belongs to the benchmarking +# pipeline, which does not run in this image. +# +# Without this file the context is ~370 MB; with it, ~47 MB. + +.git +.github +.devcontainer + +# Benchmarking pipeline: Apptainer definitions, demo spectra, evaluation code +algorithms/ +sample_data/ +evaluation/ +tests/ +evaluation.def + +# Pipeline entrypoints and helpers +run.sh +run_dataset.sh +run_split.sh +run_test.sh +build_apptainer_images.sh +augment_predictions.sh +create_dataset.py +dataset_utils.py +dataset_config.py +update_tags.py +test_output_format.py + +# Deployment files themselves are not needed inside the image +Dockerfile +.dockerignore +docker-compose.deployment.yaml +deploy.sh + +# Local/editor cruft +__pycache__/ +*.py[cod] +.venv/ +venv/ +.env +.env.template +.DS_Store diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..e8bbeee --- /dev/null +++ b/Dockerfile @@ -0,0 +1,26 @@ +# Streamlit dashboard for the de novo benchmarking results. +# +# Only the dashboard runs here. The benchmarking pipeline itself needs Apptainer +# and GPUs and is excluded from the build context via .dockerignore. + +FROM python:3.12-slim + +WORKDIR /app + +# curl is needed by the container healthcheck +RUN apt-get update && apt-get install -y --no-install-recommends \ + curl \ + && rm -rf /var/lib/apt/lists/* + +COPY ./requirements-dashboard.txt /app/requirements-dashboard.txt + +RUN pip3 install --no-cache-dir -r requirements-dashboard.txt + +# Brings in dashboard.py, datasets_info.py and results/ +COPY . /app + +EXPOSE 8501 + +HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health + +ENTRYPOINT ["streamlit", "run", "dashboard.py", "--server.port=8501", "--server.address=0.0.0.0"] diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..97475de --- /dev/null +++ b/deploy.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# Build images +docker compose -f docker-compose.deployment.yaml build + +# Start services +docker compose -f docker-compose.deployment.yaml up -d diff --git a/docker-compose.deployment.yaml b/docker-compose.deployment.yaml new file mode 100644 index 0000000..f01c7f5 --- /dev/null +++ b/docker-compose.deployment.yaml @@ -0,0 +1,31 @@ +services: + denovo-benchmarks-streamlit-app: + build: + context: . + dockerfile: Dockerfile + image: bittremieuxlab/denovo-benchmarks-streamlit-app:latest + restart: unless-stopped + + # No host port is published: the reverse proxy reaches the container over + # the shared bittremieuxlab-public network. + expose: + - "8501" + + healthcheck: + test: ["CMD", "curl", "--fail", "http://localhost:8501/_stcore/health"] + interval: 30s + timeout: 5s + retries: 3 + + environment: + STREAMLIT_SERVER_PORT: 8501 + STREAMLIT_SERVER_ADDRESS: 0.0.0.0 + STREAMLIT_SERVER_HEADLESS: "true" + TZ: Europe/Brussels + + networks: + - bittremieuxlab-public + +networks: + bittremieuxlab-public: + external: true diff --git a/requirements-dashboard.txt b/requirements-dashboard.txt new file mode 100644 index 0000000..f7ff8f6 --- /dev/null +++ b/requirements-dashboard.txt @@ -0,0 +1,13 @@ +# Dependencies for the Streamlit dashboard (dashboard.py) only. +# +# The root requirements.txt targets the benchmarking pipeline. On Streamlit +# Community Cloud, streamlit was installed automatically and pandas came in as +# one of its dependencies, so neither needed to be listed. A container image +# gets no such treatment, so both are pinned explicitly here. +# +# Versions are pinned so that rebuilds are reproducible: deploy.sh rebuilds the +# image on every deployment, and an unpinned dependency would let an unrelated +# deploy silently pull a breaking major version. Bump these deliberately. +streamlit==1.61.1 +pandas==3.0.5 +plotly==6.5.2