How to Deploy MCP-PostgreSQL-Ops Using Docker for Isolated Database Operations

Deploy MCP-PostgreSQL-Ops using Docker by cloning the repository, configuring environment variables from .env.example, and executing docker-compose up -d to orchestrate the MCP Server, MCPO Proxy, and optional PostgreSQL containers in an isolated, reproducible stack.

The MCP-PostgreSQL-Ops project by call518 provides a containerized Model Context Protocol (MCP) server that exposes PostgreSQL monitoring and operational tools via HTTP or stdio interfaces. Deploying via Docker ensures consistent dependency management across Python 3.12, required system libraries, and database drivers, while the included docker-compose.yml automates network configuration and service discovery. This guide walks through the complete Docker deployment process using the official repository structure and production-ready configuration patterns.

Architecture Overview and Component Stack

The Docker deployment consists of four primary services defined in docker-compose.yml, each serving a distinct role in the observability pipeline.

MCP Server — The core Python service built from Dockerfile.MCP-Server. This image installs Python 3.12 alongside the mcpo, fastmcp, aiohttp, and asyncpg packages. At runtime, the container executes scripts/mcp-server-docker-cmd.sh, which loads environment variables from the mounted .env file and launches the server via python -m mcp_postgresql_ops.

MCPO Proxy — An optional reverse-proxy container (call518/mcpo-proxy-postgresql-ops:1.0.3) that translates MCP Server HTTP traffic to a clean endpoint (/postgresql-ops). The proxy depends on the MCP Server container health status and exposes port 8000 internally, mapped to the host via DOCKER_EXTERNAL_PORT_MCPO_PROXY.

PostgreSQL — A target database container using the Percona PostgreSQL image (default version 17). This service exposes port 5432 internally, mapped to host port POSTGRES_PORT (default 15432). The postgres-init-extensions service pre-loads pg_stat_statements and pg_stat_monitor extensions, then creates synthetic test data for immediate validation.

OpenWebUI — An optional frontend (ghcr.io/open-webui/open-webui:0.7.2) that consumes MCP tools as LLM-augmented chat functions, connecting through the MCPO Proxy.

All services communicate over a shared Docker network, using host.docker.internal for Docker Desktop environments or direct service names (postgres, mcp-server) for Linux deployments.

Step-by-Step Docker Deployment

1. Clone and Prepare Environment

Begin by cloning the repository and initializing the configuration file:

git clone https://github.com/call518/mcp-postgresql-ops.git
cd mcp-postgresql-ops
cp .env.example .env

Edit .env to specify database credentials and external ports. The repository provides docker-compose.custom-db.yml for production scenarios where you omit the bundled PostgreSQL container and point to an existing database instance.

2. Build or Pull the MCP Server Image

The default docker-compose.yml references the pre-built image call518/mcp-server-postgresql-ops:1.0.1. To build locally from Dockerfile.MCP-Server:

docker build -t local/mcp-server -f Dockerfile.MCP-Server .

Update the compose file to use image: local/mcp-server if building manually, or rely on the registry version for immediate deployment.

3. Launch the Stack

Execute the orchestration command to start all services in detached mode:

docker-compose up -d

For production databases, use the alternative compose configuration:

docker-compose -f docker-compose.custom-db.yml up -d

This command brings up the MCP Server, MCPO Proxy, and optionally PostgreSQL with extensions initialized. The scripts/mcp-server-docker-cmd.sh entry-point automatically sources the mounted .env file and configures the FastMCP server parameters.

4. Verify Container Health

Wait 10-15 seconds for initialization, then validate service status:

docker-compose ps
docker-compose logs -f mcp-server

Look for log entries indicating "Starting OpenStack MCP server" and successful PostgreSQL connection handshakes. The MCP Server exposes its raw endpoint on the port defined by DOCKER_EXTERNAL_PORT_MCP_SERVER (default 18003), while the MCPO Proxy serves the documented API on DOCKER_EXTERNAL_PORT_MCPO_PROXY (default 8003).

Configuration and Environment Variables

The .env.example file centralizes all deployment parameters. Key variables include:

  • POSTGRES_HOST — Use host.docker.internal for host-accessible databases or postgres for the compose-managed container.
  • FASTMCP_TYPE — Set to streamable-http for Docker deployments (stdio mode is reserved for local uvx execution).
  • FASTMCP_PORT — Internal container port (default 8000), distinct from the host-mapped DOCKER_EXTERNAL_PORT_MCP_SERVER.
  • REMOTE_AUTH_ENABLE — Set to true and configure REMOTE_SECRET_KEY for production authentication.

Example minimal configuration for a self-contained demo:

POSTGRES_HOST=host.docker.internal
POSTGRES_PORT=15432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=changeme!@34
POSTGRES_DB=ecommerce

FASTMCP_TYPE=streamable-http
FASTMCP_HOST=0.0.0.0
FASTMCP_PORT=8000
REMOTE_AUTH_ENABLE=false

Building Custom Images and Registry Deployment

To customize the MCP Server with additional Python dependencies or modified source code in src/mcp_postgresql_ops/mcp_main.py, rebuild the image:

docker build -t myorg/mcp-server:latest -f Dockerfile.MCP-Server .

Tag and push to a private registry:

docker tag myorg/mcp-server:latest registry.example.com/myorg/mcp-server:latest
docker push registry.example.com/myorg/mcp-server:latest

Update docker-compose.yml to reference your custom image:

services:
  mcp-server:
    image: registry.example.com/myorg/mcp-server:latest
    env_file: .env
    ports:
      - "${DOCKER_EXTERNAL_PORT_MCP_SERVER}:8000"

Accessing the MCP API Endpoints

Once deployed, interact with the tools via HTTP requests. The MCPO Proxy routes calls to http://localhost:${DOCKER_EXTERNAL_PORT_MCPO_PROXY}/postgresql-ops/.

Test connectivity and list active database sessions:

curl -s http://localhost:8003/postgresql-ops/get_active_connections | jq .

View the auto-generated OpenAPI documentation at:


http://localhost:${DOCKER_EXTERNAL_PORT_MCPO_PROXY}/postgresql-ops/docs

For direct MCP Server access (bypassing the proxy), use the port mapped to DOCKER_EXTERNAL_PORT_MCP_SERVER (default 18003).

Summary

  • Deploy MCP-PostgreSQL-Ops using Docker by cloning call518/mcp-postgresql-ops, copying .env.example to .env, and running docker-compose up -d.
  • The Dockerfile.MCP-Server builds a Python 3.12 environment with fastmcp, asyncpg, and aiohttp, while scripts/mcp-server-docker-cmd.sh handles runtime initialization.
  • Use docker-compose.custom-db.yml to connect to existing production PostgreSQL instances instead of the bundled Percona container.
  • The MCPO Proxy (call518/mcpo-proxy-postgresql-ops:1.0.3) provides a clean HTTP interface on port 8000 (externally mapped via DOCKER_EXTERNAL_PORT_MCPO_PROXY).
  • All configuration is externalized to .env, enabling version-controlled, reproducible deployments across development and production environments.

Frequently Asked Questions

How do I connect MCP-PostgreSQL-Ops to an existing production database instead of the test container?

Use the docker-compose.custom-db.yml file provided in the repository root. This configuration omits the postgres and postgres-init-extensions services. Set POSTGRES_HOST in your .env file to host.docker.internal (for Docker Desktop) or your database server's IP address, ensuring the POSTGRES_PORT, POSTGRES_USER, and POSTGRES_PASSWORD variables match your production credentials.

What is the difference between the raw MCP Server port and the MCPO Proxy port?

The MCP Server (defined in Dockerfile.MCP-Server and started via scripts/mcp-server-docker-cmd.sh) listens on port 8000 internally for FastMCP streamable HTTP traffic, exposed to the host via DOCKER_EXTERNAL_PORT_MCP_SERVER (default 18003). The MCPO Proxy sits in front of the server to provide URL routing (/postgresql-ops), enhanced logging, and health checks, exposing port 8000 internally mapped to DOCKER_EXTERNAL_PORT_MCPO_PROXY (default 8003). Production deployments should route traffic through the proxy.

How do I enable authentication for the HTTP API?

Set REMOTE_AUTH_ENABLE=true in your .env file and define a strong REMOTE_SECRET_KEY. The src/mcp_postgresql_ops/mcp_main.py implementation checks these variables to enforce bearer token validation on HTTP endpoints. When enabled, all requests to the MCPO Proxy or direct MCP Server must include an Authorization: Bearer <token> header matching the configured secret.

Can I modify the source code without rebuilding the Docker image?

Yes. The default docker-compose.yml mounts the local ./src directory as a volume inside the container at /app/src. Changes to src/mcp_postgresql_ops/functions.py or mcp_main.py reflect immediately upon container restart without requiring a new image build. For permanent deployment, rebuild the image using Dockerfile.MCP-Server and push to your registry.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →