fix: respect NODE_DB_PATH environment variable in Docker (fixes #40)
- Fixed docker-entrypoint.sh to use NODE_DB_PATH instead of hardcoded paths - Added log_message() helper to prevent stdio mode output corruption - Fixed directory creation race condition with proper ownership - Added path validation to ensure NODE_DB_PATH ends with .db - Updated rebuild.ts to respect NODE_DB_PATH environment variable - Added comprehensive documentation for custom database paths - Bumped version to 2.7.16 The bug was caused by hardcoded /app/data/nodes.db paths in the Docker entrypoint script that ignored the NODE_DB_PATH environment variable. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
# Database Configuration
|
# Database Configuration
|
||||||
# For local development: ./data/nodes.db
|
# For local development: ./data/nodes.db
|
||||||
# For Docker: /app/data/nodes.db
|
# For Docker: /app/data/nodes.db
|
||||||
|
# Custom paths supported in v2.7.16+ (must end with .db)
|
||||||
NODE_DB_PATH=./data/nodes.db
|
NODE_DB_PATH=./data/nodes.db
|
||||||
|
|
||||||
# Logging Level (debug, info, warn, error)
|
# Logging Level (debug, info, warn, error)
|
||||||
|
|||||||
@@ -1,39 +1,75 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
|
# Helper function for safe logging (prevents stdio mode corruption)
|
||||||
|
log_message() {
|
||||||
|
[ "$MCP_MODE" != "stdio" ] && echo "$@"
|
||||||
|
}
|
||||||
|
|
||||||
# Environment variable validation
|
# Environment variable validation
|
||||||
if [ "$MCP_MODE" = "http" ] && [ -z "$AUTH_TOKEN" ] && [ -z "$AUTH_TOKEN_FILE" ]; then
|
if [ "$MCP_MODE" = "http" ] && [ -z "$AUTH_TOKEN" ] && [ -z "$AUTH_TOKEN_FILE" ]; then
|
||||||
echo "ERROR: AUTH_TOKEN or AUTH_TOKEN_FILE is required for HTTP mode"
|
log_message "ERROR: AUTH_TOKEN or AUTH_TOKEN_FILE is required for HTTP mode" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Validate AUTH_TOKEN_FILE if provided
|
# Validate AUTH_TOKEN_FILE if provided
|
||||||
if [ -n "$AUTH_TOKEN_FILE" ] && [ ! -f "$AUTH_TOKEN_FILE" ]; then
|
if [ -n "$AUTH_TOKEN_FILE" ] && [ ! -f "$AUTH_TOKEN_FILE" ]; then
|
||||||
echo "ERROR: AUTH_TOKEN_FILE specified but file not found: $AUTH_TOKEN_FILE"
|
log_message "ERROR: AUTH_TOKEN_FILE specified but file not found: $AUTH_TOKEN_FILE" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Database path configuration - respect NODE_DB_PATH if set
|
||||||
|
if [ -n "$NODE_DB_PATH" ]; then
|
||||||
|
# Basic validation - must end with .db
|
||||||
|
case "$NODE_DB_PATH" in
|
||||||
|
*.db) ;;
|
||||||
|
*) log_message "ERROR: NODE_DB_PATH must end with .db" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Use the path as-is (Docker paths should be absolute anyway)
|
||||||
|
DB_PATH="$NODE_DB_PATH"
|
||||||
|
else
|
||||||
|
DB_PATH="/app/data/nodes.db"
|
||||||
|
fi
|
||||||
|
|
||||||
|
DB_DIR=$(dirname "$DB_PATH")
|
||||||
|
|
||||||
|
# Ensure database directory exists with correct ownership
|
||||||
|
if [ ! -d "$DB_DIR" ]; then
|
||||||
|
log_message "Creating database directory: $DB_DIR"
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
# Create as root but immediately fix ownership
|
||||||
|
mkdir -p "$DB_DIR" && chown nodejs:nodejs "$DB_DIR"
|
||||||
|
else
|
||||||
|
mkdir -p "$DB_DIR"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# Database initialization with file locking to prevent race conditions
|
# Database initialization with file locking to prevent race conditions
|
||||||
if [ ! -f "/app/data/nodes.db" ]; then
|
if [ ! -f "$DB_PATH" ]; then
|
||||||
echo "Database not found. Initializing..."
|
log_message "Database not found at $DB_PATH. Initializing..."
|
||||||
# Use a lock file to prevent multiple containers from initializing simultaneously
|
# Use a lock file to prevent multiple containers from initializing simultaneously
|
||||||
(
|
(
|
||||||
flock -x 200
|
flock -x 200
|
||||||
# Double-check inside the lock
|
# Double-check inside the lock
|
||||||
if [ ! -f "/app/data/nodes.db" ]; then
|
if [ ! -f "$DB_PATH" ]; then
|
||||||
echo "Initializing database..."
|
log_message "Initializing database at $DB_PATH..."
|
||||||
cd /app && node dist/scripts/rebuild.js || {
|
cd /app && NODE_DB_PATH="$DB_PATH" node dist/scripts/rebuild.js || {
|
||||||
echo "ERROR: Database initialization failed"
|
log_message "ERROR: Database initialization failed" >&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
) 200>/app/data/.db.lock
|
) 200>"$DB_DIR/.db.lock"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Fix permissions if running as root (for development)
|
# Fix permissions if running as root (for development)
|
||||||
if [ "$(id -u)" = "0" ]; then
|
if [ "$(id -u)" = "0" ]; then
|
||||||
echo "Running as root, fixing permissions..."
|
log_message "Running as root, fixing permissions..."
|
||||||
chown -R nodejs:nodejs /app/data
|
chown -R nodejs:nodejs "$DB_DIR"
|
||||||
|
# Also ensure /app/data exists for backward compatibility
|
||||||
|
if [ -d "/app/data" ]; then
|
||||||
|
chown -R nodejs:nodejs /app/data
|
||||||
|
fi
|
||||||
# Switch to nodejs user (using Alpine's native su)
|
# Switch to nodejs user (using Alpine's native su)
|
||||||
exec su nodejs -c "$*"
|
exec su nodejs -c "$*"
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ docker run -d \
|
|||||||
| `PORT` | HTTP server port | `3000` | No |
|
| `PORT` | HTTP server port | `3000` | No |
|
||||||
| `NODE_ENV` | Environment: `development` or `production` | `production` | No |
|
| `NODE_ENV` | Environment: `development` or `production` | `production` | No |
|
||||||
| `LOG_LEVEL` | Logging level: `debug`, `info`, `warn`, `error` | `info` | No |
|
| `LOG_LEVEL` | Logging level: `debug`, `info`, `warn`, `error` | `info` | No |
|
||||||
|
| `NODE_DB_PATH` | Custom database path (v2.7.16+) | `/app/data/nodes.db` | No |
|
||||||
|
|
||||||
*Either `AUTH_TOKEN` or `AUTH_TOKEN_FILE` must be set for HTTP mode. If both are set, `AUTH_TOKEN` takes precedence.
|
*Either `AUTH_TOKEN` or `AUTH_TOKEN_FILE` must be set for HTTP mode. If both are set, `AUTH_TOKEN` takes precedence.
|
||||||
|
|
||||||
@@ -342,6 +343,28 @@ docker run --rm \
|
|||||||
alpine tar xzf /backup/n8n-mcp-backup.tar.gz -C /target
|
alpine tar xzf /backup/n8n-mcp-backup.tar.gz -C /target
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Custom Database Path (v2.7.16+)
|
||||||
|
|
||||||
|
You can specify a custom database location using `NODE_DB_PATH`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Use custom path within mounted volume
|
||||||
|
docker run -d \
|
||||||
|
--name n8n-mcp \
|
||||||
|
-e MCP_MODE=http \
|
||||||
|
-e AUTH_TOKEN=your-token \
|
||||||
|
-e NODE_DB_PATH=/app/data/custom/my-nodes.db \
|
||||||
|
-v n8n-mcp-data:/app/data \
|
||||||
|
-p 3000:3000 \
|
||||||
|
ghcr.io/czlonkowski/n8n-mcp:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important Notes:**
|
||||||
|
- The path must end with `.db`
|
||||||
|
- For data persistence, ensure the path is within a mounted volume
|
||||||
|
- Paths outside mounted volumes will be lost on container restart
|
||||||
|
- The directory will be created automatically if it doesn't exist
|
||||||
|
|
||||||
## 🐛 Troubleshooting
|
## 🐛 Troubleshooting
|
||||||
|
|
||||||
### Common Issues
|
### Common Issues
|
||||||
@@ -506,4 +529,4 @@ services:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Last updated: June 2025 - Docker implementation v1.0*
|
*Last updated: July 2025 - Docker implementation v1.1*
|
||||||
@@ -5,6 +5,7 @@ This guide helps resolve common issues when running n8n-mcp with Docker, especia
|
|||||||
## Table of Contents
|
## Table of Contents
|
||||||
- [Common Issues](#common-issues)
|
- [Common Issues](#common-issues)
|
||||||
- [502 Bad Gateway Errors](#502-bad-gateway-errors)
|
- [502 Bad Gateway Errors](#502-bad-gateway-errors)
|
||||||
|
- [Custom Database Path Not Working](#custom-database-path-not-working-v27160)
|
||||||
- [Container Name Conflicts](#container-name-conflicts)
|
- [Container Name Conflicts](#container-name-conflicts)
|
||||||
- [n8n API Connection Issues](#n8n-api-connection-issues)
|
- [n8n API Connection Issues](#n8n-api-connection-issues)
|
||||||
- [Docker Networking](#docker-networking)
|
- [Docker Networking](#docker-networking)
|
||||||
@@ -13,6 +14,41 @@ This guide helps resolve common issues when running n8n-mcp with Docker, especia
|
|||||||
|
|
||||||
## Common Issues
|
## Common Issues
|
||||||
|
|
||||||
|
### Custom Database Path Not Working (v2.7.16+)
|
||||||
|
|
||||||
|
**Symptoms:**
|
||||||
|
- `NODE_DB_PATH` environment variable is set but ignored
|
||||||
|
- Database always created at `/app/data/nodes.db`
|
||||||
|
- Custom path setting has no effect
|
||||||
|
|
||||||
|
**Root Cause:** Fixed in v2.7.16. Earlier versions had hardcoded paths in docker-entrypoint.sh.
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
|
||||||
|
1. **Update to v2.7.16 or later:**
|
||||||
|
```bash
|
||||||
|
docker pull ghcr.io/czlonkowski/n8n-mcp:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Ensure path ends with .db:**
|
||||||
|
```bash
|
||||||
|
# Correct
|
||||||
|
NODE_DB_PATH=/app/data/custom/my-nodes.db
|
||||||
|
|
||||||
|
# Incorrect (will be rejected)
|
||||||
|
NODE_DB_PATH=/app/data/custom/my-nodes
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Use path within mounted volume for persistence:**
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
n8n-mcp:
|
||||||
|
environment:
|
||||||
|
NODE_DB_PATH: /app/data/custom/nodes.db
|
||||||
|
volumes:
|
||||||
|
- n8n-mcp-data:/app/data # Ensure parent directory is mounted
|
||||||
|
```
|
||||||
|
|
||||||
### 502 Bad Gateway Errors
|
### 502 Bad Gateway Errors
|
||||||
|
|
||||||
**Symptoms:**
|
**Symptoms:**
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "n8n-mcp",
|
"name": "n8n-mcp",
|
||||||
"version": "2.7.15",
|
"version": "2.7.16",
|
||||||
"description": "Integration between n8n workflow automation and Model Context Protocol (MCP)",
|
"description": "Integration between n8n workflow automation and Model Context Protocol (MCP)",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import * as path from 'path';
|
|||||||
async function rebuild() {
|
async function rebuild() {
|
||||||
console.log('🔄 Rebuilding n8n node database...\n');
|
console.log('🔄 Rebuilding n8n node database...\n');
|
||||||
|
|
||||||
const db = await createDatabaseAdapter('./data/nodes.db');
|
const dbPath = process.env.NODE_DB_PATH || './data/nodes.db';
|
||||||
|
const db = await createDatabaseAdapter(dbPath);
|
||||||
const loader = new N8nNodeLoader();
|
const loader = new N8nNodeLoader();
|
||||||
const parser = new NodeParser();
|
const parser = new NodeParser();
|
||||||
const mapper = new DocsMapper();
|
const mapper = new DocsMapper();
|
||||||
|
|||||||
Reference in New Issue
Block a user