n8n / scripts /entrypoint.sh
subham
Sync local n8n deployment: refactor to single Dockerfile, add runners, sandbox, cleanup legacy compose/nginx
4c98a98
Raw History Blame Contribute Delete
6.31 kB
#!/bin/sh
# entrypoint.sh — single-container HF Space bootstrap (Alpine)
set -eu
log() { echo "[entrypoint] $*"; }
warn() { echo "[entrypoint][WARN] $*" >&2; }
err() { echo "[entrypoint][ERROR] $*" >&2; }
# Load .env if present (local dev); HF Space Secrets come as env already
if [ -f /app/.env ]; then
log "Loading /app/.env"
set -a; . /app/.env; set +a
fi
if [ -f .env ]; then
log "Loading ./.env"
set -a; . ./.env; set +a
fi
# Defaults — HF expects 7860
export N8N_PORT=${N8N_PORT:-7860}
export N8N_LISTEN_ADDRESS=${N8N_LISTEN_ADDRESS:-0.0.0.0}
export N8N_PORT N8N_LISTEN_ADDRESS
export DB_TYPE=${DB_TYPE:-postgresdb}
export DB_POSTGRESDB_HOST=${DB_POSTGRESDB_HOST:-127.0.0.1}
export DB_POSTGRESDB_PORT=${DB_POSTGRESDB_PORT:-5432}
export DB_POSTGRESDB_DATABASE=${DB_POSTGRESDB_DATABASE:-n8n}
export DB_POSTGRESDB_USER=${DB_POSTGRESDB_USER:-n8n}
export PGDATA=${PGDATA:-/data/postgres}
export N8N_USER_FOLDER=${N8N_USER_FOLDER:-/data/n8n}
export N8N_RUNNERS_ENABLED=${N8N_RUNNERS_ENABLED:-true}
export N8N_RUNNERS_MODE=${N8N_RUNNERS_MODE:-external}
export N8N_RUNNERS_BROKER_PORT=${N8N_RUNNERS_BROKER_PORT:-5679}
export N8N_RUNNERS_BROKER_LISTEN_ADDRESS=${N8N_RUNNERS_BROKER_LISTEN_ADDRESS:-0.0.0.0}
export N8N_RUNNERS_TASK_BROKER_URI=${N8N_RUNNERS_TASK_BROKER_URI:-http://127.0.0.1:5679}
export N8N_RUNNERS_AUTH_TOKEN=${N8N_RUNNERS_AUTH_TOKEN:-}
export N8N_RUNNERS_TASK_TIMEOUT=${N8N_RUNNERS_TASK_TIMEOUT:-300}
export N8N_INSTANCE_AI_SANDBOX_ENABLED=${N8N_INSTANCE_AI_SANDBOX_ENABLED:-true}
export N8N_INSTANCE_AI_SANDBOX_PROVIDER=${N8N_INSTANCE_AI_SANDBOX_PROVIDER:-n8n-sandbox}
export N8N_SANDBOX_SERVICE_URL=${N8N_SANDBOX_SERVICE_URL:-http://127.0.0.1:8080}
export GENERIC_TIMEZONE=${GENERIC_TIMEZONE:-Asia/Kolkata}
# Secrets persistence: /data/.env.secrets (survives bucket mount, else ephemeral)
SECRETS_FILE="/data/.env.secrets"
mkdir -p /data/postgres /data/n8n /data/sandbox /var/log/supervisor /var/run/postgresql 2>/dev/null || true
chmod 777 /data 2>/dev/null || true
chown postgres:postgres /var/run/postgresql 2>/dev/null || true
gen_secret() { cat /dev/urandom 2>/dev/null | tr -dc 'a-f0-9' | head -c 64 || openssl rand -hex 32 2>/dev/null || head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n' | head -c 64; }
if [ ! -f "$SECRETS_FILE" ]; then
log "Generating $SECRETS_FILE"
{
echo "# auto-generated $(date -u) — persists on /data bucket, else ephemeral"
echo "N8N_ENCRYPTION_KEY=$(gen_secret)"
echo "DB_POSTGRESDB_PASSWORD=$(gen_secret | cut -c1-32)"
echo "N8N_RUNNERS_AUTH_TOKEN=$(gen_secret)"
echo "N8N_USER_MANAGEMENT_JWT_SECRET=$(gen_secret)"
echo "SANDBOX_API_KEYS=$(gen_secret | cut -c1-32)"
} > "$SECRETS_FILE"
chmod 600 "$SECRETS_FILE"
fi
# Load secrets file, but do not override already-exported env (HF Secrets win)
set -a
# shellcheck disable=SC1090
while IFS='=' read -r k v; do
case "$k" in \#*|"") continue;; esac
# only set if not already set
if eval "[ -z \"\${$k:-}\" ]"; then
# strip possible quotes
v=$(printf "%s" "$v" | sed "s/^['\"]//;s/['\"]$//")
export "$k=$v"
fi
done < "$SECRETS_FILE"
set +a
# Export DB password from file if not set
if [ -z "${DB_POSTGRESDB_PASSWORD:-}" ]; then
DB_POSTGRESDB_PASSWORD=$(grep '^DB_POSTGRESDB_PASSWORD=' "$SECRETS_FILE" | cut -d= -f2-)
export DB_POSTGRESDB_PASSWORD
fi
if [ -z "${N8N_ENCRYPTION_KEY:-}" ]; then
N8N_ENCRYPTION_KEY=$(grep '^N8N_ENCRYPTION_KEY=' "$SECRETS_FILE" | cut -d= -f2-)
export N8N_ENCRYPTION_KEY
fi
if [ -z "${SANDBOX_API_KEYS:-}" ]; then
SANDBOX_API_KEYS=$(grep '^SANDBOX_API_KEYS=' "$SECRETS_FILE" | cut -d= -f2-)
export SANDBOX_API_KEYS
fi
export N8N_SANDBOX_SERVICE_API_KEY=${N8N_SANDBOX_SERVICE_API_KEY:-$SANDBOX_API_KEYS}
export SANDBOX_API_KEYS N8N_SANDBOX_SERVICE_API_KEY
# Also persist PGDATA ownership (fast, avoid chown -R on large /opt/runners)
chown postgres:postgres "$PGDATA" 2>/dev/null || true
chown node:node /home/node 2>/dev/null || true
chown runner:runner /home/runner 2>/dev/null || true
mkdir -p /data/n8n && chown node:node /data/n8n 2>/dev/null || true
# Init postgres if needed (only if POSTGRES_ENABLED != false and PG_VERSION missing)
if [ "${POSTGRES_ENABLED:-true}" != "false" ] && [ ! -f "$PGDATA/PG_VERSION" ]; then
log "Initializing postgres PGDATA=$PGDATA"
# ensure directory owned
chown postgres:postgres "$PGDATA"
# initdb as postgres user via su-exec
su-exec postgres initdb -D "$PGDATA" -U postgres --no-locale --encoding=UTF8 2>&1 | tail -20
# allow md5 + trust for local
cat >> "$PGDATA/pg_hba.conf" <<EOF
host all all 127.0.0.1/32 md5
host all all ::1/128 md5
EOF
# tune for low RAM HF
cat >> "$PGDATA/postgresql.conf" <<EOF
listen_addresses = '127.0.0.1'
port = 5432
max_connections = 40
shared_buffers = 128MB
effective_cache_size = 256MB
maintenance_work_mem = 64MB
checkpoint_completion_target = 0.9
wal_buffers = 4MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 100
work_mem = 4MB
min_wal_size = 80MB
max_wal_size = 256MB
EOF
log "Postgres initialized"
else
log "Postgres PGDATA exists or disabled, skipping initdb"
fi
log "N8N_VERSION=${N8N_VERSION:-unknown} N8N_PORT=$N8N_PORT DB=$DB_POSTGRESDB_HOST:$DB_POSTGRESDB_PORT/$DB_POSTGRESDB_DATABASE"
log "Runner broker $N8N_RUNNERS_BROKER_LISTEN_ADDRESS:$N8N_RUNNERS_BROKER_PORT mode=$N8N_RUNNERS_MODE"
log "Sandbox $N8N_INSTANCE_AI_SANDBOX_PROVIDER enabled=$N8N_INSTANCE_AI_SANDBOX_ENABLED url=$N8N_SANDBOX_SERVICE_URL (no Daytona)"
# Ensure N8N_USER_FOLDER exists
mkdir -p "$N8N_USER_FOLDER" 2>/dev/null || true
chown node:node "$N8N_USER_FOLDER" 2>/dev/null || true
# Export all for supervisord child processes (supervisord inherits env)
export N8N_PORT N8N_LISTEN_ADDRESS DB_TYPE DB_POSTGRESDB_HOST DB_POSTGRESDB_PORT DB_POSTGRESDB_DATABASE DB_POSTGRESDB_USER DB_POSTGRESDB_PASSWORD
export PGDATA N8N_USER_FOLDER N8N_ENCRYPTION_KEY N8N_RUNNERS_ENABLED N8N_RUNNERS_MODE N8N_RUNNERS_TASK_BROKER_URI N8N_RUNNERS_BROKER_PORT N8N_RUNNERS_BROKER_LISTEN_ADDRESS N8N_RUNNERS_AUTH_TOKEN N8N_RUNNERS_TASK_TIMEOUT
export N8N_INSTANCE_AI_SANDBOX_ENABLED N8N_INSTANCE_AI_SANDBOX_PROVIDER N8N_SANDBOX_SERVICE_URL N8N_SANDBOX_SERVICE_API_KEY SANDBOX_API_KEYS
export GENERIC_TIMEZONE
log "Starting supervisord"
exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf