File size: 4,840 Bytes
e110d9d 320e776 e110d9d 7f99b73 e110d9d bd3ae30 caf8b68 bd3ae30 e110d9d 7f99b73 e110d9d 5f7429a 279b061 320e776 524ec79 4d69af1 320e776 f398dc5 320e776 42a7d7b e110d9d 32b834b e110d9d 7f99b73 e110d9d f398dc5 e110d9d b47e0f4 bff801f b47e0f4 38b8274 b56c910 b47e0f4 b56c910 b47e0f4 e110d9d 320e776 658dc16 e110d9d f398dc5 e110d9d f398dc5 e110d9d 5636339 bb5c703 e110d9d 320e776 7f99b73 320e776 7f99b73 320e776 e110d9d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | #!/bin/bash
set -euo pipefail
# Tighten default file permissions for any files created by this process
umask 0077
APP_DIR="/home/node/app"
N8N_HOME="/home/node/.n8n"
N8N_PORT="${N8N_PORT:-5678}"
PUBLIC_PORT="${PUBLIC_PORT:-7861}"
SYNC_INTERVAL="${SYNC_INTERVAL:-180}"
N8N_STARTUP_TIMEOUT="${N8N_STARTUP_TIMEOUT:-180}"
mkdir -p "$N8N_HOME"
SPACE_HOST_DETECTED="${SPACE_HOST_OVERRIDE:-${SPACE_HOST:-}}"
if [ -n "$SPACE_HOST_DETECTED" ]; then
export N8N_HOST="${N8N_HOST:-$SPACE_HOST_DETECTED}"
# Namespace-based Proxy Configuration (n8n at root internally)
export N8N_PATH="/"
export N8N_PROTOCOL="https"
export N8N_HOST="${SPACE_HOST_DETECTED}"
export WEBHOOK_URL="https://${SPACE_HOST_DETECTED}/"
export N8N_EDITOR_BASE_URL="https://${SPACE_HOST_DETECTED}/"
fi
export N8N_PORT
export N8N_PROTOCOL="${N8N_PROTOCOL:-https}"
export N8N_PROXY_HOPS="${N8N_PROXY_HOPS:-1}"
export N8N_LISTEN_ADDRESS="${N8N_LISTEN_ADDRESS:-0.0.0.0}"
if [ -z "${N8N_SECURE_COOKIE:-}" ]; then
if [ "${N8N_PROTOCOL}" = "https" ]; then
export N8N_SECURE_COOKIE="true"
else
export N8N_SECURE_COOKIE="false"
fi
else
export N8N_SECURE_COOKIE
fi
export N8N_DIAGNOSTICS_ENABLED="${N8N_DIAGNOSTICS_ENABLED:-false}"
export N8N_PERSONALIZATION_ENABLED="${N8N_PERSONALIZATION_ENABLED:-false}"
export N8N_USER_FOLDER="$N8N_HOME"
export N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS="${N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS:-true}"
export GENERIC_TIMEZONE="${GENERIC_TIMEZONE:-${TZ:-UTC}}"
export TZ="${TZ:-$GENERIC_TIMEZONE}"
# Disable noisy or unnecessary services
export N8N_PYTHON_NODES_ENABLED="${N8N_PYTHON_NODES_ENABLED:-false}"
export N8N_TASK_RUNNERS_ENABLED="${N8N_TASK_RUNNERS_ENABLED:-false}"
export N8N_LICENSE_AUTO_RENEW_ENABLED="${N8N_LICENSE_AUTO_RENEW_ENABLED:-false}"
export N8N_LOG_LEVEL="${N8N_LOG_LEVEL:-error}"
# n8n v2 uses built-in user management.
echo ""
echo " ββββββββββββββββββββββββββββββββββββββ"
echo " β Hugging8n β"
echo " ββββββββββββββββββββββββββββββββββββββ"
echo ""
echo "Public host : ${SPACE_HOST_DETECTED:-not detected}"
echo "n8n port : ${N8N_PORT}"
echo "Public port : ${PUBLIC_PORT}"
echo "Timezone : ${GENERIC_TIMEZONE}"
echo "Sync every : ${SYNC_INTERVAL}s"
echo "Startup wait: ${N8N_STARTUP_TIMEOUT}s"
if [ -n "${HF_TOKEN:-}" ]; then
echo "Restoring persisted n8n state from HF Dataset..."
python3 "$APP_DIR/n8n-sync.py" restore || true
else
echo "HF_TOKEN is not set. Running without dataset persistence."
fi
CLOUDFLARE_WORKERS_TOKEN="${CLOUDFLARE_WORKERS_TOKEN:-${CLOUDFLARE_API_TOKEN:-}}"
export CLOUDFLARE_WORKERS_TOKEN
CF_PROXY_ENV_FILE="/tmp/hugging8n-cloudflare-proxy.env"
if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ] || [ -n "${CLOUDFLARE_PROXY_URL:-}" ]; then
export CLOUDFLARE_PROXY_DEBUG="${CLOUDFLARE_PROXY_DEBUG:-false}"
echo "Preparing Cloudflare outbound proxy..."
python3 "$APP_DIR/cloudflare-proxy-setup.py" || true
if [ -f "$CF_PROXY_ENV_FILE" ]; then
. "$CF_PROXY_ENV_FILE"
echo " Proxy environment loaded: ${CLOUDFLARE_PROXY_URL:-none}"
fi
fi
cleanup() {
echo "Stopping Hugging8n..."
[ -n "${PROXY_PID:-}" ] && kill "$PROXY_PID" 2>/dev/null || true
# Stop the background sync loop gracefully
if [ -n "${SYNC_PID:-}" ]; then
kill "$SYNC_PID" 2>/dev/null || true
wait "$SYNC_PID" 2>/dev/null || true
fi
# Wait for n8n to finish its graceful shutdown to ensure DB state is flushed
if [ -n "${N8N_PID:-}" ]; then
kill -TERM "$N8N_PID" 2>/dev/null || true
wait "$N8N_PID" 2>/dev/null || true
fi
if [ -n "${HF_TOKEN:-}" ]; then
echo "Running final backup pass..."
python3 "$APP_DIR/n8n-sync.py" sync-once || true
fi
}
trap cleanup EXIT INT TERM
if [ -n "${HF_TOKEN:-}" ]; then
python3 "$APP_DIR/n8n-sync.py" loop &
SYNC_PID=$!
fi
node "$APP_DIR/health-server.js" &
PROXY_PID=$!
if [ -n "${CLOUDFLARE_WORKERS_TOKEN:-}" ]; then
echo "Setting up Cloudflare KeepAlive monitor..."
python3 "$APP_DIR/cloudflare-keepalive-setup.py" || true
fi
n8n start &
N8N_PID=$!
# Readiness probe
echo "Waiting for n8n to be ready on port ${N8N_PORT}..."
start_ts="$(date +%s)"
until curl -sf "http://127.0.0.1:${N8N_PORT}/healthz" > /dev/null 2>&1; do
now_ts="$(date +%s)"
elapsed="$((now_ts - start_ts))"
if [ "$elapsed" -ge "$N8N_STARTUP_TIMEOUT" ]; then
echo "n8n did not become ready within ${N8N_STARTUP_TIMEOUT}s. Exiting."
kill -TERM "$N8N_PID" 2>/dev/null || true
wait "$N8N_PID" 2>/dev/null || true
exit 1
fi
if ! kill -0 "$N8N_PID" 2>/dev/null; then
echo "n8n process exited before readiness check passed. Exiting."
exit 1
fi
sleep 1
done
echo "n8n is ready!"
wait "$N8N_PID"
|