Arsitektur n8n Self-Hosted di Kubernetes untuk Skala Enterprise
Bagaimana DOKU men-deploy n8n di Alibaba Cloud Container Service (ACK) menggunakan arsitektur Queue Mode, managed services, dan custom image untuk kebutuhan internal.
Di DOKU, kita menggunakan n8n sebagai workflow automation platform internal. Platform ini menangani banyak proses kritis seperti sinkronisasi data, notifikasi ke Slack/Email, hingga file transfer automation dengan pihak eksternal.
Ketika skala otomasi mulai membesar, menjalankan docker-compose up di satu VM tidak lagi cukup tangguh untuk production di finance company. Kita butuh sesuatu yang scalable, highly available, dan aman.
Artikel ini membahas arsitektur yang kita gunakan untuk men-deploy n8n secara terpusat dan self-hosted di atas Kubernetes.
Kenapa n8n?
Sebelum memilih n8n, saya mengevaluasi tiga opsi utama untuk tim internal:
| Kriteria | n8n | Airflow | Jenkins |
|---|---|---|---|
| UI visual untuk workflow | ✅ Drag & drop | ⚠️ Ada, tapi DAG-centric | ❌ Pipeline as code |
| Learning curve untuk ops | Rendah | Tinggi (Python DAG) | Sedang |
| Built-in Integration | ✅ (800+ nodes) | ❌ (Custom operator) | ⚠️ Plugin |
n8n menang di kejelasan UI. Teknisi operasi (ops) dan tim product bahkan bisa membaca alurnya tanpa harus memahami code.
Trade-off: n8n kurang cocok untuk heavy data pipeline (ETL berukuran GB). Untuk itu, Airflow atau Spark jauh lebih tepat. Tapi untuk event-driven workflow, n8n berada di zona nyamannya.
Arsitektur: Queue Mode di Kubernetes (ACK)
Kita men-deploy n8n di Alibaba Cloud Container Service for Kubernetes (ACK). Alih-alih menjalankan database di dalam cluster K8s, kita menggeser komponen stateful ke managed services (ApsaraDB).
%%{init: {'layout': 'elk'}}%%flowchart TB subgraph K8s["Kubernetes Cluster (ACK)"] NAS["NAS - PVC"] Main["n8n Main (1 pod)"] Worker["n8n Worker (HPA)"] Webhook["n8n Webhook (HPA)"] end subgraph ApsaraDB["Alibaba ApsaraDB Managed"] Redis["Redis (BullMQ)"] PG["PostgreSQL"] end NAS -- mount --> Main & Worker & Webhook Main -- dispatch jobs --> Redis Main -- SQL queries --> PG Worker -- poll jobs --> Redis Worker -- SQL queries --> PG Webhook -- enqueue --> Redis Webhook -- SQL queries --> PG Redis@{ shape: cyl} PG@{ shape: cyl} NAS:::nas Main:::pod Worker:::pod Webhook:::pod Redis:::aps PG:::aps classDef pod stroke:#818cf8,fill:#eef2ff,color:#000 classDef nas stroke:#2dd4bf,fill:#f0fdfa,color:#000 classDef aps stroke:#a78bfa,fill:#f5f3ff,color:#000 linkStyle 0 stroke:#38bdf8,fill:none linkStyle 1 stroke:#facc15,fill:none linkStyle 2 stroke:#000000,fill:none linkStyle 3 stroke:#38bdf8,stroke-width:2px,fill:none linkStyle 4 stroke:#38bdf8,fill:none linkStyle 5 stroke:#facc15,stroke-width:2px,fill:none linkStyle 6 stroke:#facc15,fill:none linkStyle 7 stroke:#000000,fill:none linkStyle 8 stroke:#000000,fill:noneKomponen Utama
Arsitektur “Queue Mode” membagi n8n menjadi beberapa tipe pod:
- Main pod (1 replica): Menjalankan UI editor, API server, dan scheduler (cron job). Pod ini tidak menjalankan workflow yang berat; ia hanya melempar pekerjaan (dispatch) ke Redis.
- Worker pods (2-6 replicas, HPA): Workhorse utama. Jika ada 100 eksekusi berjalan bersamaan, worker inilah yang menarik tugas dari Redis dan menjalankannya. Kita menggunakan Horizontal Pod Autoscaler berdasarkan memori dan CPU.
- Webhook pods (1-5 replicas, HPA): Khusus menangani incoming HTTP request. Memisahkan webhook mencegah spike traffic mengganggu responsivitas UI di Main pod.
- Managed PostgreSQL: Menyimpan credential, pengaturan workflow, dan histori eksekusi.
- Managed Redis: Bertindak sebagai message broker (BullMQ) di antara Main, Webhook, dan Worker.
- NAS (Network Attached Storage): Digunakan sebagai Persistent Volume mode
ReadWriteMany. Fungsi utamanya adalah berbagi folderbinaryDatake semua pod, memungkinkan file raksasa diproses tanpa masuk ke dalam database.
Queue Mode dalam Aksi
Insight kunci dari Queue Mode: Webhook pod tidak menunggu eksekusi selesai. Ia hanya menaruh job ke antrean dan langsung balas 200 OK, Worker yang akan ambil dan jalankan secara asinkron. Inilah yang memungkinkan kita menangani spike traffic tanpa memblokir incoming request.
sequenceDiagram participant Client participant Webhook as n8n Webhook Pod participant Redis as Redis (BullMQ) participant Worker as n8n Worker Pod participant PG as PostgreSQL participant Main as n8n Main Pod participant User
Client->>Webhook: POST /webhook/abc Webhook->>Redis: enqueue job Webhook-->>Client: 200 OK (instant ack)
Note over Redis,Worker: Decoupled, webhook<br/>tidak menunggu eksekusi
Worker->>Redis: poll job Redis-->>Worker: job payload Worker->>Worker: jalankan workflow Worker->>PG: tulis hasil eksekusi Worker->>Redis: tandai selesai
User->>Main: buka dashboard Main->>PG: baca status eksekusi Main-->>User: tampilkan historyHelm Values Configuration
Berikut adalah potongan Helm values untuk environment Production, yang mengaktifkan Queue mode dan menyambungkannya ke komponen eksternal:
# values-prod.yaml (simplified)main: extraEnv: # Aktifkan arsitektur queue EXECUTIONS_MODE: value: "queue" QUEUE_MODE: value: "redis" QUEUE_BULL_REDIS_HOST: value: "redis.example.internal"
# Koneksi Database DB_TYPE: value: "postgresdb" DB_POSTGRESDB_HOST: value: "postgres.example.internal"
# Optimasi Penyimpanan File N8N_DEFAULT_BINARY_DATA_MODE: value: "filesystem" N8N_BINARY_DATA_STORAGE_PATH: value: "/home/node/.n8n/binaryData"
# Pruning Eksekusi Lama (Krusial) EXECUTIONS_DATA_PRUNE: value: "true" EXECUTIONS_DATA_MAX_AGE: value: "72" # Hapus data eksekusi setelah 3 hari
worker: enabled: true concurrency: 10 replicaCount: 2 autoscaling: enabled: true minReplicas: 2 maxReplicas: 6
webhook: enabled: true autoscaling: enabled: true minReplicas: 1 maxReplicas: 5Tips Operasional Skala Besar
Setelah platform ini aktif di production, kami mengamati beberapa area pengelolaan yang menuntut perhatian khusus:
1. Enkripsi Credential
n8n meng-encrypt semua data sensitif (API key, password database, dll) pakai N8N_ENCRYPTION_KEY. Kalau value environment variable ini ilang, seluruh credential di n8n bakal locked dan harus di-input ulang. Di lingkungan enterprise kami nggak nyimpan ini sebagai plain text, tapi taro di secret manager kayak HashiCorp Vault, yang nanti otomatis di-inject ke Kubernetes Secret pas pod dijalanin.
flowchart LR Vault["HashiCorp Vault<br/>(master secret)"] -->|External Secrets Operator| K8sSecret["K8s Secret"] K8sSecret -->|env var| Pod["n8n Pod<br/>N8N_ENCRYPTION_KEY"] Pod -->|enkripsi at rest| PG[("PostgreSQL<br/>tabel credentials")]
classDef vault stroke:#0ea5e9,fill:#e0f2fe,color:#000 classDef k8s stroke:#818cf8,fill:#eef2ff,color:#000 classDef db stroke:#a78bfa,fill:#f5f3ff,color:#000 class Vault vault class K8sSecret,Pod k8s class PG db2. Execution Pruning
Tanpa pruning, tabel execution_entity pada database PostgreSQL dapat membengkak menjadi puluhan GB yang melambatkan eksekusi n8n secara keseluruhan. Melalui variabel EXECUTIONS_DATA_MAX_AGE=72, kami menghapus data yang lebih lama dari 3 hari. Untuk audit jangka panjang, ada node terpisah dalam workflow yang menembak log ke sistem eksternal (seperti Datadog atau ELK).
3. Lingkungan Staging dan CI/CD
Semua instalasi Helm melalui pipeline GitLab CI. Kita memisahkan tahap pengujian menjadi SIT, UAT, Sandbox, dan Production. Workflow didesain di SIT, diekspor sebagai .json, lalu diimpor secara bertahap sampai masuk ke ranah Production.
flowchart LR Dev["Draft workflow<br/>export .json lokal"] --> SIT SIT["SIT<br/>integration test"] -->|GitLab CI| UAT UAT["UAT<br/>business test"] -->|GitLab CI| SBX SBX["Sandbox<br/>prod-like, terisolasi"] -->|approve manual| PROD PROD["Production"]
classDef env stroke:#a78bfa,fill:#f5f3ff,color:#000 classDef prod stroke:#10b981,fill:#d1fae5,color:#000 classDef start stroke:#94a3b8,fill:#f1f5f9,color:#000 class Dev start class SIT,UAT,SBX env class PROD prodDalam artikel selanjutnya, saya akan membahas studi kasus utamanya: bagaimana kita menggunakan klaster n8n ini untuk mengelola dan mengotomasi proses file transfer (SFTP) dengan pihak ketiga.