Spaces:
Sleeping
Sleeping
| # MCP-Compliant Dockerfile for Hugging Face Spaces deployment of Coral Server | |
| # ============================================================================== | |
| # Build Stage: Compile the Coral Server application | |
| # ============================================================================== | |
| FROM gradle:8.5-jdk21 AS build | |
| # Set working directory | |
| WORKDIR /app | |
| # Clone the Coral Server repository | |
| RUN git clone https://github.com/Coral-Protocol/coral-server.git . | |
| # Build the application, skipping tests to speed up the build | |
| RUN gradle build --no-daemon -x test | |
| # Create configuration directory | |
| RUN mkdir -p /coral-config | |
| # Copy default configs if they exist, otherwise create minimal ones. | |
| # Note: The server port here is set to 7860, but it will be overridden at runtime. | |
| RUN if [ ! -f src/main/resources/application.yaml ]; then \ | |
| echo "server:" > /coral-config/application.yaml && \ | |
| echo " port: 7860" >> /coral-config/application.yaml && \ | |
| echo "mcp:" >> /coral-config/application.yaml && \ | |
| echo " transport: sse" >> /coral-config/application.yaml; \ | |
| else \ | |
| cp src/main/resources/application.yaml /coral-config/; \ | |
| fi && \ | |
| if [ ! -f src/main/resources/registry.toml ]; then \ | |
| touch /coral-config/registry.toml; \ | |
| else \ | |
| cp src/main/resources/registry.toml /coral-config/; \ | |
| fi | |
| # ============================================================================== | |
| # Runtime Stage: Set up the final container with Nginx and the Java app | |
| # ============================================================================== | |
| FROM openjdk:21-jdk-slim | |
| # Install Nginx for reverse proxying | |
| RUN apt-get update && apt-get install -y \ | |
| curl \ | |
| nginx \ | |
| && rm -rf /var/lib/apt/lists/* | |
| # Set working directory | |
| WORKDIR /app | |
| # Copy built application and configs from the build stage | |
| COPY --from=build /app/build/libs/*.jar app.jar | |
| COPY --from=build /coral-config /app/coral-config | |
| # Create Nginx config to proxy requests from public port 7860 to the internal Coral Server port 5555 | |
| RUN echo 'server {' > /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' listen 7860;' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' server_name localhost;' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo '' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' # Proxy all locations to the Coral Server' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' location / {' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' proxy_pass http://127.0.0.1:5555;' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' proxy_http_version 1.1;' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' proxy_set_header Upgrade $http_upgrade;' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' proxy_set_header Connection "upgrade";' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' proxy_set_header Host $host;' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' proxy_cache_bypass $http_upgrade;' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' proxy_buffering off;' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' proxy_read_timeout 86400;' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo ' }' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| echo '}' >> /etc/nginx/sites-available/mcp-proxy && \ | |
| ln -s /etc/nginx/sites-available/mcp-proxy /etc/nginx/sites-enabled/ && \ | |
| rm /etc/nginx/sites-enabled/default | |
| # Create a startup script to run both Nginx and the Coral Server | |
| RUN echo '#!/bin/bash' > /app/start.sh && \ | |
| echo 'set -e' >> /app/start.sh && \ | |
| echo '' >> /app/start.sh && \ | |
| echo '# Start Nginx in the background, listening on port 7860' >> /app/start.sh && \ | |
| echo 'nginx -g "daemon off;" &' >> /app/start.sh && \ | |
| echo 'NGINX_PID=$!' >> /app/start.sh && \ | |
| echo '' >> /app/start.sh && \ | |
| echo '# Start Coral Server, telling it to listen on internal port 5555' >> /app/start.sh && \ | |
| echo 'java -Xmx1g -Xms512m -jar app.jar --sse-server 5555 &' >> /app/start.sh && \ | |
| echo 'CORAL_PID=$!' >> /app/start.sh && \ | |
| echo '' >> /app/start.sh && \ | |
| echo '# Wait for either process to exit' >> /app/start.sh && \ | |
| echo 'wait -n $NGINX_PID $CORAL_PID' >> /app/start.sh && \ | |
| echo '' >> /app/start.sh && \ | |
| echo '# Clean up both processes if one exits' >> /app/start.sh && \ | |
| echo 'kill $NGINX_PID $CORAL_PID 2>/dev/null || true' >> /app/start.sh && \ | |
| chmod +x /app/start.sh | |
| # Create a non-root user as required by Hugging Face Spaces | |
| RUN useradd -m -u 1000 user && \ | |
| chown -R user:user /app && \ | |
| chown -R user:user /var/log/nginx && \ | |
| chown -R user:user /var/lib/nginx && \ | |
| touch /var/run/nginx.pid && \ | |
| chown user:user /var/run/nginx.pid | |
| USER user | |
| # Set environment variables | |
| ENV HOME=/home/user \ | |
| PATH=/home/user/.local/bin:$PATH \ | |
| CONFIG_PATH=/app/coral-config/ | |
| # Expose the public port that Nginx is listening on | |
| EXPOSE 7860 | |
| # Health check to ensure the service is running and accessible via the proxy | |
| HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ | |
| CMD curl -f http://localhost:7860/devmode/exampleApplication/privkey/session1/sse || exit 1 | |
| # Start the application using the script | |
| CMD ["/app/start.sh"] |