cropguard / Dockerfile
Abhinav Bhatia
Deploy CropGuard demo panel
22f061a verified
Raw
History Blame Contribute Delete
2.17 kB
# Space image for the demo panel. Docker rather than the Streamlit SDK because the Hub no
# longer accepts `streamlit` as an SDK for new Spaces — only gradio, docker and static.
#
# Separate from the repo-root Dockerfile, which builds the FastAPI serving image. That one
# bakes in weights and serves an API; this one runs a UI and fetches weights at runtime.
FROM python:3.11-slim
# Spaces run the container as uid 1000. Installing as root and running as user leaves pip's
# cache unwritable, so the user is created first and everything happens inside its home.
RUN useradd -m -u 1000 user
USER user
ENV PATH=/home/user/.local/bin:$PATH \
HF_HOME=/home/user/.cache/huggingface \
PYTHONUNBUFFERED=1
WORKDIR /home/user/app
COPY --chown=user requirements.txt .
RUN pip install --no-cache-dir --upgrade pip && pip install --no-cache-dir -r requirements.txt
COPY --chown=user . .
# 7860 is the Spaces default and is declared as `app_port` in the Space card.
EXPOSE 7860
# fileWatcherType=none because nothing edits the source at runtime, and the watcher costs CPU
# that the free tier would rather spend on inference.
#
# XSRF protection is off, and that is required rather than lazy. Spaces serves the app inside
# an iframe on huggingface.co, so Streamlit's XSRF cookie is a third-party cookie and modern
# browsers drop it. The token then never reaches /_stcore/upload_file, which rejects every
# upload with 403 - the file uploader is simply broken with it on. CORS goes with it because
# Streamlit ignores enableCORS=false while XSRF is enabled, so the pair has to move together.
#
# What that costs: a third-party page could POST a file to this app. There is no auth, no
# stored state and no cross-user data here - one anonymous visitor cannot reach another's
# session - so the exposure is an unwanted inference, not a leak.
CMD ["streamlit", "run", "app/streamlit_app.py", \
"--server.port=7860", "--server.address=0.0.0.0", \
"--server.headless=true", "--server.fileWatcherType=none", \
"--server.enableXsrfProtection=false", "--server.enableCORS=false", \
"--server.maxUploadSize=10", \
"--browser.gatherUsageStats=false"]