Skip to content
This repository was archived by the owner on Oct 17, 2025. It is now read-only.

Commit a06b569

Browse files
committed
dockerize everything
1 parent fad000d commit a06b569

File tree

4 files changed

+289
-0
lines changed

4 files changed

+289
-0
lines changed

Dockerfile

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Use an official Python runtime as a parent image
2+
FROM python:3.12-slim
3+
4+
# Set environment variables to prevent interactive prompts during installation
5+
ENV PYTHONUNBUFFERED=1 \
6+
DEBIAN_FRONTEND=noninteractive
7+
8+
# Install system dependencies: nginx, curl (for health checks in registry), procps (for ps command used in stop script), openssl (for cert generation), git (needed by uv sometimes), build-essential (for potential C extensions)
9+
RUN apt-get update && apt-get install -y --no-install-recommends \
10+
nginx \
11+
curl \
12+
procps \
13+
openssl \
14+
git \
15+
build-essential \
16+
&& apt-get clean \
17+
&& rm -rf /var/lib/apt/lists/*
18+
19+
# Install uv globally using pip
20+
RUN pip install uv
21+
22+
# Set the working directory in the container
23+
WORKDIR /app
24+
25+
# Copy the entire project context into the container
26+
COPY . /app/
27+
28+
# Install Python dependencies for the MCP Registry using uv
29+
# The server dependencies will be installed by start_all_servers.sh at runtime
30+
RUN cd /app && uv pip install --system --requirement pyproject.toml
31+
32+
# Generate self-signed SSL certificate for Nginx
33+
# Create directories for SSL certs
34+
RUN mkdir -p /etc/ssl/certs /etc/ssl/private
35+
# Generate the certificate and key
36+
RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
37+
-keyout /etc/ssl/private/nginx-selfsigned.key \
38+
-out /etc/ssl/certs/nginx-selfsigned.crt \
39+
-subj "/C=US/ST=State/L=City/O=Organization/OU=OrgUnit/CN=localhost"
40+
41+
# Copy the custom Nginx configuration (will be moved by entrypoint)
42+
# Note: We copy it here so it's part of the image layer
43+
COPY docker/nginx_rev_proxy.conf /app/docker/nginx_rev_proxy.conf
44+
45+
# Make the entrypoint script executable
46+
COPY docker/entrypoint.sh /app/docker/entrypoint.sh
47+
RUN chmod +x /app/docker/entrypoint.sh
48+
49+
# Expose ports for Nginx (HTTP/HTTPS) and the Registry (direct access, though usually proxied)
50+
EXPOSE 80 443 7860
51+
52+
# Define environment variables for registry/server configuration (can be overridden at runtime)
53+
# Provide sensible defaults or leave empty if they should be explicitly set
54+
ARG SECRET_KEY=""
55+
ARG ADMIN_USER="admin"
56+
ARG ADMIN_PASSWORD="password"
57+
ARG POLYGON_API_KEY=""
58+
59+
ENV SECRET_KEY=$SECRET_KEY
60+
ENV ADMIN_USER=$ADMIN_USER
61+
ENV ADMIN_PASSWORD=$ADMIN_PASSWORD
62+
ENV POLYGON_API_KEY=$POLYGON_API_KEY
63+
64+
# Run the entrypoint script when the container launches
65+
ENTRYPOINT ["/app/docker/entrypoint.sh"]

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,29 @@ flowchart TB
138138
cd mcp-gateway
139139
```
140140

141+
1. **Build the Docker container to run the Gateway and Registry:**
142+
143+
```bash
144+
docker build -t mcp-gateway .
145+
146+
```
147+
148+
1. **Run the container:**
149+
150+
```bash
151+
export ADMIN_USER=admin
152+
export ADMIN_PASSWORD=your-admin-password
153+
export POLYGON_API_KEY=your-polygon-api-key
154+
docker run -p 80:80 -p 443:443 \
155+
-e ADMIN_USER=$ADMIN_USER \
156+
-e ADMIN_PASSWORD=$ADMIN_PASSWORD \
157+
-e POLYGON_API_KEY=$POLYGON_API_KEY \
158+
-e SECRET_KEY=$(python3 -c 'import secrets; print(secrets.token_hex(32))') \
159+
--name mcp-gateway-container mcp-gateway
160+
```
161+
162+
### Depreacted instructions, will remove
163+
141164
1. **Create and activate a virtual environment:**
142165
* Using `uv`:
143166
```bash

docker/entrypoint.sh

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/bin/bash
2+
set -e # Exit immediately if a command exits with a non-zero status.
3+
4+
# --- Configuration ---
5+
REGISTRY_ENV_FILE="/app/registry/.env"
6+
FININFO_ENV_FILE="/app/servers/fininfo/.env"
7+
REGISTRY_ENV_TEMPLATE="/app/registry/.env.template"
8+
FININFO_ENV_TEMPLATE="/app/servers/fininfo/.env.template"
9+
NGINX_CONF_SRC="/app/docker/nginx_rev_proxy.conf"
10+
NGINX_CONF_DEST="/etc/nginx/conf.d/nginx_rev_proxy.conf"
11+
12+
# --- Helper Functions ---
13+
generate_secret_key() {
14+
python -c 'import secrets; print(secrets.token_hex(32))'
15+
}
16+
17+
# --- Environment Variable Setup ---
18+
19+
# 1. Registry .env
20+
echo "Setting up Registry environment ($REGISTRY_ENV_FILE)..."
21+
# Use provided values or defaults/generated ones
22+
SECRET_KEY_VALUE=${SECRET_KEY:-$(generate_secret_key)}
23+
ADMIN_USER_VALUE=${ADMIN_USER:-admin}
24+
ADMIN_PASSWORD_VALUE=${ADMIN_PASSWORD:-password} # Default password, recommend changing via env var
25+
26+
# Create .env file from template structure, substituting values
27+
echo "SECRET_KEY=${SECRET_KEY_VALUE}" > "$REGISTRY_ENV_FILE"
28+
echo "ADMIN_USER=${ADMIN_USER_VALUE}" >> "$REGISTRY_ENV_FILE"
29+
echo "ADMIN_PASSWORD=${ADMIN_PASSWORD_VALUE}" >> "$REGISTRY_ENV_FILE"
30+
echo "Registry .env created."
31+
cat "$REGISTRY_ENV_FILE" # Print for verification
32+
33+
# 2. Fininfo Server .env
34+
echo "Setting up Fininfo server environment ($FININFO_ENV_FILE)..."
35+
# Use provided POLYGON_API_KEY or leave it empty (server handles missing key)
36+
POLYGON_API_KEY_VALUE=${POLYGON_API_KEY:-}
37+
38+
# Create .env file from template structure
39+
echo "POLYGON_API_KEY=${POLYGON_API_KEY_VALUE}" > "$FININFO_ENV_FILE"
40+
echo "Fininfo .env created."
41+
cat "$FININFO_ENV_FILE" # Print for verification
42+
43+
# --- Nginx Configuration ---
44+
echo "Copying custom Nginx configuration..."
45+
cp "$NGINX_CONF_SRC" "$NGINX_CONF_DEST"
46+
echo "Nginx configuration copied to $NGINX_CONF_DEST."
47+
48+
# --- Start Background Services ---
49+
50+
# 1. Start Example MCP Servers
51+
echo "Starting example MCP servers in the background..."
52+
cd /app
53+
./start_all_servers.sh &
54+
echo "MCP servers start command issued."
55+
# Give servers a moment to initialize
56+
sleep 5
57+
58+
# 2. Start MCP Registry
59+
echo "Starting MCP Registry in the background..."
60+
# Navigate to the registry directory to ensure relative paths work
61+
cd /app/registry
62+
# Use uv run to start uvicorn, ensuring it uses the correct environment
63+
# Run on 0.0.0.0 to be accessible within the container network
64+
# Use port 7860 as configured in nginx proxy_pass
65+
uv run uvicorn main:app --host 0.0.0.0 --port 7860 &
66+
echo "MCP Registry start command issued."
67+
# Give registry a moment to initialize and generate initial nginx config
68+
sleep 10
69+
70+
# --- Start Nginx in Background ---
71+
echo "Starting Nginx in the background..."
72+
# Start nginx normally, it will daemonize by default
73+
nginx
74+
75+
echo "Nginx started. Keeping container alive..."
76+
# Keep the container running indefinitely
77+
tail -f /dev/null
78+
79+
echo "Entrypoint script finished." # This line will likely not be reached unless tail fails

docker/nginx_rev_proxy.conf

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# First server block now directly handles HTTP requests instead of redirecting
2+
server {
3+
listen 80;
4+
server_name mcpgateway localhost;
5+
6+
# Route for Cost Explorer service
7+
location / {
8+
proxy_pass http://127.0.0.1:8000/;
9+
proxy_http_version 1.1;
10+
proxy_set_header Host $host;
11+
proxy_set_header X-Real-IP $remote_addr;
12+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
13+
}
14+
15+
# Route for Current Time service
16+
location /currenttime/ {
17+
proxy_pass http://127.0.0.1:8001/;
18+
proxy_http_version 1.1;
19+
proxy_set_header Host $host;
20+
proxy_set_header X-Real-IP $remote_addr;
21+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
22+
}
23+
24+
# Route for Financial Information service
25+
location /fininfo/ {
26+
proxy_pass http://127.0.0.1:8002/;
27+
proxy_http_version 1.1;
28+
proxy_set_header Host $host;
29+
proxy_set_header X-Real-IP $remote_addr;
30+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
31+
32+
# Additional settings for SSE support
33+
proxy_set_header Connection '';
34+
chunked_transfer_encoding off;
35+
proxy_buffering off;
36+
proxy_cache off;
37+
proxy_read_timeout 3600s;
38+
}
39+
40+
location /tsbedrock/ {
41+
# Fix the path handling by adding trailing slash and using $request_uri
42+
proxy_pass https://hwfo2k8szg.execute-api.us-east-1.amazonaws.com/prod/;
43+
44+
# AWS API Gateway often needs Host header to match the API Gateway domain
45+
proxy_set_header Host hwfo2k8szg.execute-api.us-east-1.amazonaws.com;
46+
47+
# These headers help with request routing
48+
proxy_set_header X-Real-IP $remote_addr;
49+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
50+
proxy_set_header X-Forwarded-Proto $scheme;
51+
52+
# API Gateway often requires these settings
53+
proxy_ssl_server_name on;
54+
proxy_buffer_size 16k;
55+
proxy_buffers 4 16k;
56+
57+
# Adjust the rewrite to handle the path correctly
58+
rewrite ^/tsbedrock/(.*)$ /prod/$1 break;
59+
}
60+
61+
error_log /var/log/nginx/error.log debug;
62+
}
63+
64+
# Keep the HTTPS server for clients that prefer it
65+
server {
66+
listen 443 ssl;
67+
server_name mcpgateway localhost;
68+
69+
# SSL Configuration using self-signed certs generated in Dockerfile
70+
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
71+
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
72+
ssl_protocols TLSv1.2 TLSv1.3;
73+
ssl_prefer_server_ciphers off;
74+
# Stronger cipher suite
75+
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
76+
77+
# Duplicate the same location blocks for HTTPS access
78+
location / {
79+
proxy_pass http://127.0.0.1:8000/;
80+
proxy_http_version 1.1;
81+
proxy_set_header Host $host;
82+
proxy_set_header X-Real-IP $remote_addr;
83+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
84+
}
85+
86+
location /currenttime/ {
87+
proxy_pass http://127.0.0.1:8001/;
88+
proxy_http_version 1.1;
89+
proxy_set_header Host $host;
90+
proxy_set_header X-Real-IP $remote_addr;
91+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
92+
}
93+
94+
location /fininfo/ {
95+
proxy_pass http://127.0.0.1:8002/;
96+
proxy_http_version 1.1;
97+
proxy_set_header Host $host;
98+
proxy_set_header X-Real-IP $remote_addr;
99+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
100+
101+
# Additional settings for SSE support
102+
proxy_set_header Connection '';
103+
chunked_transfer_encoding off;
104+
proxy_buffering off;
105+
proxy_cache off;
106+
proxy_read_timeout 3600s;
107+
}
108+
109+
location /tsbedrock/ {
110+
proxy_pass https://hwfo2k8szg.execute-api.us-east-1.amazonaws.com/prod/;
111+
proxy_set_header Host hwfo2k8szg.execute-api.us-east-1.amazonaws.com;
112+
proxy_set_header X-Real-IP $remote_addr;
113+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
114+
proxy_set_header X-Forwarded-Proto $scheme;
115+
proxy_ssl_server_name on;
116+
proxy_buffer_size 16k;
117+
proxy_buffers 4 16k;
118+
rewrite ^/tsbedrock/(.*)$ /prod/$1 break;
119+
}
120+
121+
error_log /var/log/nginx/error.log debug;
122+
}

0 commit comments

Comments
 (0)