Skip to main content
This guide covers running mcp-server-db2i with Docker and docker-compose.

Quick Start

Build the Image

This builds the default odbc image with the IBM i Access ODBC Driver. IBM publishes that driver for amd64 only, so on an arm64 host such as an Apple Silicon Mac add --platform linux/amd64, or build the jt400 image instead. See Multi-Stage Build.

Run with Environment Variables

Security Warning: Passing credentials via -e flags exposes them in process lists (ps aux), docker inspect output, and shell history. Use --env-file for local testing and Docker secrets for production deployments.

Docker Compose

Basic Setup

Create a .env file:
Run with docker-compose:

HTTP Transport

To expose the HTTP API, uncomment the ports section in docker-compose.yml:
Then run:

Docker Secrets

For production deployments, use Docker secrets instead of environment variables.

1. Create Secret Files

Security Note: Avoid using echo "password" > file directly, as it may be logged in shell history. The read -s command hides input from the terminal.

2. Update docker-compose.yml

3. Run

TLS with Docker

Using Built-in TLS

  1. Mount your certificates:
  1. Generate self-signed certificates (for testing):

Using Reverse Proxy

For production, use a reverse proxy like nginx or Traefik for TLS termination:

Environment Variables

All environment variables can be set in docker-compose.yml or via .env file:

Business SQL tools

Mount a directory of YAML tool files and point MCP_CUSTOM_TOOLS at it. The example pack in examples/erp-tools uses placeholder names such as MYLIB.ORDERHDR. Edit those names before relying on the tools.
The server reads the files at startup. A statement that is not a query, or that names a library outside QUERY_ALLOWED_SCHEMAS, stops the container. See Business SQL tools.

Query exports

The image has an empty /data/exports directory owned by mcpuser with mode 0700. Point EXPORT_DIR at it and mount a named volume there, which takes the same owner:
Over HTTP, users download through the link and never see the path. Over stdio the result is a path inside the container, which is only useful on the host through a bind mount: mount a host directory at /data/exports and make it writable by the container’s mcpuser. See Query exports.

Multi-Stage Build

The Dockerfile uses a multi-stage build with two runtime targets:
  1. Builder stage: Compiles TypeScript to JavaScript and prunes dev dependencies
  2. odbc target (default): unixODBC and the IBM i Access ODBC Driver from IBM’s apt repository, no Java. Sets DB2I_DRIVER=odbc.
  3. jt400 target: OpenJDK 17 JRE for the JT400 JDBC driver. Sets DB2I_DRIVER=jt400.
IBM publishes the ODBC driver package for amd64, i386 and ppc64el only. On an arm64 host such as an Apple Silicon Mac, build and run the ODBC image under emulation with --platform linux/amd64; the build fails early with a message otherwise. The jt400 image builds natively on arm64.
Either image can run the mapepire driver, because it needs nothing native. Override the driver and pin the host key, since the container has no known_hosts. Alternatively, mount a known_hosts file and set knownHostsFile to its path.
The bundled docker-compose.yml builds the ODBC image with platform: linux/amd64. To use the JDBC image, set target: jt400 under build and remove the platform line. Both images:
  • Use node:22-bookworm-slim. Bookworm is pinned so OpenJDK 17 stays available for the jt400 target. Debian trixie does not package it.
  • Run as non-root user (mcpuser)
  • Include only production dependencies
  • Default MCP_SESSION_MODE to stateless, matching the server. stateful is deprecated.
The odbc image installs ibm-iaccess from public.dhe.ibm.com at build time, so the build needs network access to that host. See Database Drivers for the ODBC keywords.

Health Checks

For HTTP transport, add a health check:
Note: The image is Debian slim and does not include curl or wget. The check uses Node’s built-in fetch.

Resource Limits

Set resource limits for production:

Logging

View Logs

Log Configuration

For production, use JSON logging:

Log Drivers

Configure Docker log drivers for centralized logging:

Networking

Bridge Network (default)

Host Network

For better performance (Linux only):

Example: Complete Production Setup

Troubleshooting

Container Won’t Start

  1. Check logs: docker-compose logs mcp-server-db2i
  2. Verify environment variables are set
  3. Ensure IBM i is reachable from container

Connection Refused

  1. Check if IBM i port (446) is accessible
  2. Verify hostname resolves correctly
  3. Check firewall rules

Permission Denied

  1. Ensure secret files have correct permissions
  2. Check volume mount permissions
  3. Verify non-root user has access

Out of Memory

  1. Increase memory limits
  2. Reduce QUERY_MAX_LIMIT
  3. Lower MCP_MAX_SESSIONS