Quick Start
Build the Image
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-eflags exposes them in process lists (ps aux),docker inspectoutput, and shell history. Use--env-filefor local testing and Docker secrets for production deployments.
Run with env file (Recommended)
Docker Compose
Basic Setup
Create a.env file:
HTTP Transport
To expose the HTTP API, uncomment theports section in docker-compose.yml:
Docker Secrets
For production deployments, use Docker secrets instead of environment variables.1. Create Secret Files
Security Note: Avoid usingecho "password" > filedirectly, as it may be logged in shell history. Theread -scommand hides input from the terminal.
2. Update docker-compose.yml
3. Run
TLS with Docker
Using Built-in TLS
- Mount your certificates:
- 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 pointMCP_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.
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:
/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:- Builder stage: Compiles TypeScript to JavaScript and prunes dev dependencies
odbctarget (default): unixODBC and the IBM i Access ODBC Driver from IBM’s apt repository, no Java. SetsDB2I_DRIVER=odbc.jt400target: OpenJDK 17 JRE for the JT400 JDBC driver. SetsDB2I_DRIVER=jt400.
--platform linux/amd64; the build fails early with a message otherwise. The jt400 image builds natively on arm64.
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.
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 thejt400target. Debian trixie does not package it. - Run as non-root user (
mcpuser) - Include only production dependencies
- Default
MCP_SESSION_MODEtostateless, matching the server.statefulis deprecated.
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 includecurlorwget. The check uses Node’s built-infetch.
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
- Check logs:
docker-compose logs mcp-server-db2i - Verify environment variables are set
- Ensure IBM i is reachable from container
Connection Refused
- Check if IBM i port (446) is accessible
- Verify hostname resolves correctly
- Check firewall rules
Permission Denied
- Ensure secret files have correct permissions
- Check volume mount permissions
- Verify non-root user has access
Out of Memory
- Increase memory limits
- Reduce
QUERY_MAX_LIMIT - Lower
MCP_MAX_SESSIONS