File size: 2,215 Bytes
9a17899
 
 
 
 
 
 
 
 
 
 
 
 
 
979ea1d
 
9a17899
 
979ea1d
9a17899
 
 
 
9237b3c
9a17899
 
 
 
 
9237b3c
 
 
 
 
 
9a17899
405355b
 
 
9a17899
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# MyAbs — HF Docker Space image.
#
# Why Docker (not the Gradio SDK): ANARCI is bioconda-only and OpenMM/pdbfixer
# are conda-forge — none install cleanly from PyPI. A miniforge base lets us
# recreate the exact stack verified in WSL conda `base` (2026-07).
#
# Layer order matters: conda deps first (so pip sees anarci/torch already
# satisfied and never tries to pull the non-existent PyPI anarci or a CUDA torch).

FROM condaforge/miniforge3:latest

# ---- conda-only deps (pin python to mirror the verified env) --------------
# anarci + hmmer  -> bioconda (IMGT numbering; hmmer is ANARCI's engine)
# openmm + pdbfixer -> conda-forge (ABodyBuilder2 structure refinement)
# biopython is used for Shrake-Rupley SASA (exposure gating of liability flags);
# it also comes in via anarci, but pin it explicitly since the app now needs it.
RUN mamba install -y -n base \
        -c conda-forge -c bioconda \
        python=3.13 anarci hmmer openmm pdbfixer biopython && \
    mamba clean -afy

# ---- pip deps -------------------------------------------------------------
# CPU-only torch FIRST so ImmuneBuilder sees torch satisfied and does not pull
# the multi-GB CUDA build.
RUN pip install --no-cache-dir \
        torch --index-url https://download.pytorch.org/whl/cpu && \
    pip install --no-cache-dir \
        ImmuneBuilder gradio py3Dmol

# The pip package ships WITHOUT the ~674MB ABodyBuilder2 ensemble — it downloads
# on first init. Do that here at BUILD time (as root) so the weights are baked
# into the image (world-readable), avoiding a runtime download AND the
# PermissionError the non-root runtime user would hit writing into site-packages.
RUN python -c "from ImmuneBuilder import ABodyBuilder2; ABodyBuilder2()"

# ---- HF Spaces requirement: run as uid 1000 with a writable home ----------
# The miniforge base already has a user at uid 1000, so -o allows the dup uid
# while still giving us a clean "user" account + /home/user.
RUN useradd -m -o -u 1000 user
USER user
ENV HOME=/home/user \
    PATH=/home/user/.local/bin:$PATH \
    GRADIO_SERVER_NAME=0.0.0.0 \
    GRADIO_SERVER_PORT=7860

WORKDIR /home/user/app
COPY --chown=user:user app.py .

EXPOSE 7860
CMD ["python", "app.py"]