Skip to content
Draft
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
87 changes: 79 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# This Dockerfile builds OpenMS, the TOPP tools, pyOpenMS and thidparty tools.
# This Dockerfile builds OpenMS, the TOPP tools, pyOpenMS and thirdparty tools.
# It also adds a basic streamlit server that serves a pyOpenMS-based app.
# Uses multi-stage build: Ubuntu for compilation, python:3.10-slim-bookworm for runtime (~150MB lighter)
# hints:
# build image and give it a name (here: streamlitapp) with: docker build --no-cache -t streamlitapp:latest --build-arg GITHUB_TOKEN=<your-github-token> . 2>&1 | tee build.log
# check if image was build: docker image ls
Expand Down Expand Up @@ -117,7 +118,79 @@ ENV OPENMS_DATA_PATH="/openms/share/"
RUN rm -rf openms-build

# Prepare and run streamlit app.
FROM compile-openms AS run-app
# Use a minimal Python base image for the runtime
FROM python:3.10-slim-bookworm AS run-app
ARG PORT=8501
ARG GITHUB_TOKEN
ENV GH_TOKEN=${GITHUB_TOKEN}
ARG GITHUB_USER=OpenMS
ARG GITHUB_REPO=streamlit-template

USER root

# Install only runtime dependencies (not build dependencies)
RUN apt-get -y update && apt-get install -y --no-install-recommends --no-install-suggests \
libgtk2.0-0 \
libsvm3 \
libglpk40 \
libzip4 \
zlib1g \
libxerces-c3.2 \
libbz2-1.0 \
libomp5 \
libhdf5-103-1 \
libboost-date-time1.74.0 \
libboost-iostreams1.74.0 \
libboost-regex1.74.0 \
libboost-math1.74.0 \
libboost-random1.74.0 \
libqt6core6 \
libqt6gui6 \
libqt6widgets6 \
libqt6svg6 \
libqt6opengl6 \
libqt6openglwidgets6 \
libgl1 \
openjdk-17-jre-headless \
curl \
jq \
cron \
gnupg \
wget \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
RUN update-ca-certificates

# Install Github CLI (needed for downloading artifacts)
RUN mkdir -p -m 755 /etc/apt/keyrings \
&& wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& apt-get update \
&& apt-get install gh -y \
&& rm -rf /var/lib/apt/lists/*

# Copy OpenMS binaries and libraries from the build stage
COPY --from=compile-openms /openms /openms
COPY --from=compile-openms /thirdparty /thirdparty

# Set environment variables for OpenMS
ENV PATH="/openms/bin/:/thirdparty/LuciPHOr2:/thirdparty/MSGFPlus:/thirdparty/Sirius:/thirdparty/ThermoRawFileParser:/thirdparty/Comet:/thirdparty/Fido:/thirdparty/MaRaCluster:/thirdparty/MyriMatch:/thirdparty/OMSSA:/thirdparty/Percolator:/thirdparty/SpectraST:/thirdparty/XTandem:/thirdparty/crux:${PATH}"
ENV LD_LIBRARY_PATH="/openms/lib/:${LD_LIBRARY_PATH}"
ENV OPENMS_DATA_PATH="/openms/share/"

# Install Python dependencies and copy pyOpenMS from build stage
COPY requirements.txt ./requirements.txt
RUN python -m pip install --upgrade pip && \
grep -Ev '^pyopenms([=<>!~].*)?$' requirements.txt > requirements_cleaned.txt && \
mv requirements_cleaned.txt requirements.txt && \
python -m pip install -r requirements.txt

# Copy pyOpenMS from build stage (built with mamba in compile-openms stage)
# Source path is from mamba environment, target is system site-packages
# The wildcard matches both pyopenms/ package dir and pyopenms-*.dist-info/ metadata
COPY --from=compile-openms /root/miniforge3/envs/streamlit-env/lib/python3.10/site-packages/pyopenms* /usr/local/lib/python3.10/site-packages/

# Create workdir and copy over all streamlit related files/folders.

# note: specifying folder with slash as suffix and repeating the folder name seems important to preserve directory structure
Expand All @@ -139,18 +212,16 @@ COPY .streamlit/config.toml /app/.streamlit/config.toml
COPY clean-up-workspaces.py /app/clean-up-workspaces.py

# add cron job to the crontab
RUN echo "0 3 * * * /root/miniforge3/envs/streamlit-env/bin/python /app/clean-up-workspaces.py >> /app/clean-up-workspaces.log 2>&1" | crontab -
RUN echo "0 3 * * * /usr/local/bin/python /app/clean-up-workspaces.py >> /app/clean-up-workspaces.log 2>&1" | crontab -

# create entrypoint script to start cron service and launch streamlit app
RUN echo "#!/bin/bash" > /app/entrypoint.sh && \
echo "source /root/miniforge3/bin/activate streamlit-env" >> /app/entrypoint.sh && \
echo "service cron start" >> /app/entrypoint.sh && \
echo "streamlit run app.py" >> /app/entrypoint.sh
# make the script executable
RUN chmod +x /app/entrypoint.sh
echo "streamlit run app.py" >> /app/entrypoint.sh && \
chmod +x /app/entrypoint.sh

# Patch Analytics
RUN mamba run -n streamlit-env python hooks/hook-analytics.py
RUN python hooks/hook-analytics.py

# Set Online Deployment
RUN jq '.online_deployment = true' settings.json > tmp.json && mv tmp.json settings.json
Expand Down
64 changes: 25 additions & 39 deletions Dockerfile_simple
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# This Dockerfile creates a container with pyOpenMS
# It also adds a basic streamlit server that serves a pyOpenMS-based app.
# Uses python:3.10-slim-bookworm as base image for smaller image size (~150MB vs ~700MB for ubuntu:22.04)
# hints:
# build image with: docker build -f Dockerfile_simple --no-cache -t streamlitapp:latest --build-arg GITHUB_TOKEN=<your-github-token> . 2>&1 | tee build.log
# check if image was build: docker image ls
# run container: docker run -p 8501:8501 streamlitapp:latest
# debug container after build (comment out ENTRYPOINT) and run container with interactive /bin/bash shell
# prune unused images/etc. to free disc space (e.g. might be needed on gitpod). Use with care.: docker system prune --all --force

FROM ubuntu:22.04 AS stage1
FROM python:3.10-slim-bookworm AS stage1
ARG OPENMS_REPO=https://github.com/OpenMS/OpenMS.git
ARG OPENMS_BRANCH=develop
ARG PORT=8501
Expand All @@ -23,38 +24,28 @@ ARG GITHUB_REPO=streamlit-template
# Step 1: set up a sane build system
USER root

RUN apt-get -y update
# note: streamlit in docker needs libgtk2.0-dev (see https://yugdamor.medium.com/importerror-libgthread-2-0-so-0-cannot-open-shared-object-file-no-such-file-or-directory-895b94a7827b)
RUN apt-get install -y --no-install-recommends --no-install-suggests wget ca-certificates libgtk2.0-dev curl jq cron
RUN apt-get -y update && apt-get install -y --no-install-recommends --no-install-suggests \
wget \
ca-certificates \
libgtk2.0-0 \
curl \
jq \
cron \
gnupg \
&& rm -rf /var/lib/apt/lists/*
RUN update-ca-certificates

# Install Github CLI
RUN (type -p wget >/dev/null || (apt-get update && apt-get install wget -y)) \
&& mkdir -p -m 755 /etc/apt/keyrings \
&& wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& apt-get update \
&& apt-get install gh -y

# Download and install miniforge.
ENV PATH="/root/miniforge3/bin:${PATH}"
RUN wget -q \
https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-Linux-x86_64.sh \
&& bash Miniforge3-Linux-x86_64.sh -b \
&& rm -f Miniforge3-Linux-x86_64.sh
RUN mamba --version

# Setup mamba environment.
RUN mamba create -n streamlit-env python=3.10
RUN echo "mamba activate streamlit-env" >> ~/.bashrc
SHELL ["/bin/bash", "--rcfile", "~/.bashrc"]
SHELL ["mamba", "run", "-n", "streamlit-env", "/bin/bash", "-c"]

#################################### install streamlit
# install packages
RUN mkdir -p -m 755 /etc/apt/keyrings \
&& wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& apt-get update \
&& apt-get install gh -y \
&& rm -rf /var/lib/apt/lists/*

# Install packages
COPY requirements.txt requirements.txt
RUN mamba install pip
RUN python -m pip install --upgrade pip
RUN python -m pip install -r requirements.txt

Expand All @@ -81,18 +72,16 @@ COPY .streamlit/config.toml /app/.streamlit/config.toml
COPY clean-up-workspaces.py /app/clean-up-workspaces.py

# add cron job to the crontab
RUN echo "0 3 * * * /root/miniforge3/envs/streamlit-env/bin/python /app/clean-up-workspaces.py >> /app/clean-up-workspaces.log 2>&1" | crontab -
RUN echo "0 3 * * * /usr/local/bin/python /app/clean-up-workspaces.py >> /app/clean-up-workspaces.log 2>&1" | crontab -

# create entrypoint script to start cron service and launch streamlit app
RUN echo "#!/bin/bash" > /app/entrypoint.sh
RUN echo "source /root/miniforge3/bin/activate streamlit-env" >> /app/entrypoint.sh && \
RUN echo "#!/bin/bash" > /app/entrypoint.sh && \
echo "service cron start" >> /app/entrypoint.sh && \
echo "streamlit run app.py" >> /app/entrypoint.sh
# make the script executable
RUN chmod +x /app/entrypoint.sh
echo "streamlit run app.py" >> /app/entrypoint.sh && \
chmod +x /app/entrypoint.sh

# Patch Analytics
RUN mamba run -n streamlit-env python hooks/hook-analytics.py
RUN python hooks/hook-analytics.py

# Set Online Deployment
RUN jq '.online_deployment = true' settings.json > tmp.json && mv tmp.json settings.json
Expand All @@ -105,8 +94,5 @@ RUN if [ -n "$GH_TOKEN" ]; then \
echo "GH_TOKEN is not set, skipping the release asset download."; \
fi

# make sure that mamba environment is used
SHELL ["mamba", "run", "-n", "streamlit-env", "/bin/bash", "-c"]

EXPOSE $PORT
ENTRYPOINT ["/app/entrypoint.sh"]
Loading