File size: 2,505 Bytes
daf8333
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
afac3e2
 
 
 
b8cc449
 
 
 
 
 
 
daf8333
4c7eeb6
daf8333
 
b0d48d5
daf8333
 
933cfdd
daf8333
 
b8cc449
daf8333
 
 
 
 
 
 
 
 
 
 
 
b0d48d5
daf8333
f34bdbb
b8cc449
daf8333
 
 
 
 
b8cc449
 
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
# ==============================================================================
# Dockerfile – n8n on Hugging Face Spaces
#
# Solves:
#   1. "Command not found" β†’ uses node:22-alpine base (has /bin/sh + bash)
#   2. "Permissions too wide" β†’ start.sh fixes perms before dropping to uid 1000
#   3. Port 7860            β†’ HF Spaces requirement
#   4. Persistence          β†’ /data/.n8n backed by HF persistent storage
#   5. Node >= 22.16        β†’ required by n8n >= 2.15 and isolated-vm >= 6.1
# ==============================================================================

# --------------- Stage 1: Build (includes native compilation toolchain) -------
FROM node:22-alpine AS build

# Install native build dependencies for isolated-vm and other C++ addons
RUN apk add --no-cache \
    python3 \
    make \
    g++

# Install n8n globally (semver installed explicitly to avoid module resolution
# issues when running via su-exec in the runtime stage)
RUN npm install -g semver n8n@latest --omit=dev && \
    npm cache clean --force

# --------------- Stage 2: Runtime (lean, no build toolchain) ------------------
FROM node:22-alpine

# Runtime-only dependencies
RUN apk add --no-cache \
    su-exec \
    tini \
    bash \
    curl \
    git \
    openssh-client \
    ca-certificates \
    tzdata

# Copy the globally-installed n8n from the build stage
COPY --from=build /usr/local/lib/node_modules /usr/local/lib/node_modules

# Re-link the n8n binary from source (the copied symlink may be broken)
RUN ln -sf /usr/local/lib/node_modules/n8n/bin/n8n /usr/local/bin/n8n

# Note: node:22-alpine already provides user "node" at uid/gid 1000.
# No addgroup/adduser needed β€” start.sh uses su-exec 1000:1000.

# ---------- Environment -------------------------------------------------------
# NODE_PATH tells Node where to find globally-installed modules (fixes
# "Cannot find module 'semver/functions/satisfies'" at runtime)
ENV NODE_PATH=/usr/local/lib/node_modules \
    N8N_PORT=7860 \
    N8N_PROTOCOL=https \
    N8N_USER_FOLDER=/data/.n8n \
    N8N_DIAGNOSTICS_ENABLED=false \
    N8N_HIRING_BANNER_ENABLED=false \
    N8N_PERSONALIZATION_ENABLED=false \
    NODE_ENV=production \
    GENERIC_TIMEZONE=UTC

# Expose the HF-required port
EXPOSE 7860

# ---------- Entrypoint --------------------------------------------------------
COPY start.sh /start.sh
RUN chmod +x /start.sh

# Use tini as PID 1 to reap zombies and forward signals
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/start.sh"]