Skip to content

Conversation

@michaelmoore-s1
Copy link
Contributor

Docker Deployment and Production Setup

This pull request introduces comprehensive Docker support and production deployment capabilities for Purple MCP. The changes enable the server to run in containerized environments with proper security hardening, authentication, and observability.

Summary

  • Adds multi-stage Dockerfile with optimized production builds running as non-root user
  • Implements nginx reverse proxy with TLS termination and bearer token authentication
  • Includes automated GHCR publishing workflow triggered by release tags
  • Adds comprehensive Docker and production deployment documentation (DOCKER.md, PRODUCTION_SETUP.md)
  • Implements CI testing for all three MCP transport modes (stdio, SSE, streamable-http)
  • Provides Docker Compose profiles for development and production deployment scenarios
  • Includes security hardening with rate limiting, HTTP security headers, and capability dropping
  • Bumps version to 0.5.1

Docker Support

The implementation provides a multi-stage Dockerfile that creates optimized production images. The build process leverages uv for dependency management with build caching, and the resulting runtime image runs as a non-root user with minimal dependencies. The entrypoint script handles all three MCP transport modes (stdio, SSE, and streamable-http) with automatic configuration based on environment variables.

Images are automatically published to GitHub Container Registry on release tags through a new CI workflow. The workflow produces semantic version tags along with a latest tag for convenient deployment.

Production Deployment Architecture

For production deployments, this adds an nginx reverse proxy configuration that sits in front of the Purple MCP server. The proxy handles TLS termination, bearer token authentication, and provides security hardening through rate limiting and HTTP security headers. The authentication uses a map directive to extract bearer tokens from request headers, avoiding problematic regex patterns.

The nginx configuration includes an IP-restricted health check endpoint at /internal/health that Docker and orchestration platforms can use for health monitoring without requiring authentication. This endpoint allows traffic only from localhost and common Docker bridge networks by default.

Security Hardening

Several security measures are implemented throughout the Docker deployment:

The docker-entrypoint.sh script validates that placeholder authentication tokens are not used in production and issues clear warnings when binding to non-loopback addresses. It automatically adds the --allow-remote-access flag when needed but reminds operators to use a reverse proxy.

The Docker Compose production profile includes security options like no-new-privileges and drops all Linux capabilities to minimize attack surface. The nginx configuration enforces TLS 1.2+ with strong ciphers and includes comprehensive security headers.

Strong warnings are included in the documentation about never using self-signed certificates in production. The production setup guide includes both self-signed certificate generation for testing and Let's Encrypt integration for production use.

Documentation

Three new documentation files provide comprehensive guidance:

DOCKER.md covers basic Docker usage, including building images, running containers directly, and using Docker Compose for development. It explains the different transport modes and how to configure them.

PRODUCTION_SETUP.md provides detailed production deployment instructions with the nginx reverse proxy. It includes credential generation, SSL certificate setup, health check configuration, and troubleshooting guidance. The guide also covers cloud load balancer integration for AWS, GCP, and Azure deployments as an alternative to nginx.

A deploy/ directory includes the nginx configuration template and additional deployment documentation for reference.

Testing Infrastructure

A comprehensive Docker startup test workflow validates all transport modes in CI. The workflow builds the Docker image and tests SSE, streamable-http, and stdio modes with real SentinelOne credentials (from repository secrets). Each test validates that the container starts successfully, passes health checks, and can communicate with the SentinelOne API.

The tests include proper secret masking and skip fork PRs where secrets aren't available. The workflow triggers on changes to Docker-related files and runs concurrently with automatic cancellation of outdated builds.

Changes to Core Files

The pyproject.toml version was bumped to 0.5.1, and package metadata was updated. The .gitignore file now excludes SSL certificates and production configuration files that should never be committed.

CONTRIBUTING.md received updates about Docker development workflows, and README.md was enhanced with a Docker deployment section linking to the detailed guides.

Configuration Flexibility

The Docker Compose configuration provides profiles for different deployment scenarios. Developers can run individual transport modes for testing, while the production profile starts the full stack with nginx and security hardening enabled. Environment variables control all aspects of the deployment, with sensible defaults for optional settings.

The implementation maintains backward compatibility with existing deployment methods while providing a clear path for containerized and production deployments.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@michaelmoore-s1
Copy link
Contributor Author

AI Analysis

Here are some suggestions to consider:

  • Thanks for landing all the automation and docs updates! One blocker remains: the Docker image still uses the unpublished Python 3.14 bases (Dockerfile:3, Dockerfile:19), so docker build (and every new workflow built on top of it) fails before dependency installation. As mentioned previously in this comment, please retarget both stages to a published Python tag (e.g., 3.13) so the container build and startup tests can run end-to-end.

These suggestions are generated by gpt-5-codex as an experimental capability. It may make mistakes. You do not need to follow all these suggestions.

This is outdated model knowlege, the those bases are published and fine. Also the model is misinterpreting the strings...

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

This commit fixes issues with Docker container startup tests and improves
the production deployment configuration:

Test fixes:
- Fixed entrypoint loopback detection tests by intercepting exec with fake python
- Added health check wait for backend before testing proxy (fixes 502 errors)
- Removed obsolete 'version: 3.8' from docker-compose.yml

Configuration improvements:
- Removed capability restrictions that prevented Python HTTP server startup
- Security maintained through Docker network isolation and nginx reverse proxy

The key issue was that the backend service needs time to fully initialize
and pass health checks before nginx can successfully proxy to it. Tests
now wait up to 30 seconds for backend health before proceeding.
@michaelmoore-s1 michaelmoore-s1 merged commit 07a24b4 into main Nov 9, 2025
20 checks passed
@michaelmoore-s1 michaelmoore-s1 deleted the feat-docker-support branch November 9, 2025 01:45
@github-actions
Copy link

github-actions bot commented Nov 9, 2025

AI Analysis

Here are some suggestions to consider:

  • Really appreciate how comprehensive the Docker story now is! I did spot one blocker in docker-entrypoint.sh:21: the script rebuilds the command with set -- python … but never re-appends the original "$@", so every CLI flag a user passes (for example the --mode streamable-http invocation documented in DOCKER.md and README.md) is silently dropped. That makes the container fall back to the default stdio mode, so the advertised HTTP transports never start. Can we preserve the user-supplied arguments when rebuilding the command (e.g., set -- python … "$@") and add a quick test to cover this path?

These suggestions are generated by gpt-5-codex as an experimental capability. It may make mistakes. You do not need to follow all these suggestions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants