Docker Deployment
Build, run, verify, and secure the Terry-Form MCP Docker container
Docker Deployment Guide
This guide covers building, running, and securing the Terry-Form MCP Docker container.
Building the Image
Using the Build Script
# Linux/macOS
scripts/build.sh
# Windows
scripts\build.bat
Manual Build
docker build -t terry-form-mcp .
The image is built on hashicorp/terraform:1.12 (Alpine-based) and includes:
- Terraform 1.12
- terraform-ls 0.38.5
- Python 3.10+
- All Python dependencies
Verifying the Build
Run the verification suite (8 checks):
scripts/verify.sh
This verifies:
- Docker is available
- Image size is reasonable
- Terraform is installed and working
- terraform-ls is installed and working
- Python runtime is available
- Required files are present
- All 25 MCP tools register correctly
- Server starts up successfully
Running the Container
Basic Usage
docker run -i --rm \
-v /path/to/workspace:/mnt/workspace \
terry-form-mcp:latest
| Flag | Purpose |
|---|---|
-i |
Interactive mode (required for MCP stdio) |
--rm |
Remove container on exit |
-v |
Mount workspace directory |
Important
Do NOT use
Do NOT use
-d (detached mode) or -p (port mapping). Terry-Form MCP uses stdio transport, not HTTP. The container is invoked by your MCP client.
With Cloud Credentials
docker run -i --rm \
-v /path/to/workspace:/mnt/workspace \
-e AWS_ACCESS_KEY_ID \
-e AWS_SECRET_ACCESS_KEY \
-e AWS_DEFAULT_REGION=us-east-1 \
terry-form-mcp:latest
With GitHub Integration
docker run -i --rm \
-v /path/to/workspace:/mnt/workspace \
-v /path/to/github-app.pem:/keys/github-app.pem:ro \
-e GITHUB_APP_ID=12345 \
-e GITHUB_APP_INSTALLATION_ID=67890 \
-e GITHUB_APP_PRIVATE_KEY_PATH=/keys/github-app.pem \
terry-form-mcp:latest
Container Security
Non-Root Execution
The container runs as the terraform user (UID 1001), not root. This limits the impact of any potential container escape.
Security-Hardened Run
docker run -i --rm \
--security-opt=no-new-privileges \
--cap-drop=ALL \
--read-only \
--tmpfs /tmp \
-v /path/to/workspace:/mnt/workspace:rw \
terry-form-mcp:latest
| Option | Purpose |
|---|---|
--security-opt=no-new-privileges |
Prevent privilege escalation |
--cap-drop=ALL |
Drop all Linux capabilities |
--read-only |
Read-only root filesystem |
--tmpfs /tmp |
Writable temp only in /tmp |
Resource Limits
docker run -i --rm \
--memory=1g \
--cpus=2 \
--pids-limit=100 \
-v /path/to/workspace:/mnt/workspace \
terry-form-mcp:latest
Image Details
| Property | Value |
|---|---|
| Base image | hashicorp/terraform:1.12 |
| OS | Alpine Linux |
| Architecture | amd64, arm64 |
| Size | ~150 MB |
| User | terraform (UID 1001) |
| Entrypoint | python3 server_enhanced_with_lsp.py |
| Workdir | /app |
Windows Support
On Windows, use forward slashes or escaped backslashes for volume mounts:
# PowerShell
docker run -i --rm `
-v "${PWD}/workspace:/mnt/workspace" `
terry-form-mcp:latest
REM Command Prompt
docker run -i --rm -v "%cd%\workspace:/mnt/workspace" terry-form-mcp:latest
Windows with WSL 2
If using WSL 2 (recommended), Docker Desktop integrates natively:
docker run -i --rm \
-v "$(pwd)/workspace:/mnt/workspace" \
terry-form-mcp:latest
Troubleshooting
Image Won’t Build
# Check Docker is running
docker info
# Build with verbose output
docker build --progress=plain -t terry-form-mcp .
Permission Denied on Workspace
The container runs as UID 1001. Ensure your workspace is accessible:
# Option 1: Make workspace world-readable
chmod -R 755 /path/to/workspace
# Option 2: Match the container UID
chown -R 1001:1001 /path/to/workspace
Container Exits Immediately
Terry-Form MCP expects stdin input (MCP protocol). If run without -i, it will exit immediately. Always use the -i flag.
Checking Container Contents
# List installed tools
docker run --rm terry-form-mcp:latest terraform version
docker run --rm terry-form-mcp:latest terraform-ls -version
docker run --rm terry-form-mcp:latest python3 --version
# Check file structure
docker run --rm terry-form-mcp:latest ls -la /app/