Spaces:
Runtime error
Runtime error
| # 1. Start from a slim Python 3.11 base image | |
| FROM python:3.11-slim | |
| # 2. Set Environment Variables | |
| # - DEBIAN_FRONTEND: Prevents installers from asking interactive questions | |
| # - PYTHONUNBUFFERED/PYTHONDONTWRITEBYTECODE: Standard Python-in-Docker settings | |
| # - PYVISTA_OFF_SCREEN/DISPLAY: Crucial for running PyVista headless (off-screen) | |
| # by telling it to use a "virtual" display at address :99 | |
| ENV DEBIAN_FRONTEND=noninteractive \ | |
| PYTHONUNBUFFERED=1 \ | |
| PYTHONDONTWRITEBYTECODE=1 \ | |
| HOME=/home/user \ | |
| PATH=/home/user/.local/bin:$PATH \ | |
| PYVISTA_OFF_SCREEN=true \ | |
| DISPLAY=:99 \ | |
| VTK_SILENCE_GET_VOID_POINTER_WARNINGS=1 | |
| # 3. Install System Dependencies | |
| # This is the most critical part for PyVista/VTK. We need the OS | |
| # graphics libraries (libosmesa, libgl1) and the X Virtual FrameBuffer (xvfb). | |
| # | |
| # *** UPDATED this section to use current package names (e.g., libgl1, libegl1) *** | |
| # | |
| RUN apt-get update && apt-get install -y --no-install-recommends \ | |
| build-essential cmake wget xvfb nginx \ | |
| libosmesa6 libosmesa6-dev \ | |
| libgl1 libgl1-mesa-dev \ | |
| libegl1 libegl1-mesa-dev \ | |
| libglu1-mesa libglu1-mesa-dev \ | |
| libgles2-mesa-dev \ | |
| libx11-6 libxt6 libxrender1 libsm6 libice6 \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # 4. Create a non-root user for security | |
| RUN useradd -m -u 1000 user | |
| WORKDIR /home/user/app | |
| # 5. Install Python dependencies (optimized) | |
| # We copy *only* requirements.txt first and install it. | |
| # This "layer" is cached by Docker. If you only change app.py later, | |
| # Docker skips this step, making builds much faster. | |
| COPY requirements.txt . | |
| RUN python3 -m pip install --upgrade pip setuptools wheel \ | |
| && python3 -m pip install --no-cache-dir -r requirements.txt | |
| # 6. Copy the rest of the application code | |
| # This copies app.py, delta_impulse_generator.py, etc. | |
| # We set the owner to our new 'user'. | |
| COPY --chown=user:user . . | |
| COPY docker/nginx.conf /etc/nginx/nginx.conf | |
| # Prepare writable directories for nginx (running as non-root later) | |
| RUN mkdir -p /tmp/nginx/body /tmp/nginx/proxy /tmp/nginx/fastcgi /tmp/nginx/uwsgi /tmp/nginx/scgi \ | |
| && touch /tmp/nginx.access.log /tmp/nginx.error.log \ | |
| && chown -R user:user /tmp/nginx /tmp/nginx.access.log /tmp/nginx.error.log | |
| # 7. Switch to the non-root user | |
| USER user | |
| # Default runtime configuration for multiprocess layout | |
| ENV OMP_NUM_THREADS=1 \ | |
| APP_HOST=127.0.0.1 \ | |
| APP_PORT=8700 \ | |
| EM_APP_PORT=8701 \ | |
| QLBM_APP_PORT=8702 \ | |
| EM_HOST=127.0.0.1 \ | |
| QLBM_HOST=127.0.0.1 \ | |
| EM_IFRAME_SRC=/em/ \ | |
| QLBM_IFRAME_SRC=/qlbm/ | |
| # 8. Expose the port the app will run on | |
| EXPOSE 7860 | |
| # 9. Healthcheck (good practice for hosting platforms) | |
| HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ | |
| CMD wget --no-verbose --tries=1 --spider http://localhost:${PORT:-7860}/ || exit 1 | |
| # 10. Start Command | |
| # This command does two things: | |
| # a) Starts the X Virtual FrameBuffer (Xvfb) in the background (&) on display :99 | |
| # b) 'exec' runs your app. Using 'exec' is important as it makes the Python | |
| # process the main one, which properly handles signals (like stopping the container). | |
| # '--host 0.0.0.0' is ESSENTIAL to make the server accessible from outside the container. | |
| CMD ["sh", "-c", "Xvfb :99 -screen 0 1024x768x24 >/dev/null 2>&1 & nginx && exec python3 app.py --server --host ${APP_HOST:-127.0.0.1} --port ${APP_PORT:-8700}"] | |