# 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"]