VPS-এ Docker দিয়ে n8n সেটআপ করার নিয়ম
Docker Compose ও Postgres ব্যবহার করে VPS-এ n8n হোস্ট করার পূর্ণাঙ্গ গাইড। WEBHOOK_URL কনফিগারেশন, এনক্রিপশন কি এবং রিভার্স প্রক্সির মাধ্যমে HTTPS সেটআপের খুঁটিনাটি এখানে দেখুন।
আপনি যা তৈরি করছেন
n8n হলো একটি workflow automation টুল: এটি একটি ভিজ্যুয়াল এডিটর যেখানে কোনো trigger, webhook, schedule বা form submission নোডের একটি চেইন চালু করে, যা API কল করে, ডেটা পরিবর্তন করে এবং অন্যান্য সিস্টেমে লিখে রাখে। এটি AI-agent workflow-এর জন্য ডিফল্ট মাধ্যম হয়ে উঠেছে, কারণ কোনো সার্ভিস না লিখেই এটি প্রতিটি model provider এবং database-এর সাথে যোগাযোগ করতে পারে। একটি docker run ব্যবহার করে দুই মিনিটের মধ্যে একটি কার্যকর এডিটর পাওয়া যায়। এই নির্দেশিকাটি বাকি নব্বই শতাংশ কাজের জন্য: ডিফল্ট SQLite ফাইলের পরিবর্তে Postgres ব্যবহার করে এটিকে টেকসই করা, HTTPS-এর মাধ্যমে অ্যাক্সেসযোগ্য করা এবং যে বিষয়টি প্রায় সবাই ভুল করে, তা হলো—webhook-কে এমন একটি URL প্রদান করতে বাধ্য করা যা বাইরের জগত থেকে আসলেই অ্যাক্সেস করা যায়।
সম্পূর্ণ স্ট্যাকটি একটি Docker network-এ দুটি কন্টেইনার নিয়ে গঠিত: n8n নিজে এবং এর workflow ও credential সংরক্ষণকারী একটি Postgres database। হোস্টের একটি reverse proxy TLS termination সম্পন্ন করে এবং localhost-এ n8n-এর কাছে অনুরোধ পাঠায়, ফলে proxy ছাড়া অন্য কোনো কিছু সরাসরি ইন্টারনেটের মুখোমুখি হয় না। এটি 2026 self-hosting shortlist-এ থাকা অন্যান্য সার্ভিসের পাশাপাশি অবস্থান করে।
পূর্বশর্ত এবং বাস্তব সীমাবদ্ধতা
আপনার অন্তত 1 GB RAM-সমৃদ্ধ একটি VPS দরকার। Workflow বাস্তবে কাজ শুরু করলে 2 GB RAM ধরে পরিকল্পনা করুন। Execution এবং Node.js runtime মিলে মেমরি ব্যবহার করে। মাঝপথে container বন্ধ করে দেওয়া out-of-memory killer-এর মাধ্যমে এটি শেখা খুবই দুর্ভোগের বিষয়।
শুরু করার জন্য একটি vCPU যথেষ্ট। এই মেশিনে অন্য কোনো বেশি resource-নির্ভর service চালালে আগে সেই service অনুযায়ী VPS-এর আকার নির্ধারণ করুন। সাধারণত photo library-ই প্রধান কারণ। PhotoPrism এবং Immich-এর প্রকৃত RAM প্রয়োজনীয়তা n8n-এর চাহিদার তুলনায় অনেক বেশি।
Media box-এর ক্ষেত্রেও একই কথা প্রযোজ্য। Jellyfin server-এর সঙ্গে এর জন্য browsable front end, যেমন Halcyon, যা library-কে 90s-এর rental shop হিসেবে নতুন করে সাজায়, চালালে n8n-এর নজরে পড়ার অনেক আগেই RAM এবং transcoding headroom ব্যবহার হয়ে যাবে।
আপনার একটি ডোমেইন বা সাব-ডোমেইন প্রয়োজন, যেমন n8n.example.com। সার্টিফিকেট অনুরোধ করার আগেই এর একটি A record VPS-এর পাবলিক IP-কে নির্দেশ করতে হবে এবং তা সঠিকভাবে রিজলভ হতে হবে। পোর্ট 80 এবং 443 অবশ্যই প্রক্সির জন্য খোলা থাকতে হবে; n8n-এর নিজস্ব পোর্ট 5678 কখনোই ইন্টারনেটের সরাসরি মুখোমুখি থাকা উচিত নয়। আপনার Docker Engine এবং Compose plugin প্রয়োজন। যদি docker compose version কমান্ডটি চালালে docker: 'compose' is not a docker command এরর দেখায়, তবে বুঝবেন আপনি পুরনো standalone বাইনারি ব্যবহার করছেন, সেক্ষেত্রে সঠিক কমান্ডটি হলো sudo apt install docker-compose-plugin।
পরীক্ষামূলক কাজের জন্য SQLite ঠিক আছে, তবে নির্ভরযোগ্য যেকোনো কিছুর জন্য Postgres ব্যবহার করুন
n8n-এর ডিফল্ট ডাটাবেস হলো /home/node/.n8n/database.sqlite-এ থাকা একটি SQLite ফাইল। প্রাথমিক যাচাই-বাছাইয়ের জন্য এটি ঠিক আছে, তবে কোনো volume mount না করলে প্রথমবার কন্টেইনার রিক্রিয়েট করার সময়ই আপনি সব ডেটা হারাবেন, যা নিজেই একটি শিক্ষা। Postgres-এ স্থানান্তরের কারণ কেবল গতি নয়; বরং SQLite একটি সিঙ্গেল রাইটার লক ব্যবহার করে। ফলে একই সময়ে একাধিক ওয়ার্কফ্লো চালানো হলে বা আপনি যখন কিউ মোড (queue mode) ব্যবহার করতে চাইবেন, তখন কনকারেন্সির কারণে SQLITE_BUSY: database is locked এরর দেখা দেবে। Postgres-এ এই সীমাবদ্ধতা নেই, pg_dump দিয়ে এটি সহজে ব্যাকআপ নেওয়া যায় এবং n8n-এর নিজস্ব ডকুমেন্টেশনেও নির্ভরযোগ্য সার্ভারের জন্য Postgres ব্যবহারের পরামর্শ দেওয়া হয়েছে। পরবর্তীতে ডাটাবেস পরিবর্তন করতে হলে ম্যানুয়ালি ডেটা মাইগ্রেট করতে হবে, তাই এই সার্ভারটি যদি গুরুত্বপূর্ণ হয়, তবে শুরু থেকেই Postgres ব্যবহার করুন।
DNS এবং ফায়ারওয়াল
প্রথমে DNS রেকর্ড সেট করুন এবং পোর্টগুলো খুলে দিন, যাতে পরবর্তী ধাপে সার্টিফিকেটের কাজ এমন কোনো নামের জন্য ব্যর্থ না হয় যা resolve হচ্ছে না।
dig +short n8n.example.com
curl -s ifconfig.me
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow OpenSSH
sudo ufw enable5678 পোর্টটি খুলবেন না। compose ফাইলটি n8n-কে 127.0.0.1:5678-এ bind করে, ফলে শুধুমাত্র হোস্টের reverse proxy এটিতে পৌঁছাতে পারে, এবং একটি ufw allow 5678 সেই আইসোলেশন বা বিচ্ছিন্নতাকে নষ্ট করে দেবে।
Compose ফাইল
একটি ওয়ার্কিং ডিরেক্টরি এবং একটি docker-compose.yml তৈরি করুন। এটি সম্পূর্ণ স্ট্যাক, দুটি সার্ভিস, একটি প্রাইভেট নেটওয়ার্ক এবং দুটি নেমড ভলিউম নিয়ে গঠিত।
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: n8n
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: n8n
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- n8n_net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U n8n -d n8n"]
interval: 10s
timeout: 5s
retries: 5
n8n:
image: docker.n8n.io/n8nio/n8n:2.29.10
restart: unless-stopped
ports:
- "127.0.0.1:5678:5678"
environment:
- N8N_HOST=n8n.example.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.example.com/
- N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
- N8N_PROXY_HOPS=1
- GENERIC_TIMEZONE=Europe/London
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
volumes:
- n8n_data:/home/node/.n8n
networks:
- n8n_net
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:
n8n_data:
networks:
n8n_net:এখানে কিছু সিদ্ধান্ত সরাসরি উল্লেখ করা প্রয়োজন। DB_POSTGRESDB_HOST=postgres হলো সার্ভিস নেম, যা Docker শেয়ার্ড নেটওয়ার্কে রিজলভ করে, localhost নয়, যা n8n কন্টেইনারের ভেতরে n8n-কেই বোঝায়। condition: service_healthy সহ depends_on ব্যবহার করলে বুট হওয়ার সময় n8n এবং Postgres-এর মধ্যে রেসিং কন্ডিশন তৈরি হয় না; এটি ছাড়া n8n চালু হয়ে ডাটাবেস খুঁজে না পেয়ে বন্ধ হয়ে যায়। /home/node/.n8n-এ থাকা নেমড ভলিউম n8n_data এনক্রিপশন কি এবং SQLite-এর ক্ষেত্রে ডাটাবেস ধরে রাখে; এটি এমন একটি ডিরেক্টরি যা কোনোভাবেই হারানো যাবে না। ইমেজটিকে একটি নির্দিষ্ট ভার্সনের সাথে পিন করুন, কখনোই latest ব্যবহার করবেন না; এর কারণগুলো নিচের আপগ্রেড সেকশনে দেওয়া হয়েছে।
secrets ফাইল
কখনোই compose ফাইলে পাসওয়ার্ড রাখবেন না। সেগুলোকে এর পাশে একটি .env ফাইলে রাখুন যা Compose স্বয়ংক্রিয়ভাবে পড়ে নেয় এবং সেগুলোকে এমনভাবে তৈরি করুন যেন সেগুলো প্রকৃতপক্ষেই র্যান্ডম হয়।
printf 'POSTGRES_PASSWORD=%s\n' "$(openssl rand -hex 24)" > .env
printf 'N8N_ENCRYPTION_KEY=%s\n' "$(openssl rand -hex 32)" >> .env
chmod 600 .envN8N_ENCRYPTION_KEY হলো এখানকার সবচেয়ে গুরুত্বপূর্ণ স্ট্রিং, এটি সেই কী (key) যা দিয়ে প্রতিটি সংরক্ষিত ক্রেডেনশিয়াল এনক্রিপ্ট করা থাকে। n8n-কে নিজে থেকে একটি তৈরি করতে না দিয়ে বরং আপনি স্পষ্টভাবে একটি মান সেট করুন, কারণ আপনার তৈরি করা মানটি আপনি লিখে রাখতে পারবেন এবং প্রয়োজনে পুনরুদ্ধার করতে পারবেন। একবার n8n এই কী ব্যবহার করে তার প্রথম ক্রেডেনশিয়াল এনক্রিপ্ট করে ফেললে, এটি পরিবর্তন করলে প্রতিটি ক্রেডেনশিয়াল আর ডিক্রিপ্ট করা যাবে না, তাই এটি একবারই সেট করুন, এখনই, এবং এই লাইনটি আর কখনোই পরিবর্তন করবেন না।
ওয়েবহুক কাজ করবে কি না নির্ধারণকারী env var
4টি variable n8n কীভাবে বাইরের সিস্টেমের কাছে নিজেকে বর্ণনা করবে তা নিয়ন্ত্রণ করে। এগুলো ভুলভাবে সেট করা n8n support-এর সবচেয়ে সাধারণ প্রশ্ন।
N8N_HOSTহলো public hostname,n8n.example.com। Proxy-এর পেছনে এটিকে defaultlocalhostরেখে দিলে editor আপনার browser-এlocalhostথেকে নিজের API load করার চেষ্টা করে, যা ব্যর্থ হয়।N8N_PROTOCOL=httpsn8n-কে জানায় যে এটি TLS-এর মাধ্যমে পরিবেশিত হচ্ছে। তাই এটি session cookie-তেSecureচিহ্নিত করে এবংhttps://URL তৈরি করে।N8N_PORT=5678হলো container-এর ভেতরে n8n যে port-এ listen করে। এটি public port নয়; 443-এর দায়িত্ব proxy-এর।WEBHOOK_URL=https://n8n.example.com/-ই সবচেয়ে বেশি সমস্যা তৈরি করে। n8n এই মানগুলো থেকে webhook address তৈরি করে, যা আপনি Stripe, GitHub বা অন্য কোনো external caller-এ paste করেন। এটি unset বা ভুল হলে n8nN8N_HOST:N8N_PORT-এ fallback করে এবং আপনাকেhttps://n8n.example.com:5678/webhook/...অথবা আরও খারাপ ক্ষেত্রেhttp://localhost:5678/webhook/...দেয়। এগুলো কোনো error ছাড়াই প্রদর্শিত হয়, দেখতে বিশ্বাসযোগ্য হলেও Internet থেকে reach করা যায় না। ফলে caller-এর request নীরবে n8n-এ পৌঁছায় না। trailing slash-সহ exact public base URL সেট করুন। এরপর নিশ্চিত করুন যে webhook node-এ প্রদর্শিত URL-এ কোনো port নেই।
N8N_PROXY_HOPS=1 n8n-এর Express server-কে জানায় যে এর সামনে 1টি proxy রয়েছে। ফলে rate limiting এবং client IP পড়ে এমন feature-গুলো proxy-এর IP-এর বদলে প্রকৃত client address দেখতে পায়। এখানে আপনি ইচ্ছাকৃতভাবে যে variable-টি set করবেন না, সেটি হলো N8N_RUNNERS_ENABLED। Task runner হলো n8n-এর Code-node logic-কে main process থেকে আলাদা একটি process-এ isolated রেখে চালানোর ব্যবস্থা। 1.x line জুড়ে এগুলো opt-in ছিল। তখন variable-এর default ছিল false এবং আপনাকে এটি true-এ set করতে হতো। n8n 2.0-তে এগুলো default হিসেবে চালু হয়েছে। তাই 2.x line-এ এই guide অনুযায়ী variable-টি deprecated, এবং n8n-এর documentation-এ বলা হয়েছে যে এখন এটি set করার প্রয়োজন নেই।
প্রথম স্টার্ট
docker compose up -d
docker compose ps
docker compose logs -f n8nএকটি সফল প্রথম বুট Editor is now accessible via: লাইন দিয়ে শেষ হয়, যার ঠিক উপরে একটি n8n ready on ..., port 5678 লাইন থাকে। docker compose ps-এ দুটি কন্টেইনারই Up অবস্থায় থাকা উচিত এবং postgres-কে (healthy) হিসেবে চিহ্নিত থাকতে হবে। যদি n8n একটি Restarting লুপে আটকে থাকে, তবে লগগুলো পড়ুন; এটি প্রায় সবসময়ই ডাটাবেস সংযোগ বা নিচে বর্ণিত ভলিউম পারমিশনের সমস্যার কারণে হয়।
রিভার্স প্রক্সির সাথে TLS
n8n নিজে 5678 পোর্টে plain HTTP ব্যবহার করে; তাই এর সামনে HTTPS টার্মিনেশন প্রয়োজন। এর জন্য দুটি সহজ উপায় আছে।
আপনি যদি ইতিমধ্যে একাধিক কন্টেইনার চালান, তবে n8n-কে স্বয়ংক্রিয়ভাবে TLS সার্টিফিকেট ইস্যু করা Traefik রিভার্স প্রক্সির পেছনে রাখুন। কিছু লেবেল যোগ করলেই Traefik আপনার জন্য সার্টিফিকেট রিকোয়েস্ট এবং রিনিউ করবে।
যদি সার্ভারে এটিই একমাত্র অ্যাপ হয়, তবে Let's Encrypt সার্টিফিকেটসহ একটি nginx ভার্চুয়াল হোস্ট ব্যবহার করা সহজ। সার্টিফিকেট পাওয়ার জন্য Ubuntu 24.04-এর জন্য Certbot এবং nginx TLS সেটআপ অনুসরণ করুন, তারপর নিচের সার্ভার ব্লকটি ব্যবহার করুন:
server {
listen 443 ssl;
server_name n8n.example.com;
ssl_certificate /etc/letsencrypt/live/n8n.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/n8n.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600;
client_max_body_size 16m;
}
}Upgrade এবং Connection "upgrade" হেডারগুলো ঐচ্ছিক নয়। n8n ওয়েব-সকেটের মাধ্যমে এডিটরে লাইভ এক্সিকিউশন আপডেট পাঠায়, এই দুটি লাইন ছাড়া লগইন পেজ লোড হওয়ার পর সংযোগ বিচ্ছিন্ন হওয়ার বার্তা দেখাবে। proxy_read_timeout 3600 দীর্ঘ সময় ধরে চলা এক্সিকিউশনগুলোকে nginx-এর ডিফল্ট 60 সেকেন্ডের সময়সীমার কারণে বন্ধ হওয়া থেকে রক্ষা করে। X-Forwarded-Proto $scheme হেডারটি N8N_PROXY_HOPS=1-এর পরিপূরক: এটি n8n-কে জানায় যে মূল অনুরোধটি HTTPS ছিল, যদিও প্রক্সি এটিকে plain HTTP-এর মাধ্যমে পাঠিয়েছে। ফলে n8n সংযোগটিকে অনিরাপদ মনে করে নিজের কুকি প্রত্যাখ্যান করে না।
আপনার প্রথম workflow, এটিকে বাস্তবে চালানো
https://n8n.example.com/ খুলুন, owner account তৈরি করুন (পরের section দেখুন), এবং এমন ক্ষুদ্রতম workflow তৈরি করুন যা পুরো path কাজ করছে প্রমাণ করে: webhook আসবে, HTTP call হবে, response যাবে।
- একটি Webhook node যোগ করুন। method হিসেবে
POSTসেট করুন এবংhello-এর মতো একটি path দিন। এখানে দুটি URL দেখা যাবে, একটি Test URL এবং একটি Production URL। “my webhook doesn't work” ধরনের report-এর অর্ধেকের উৎস এটি। Test URL একটি call-এর উত্তর দেয়, এবং শুধু তখনই দেয় যখন আপনি Listen for test event-এ click করেছেন; এরপর এটি expire হয়ে যায়। আপনি workflow publish করলে Production URL register হয় এবং এরপর থেকে response দেয়। - এর পরে একটি HTTP Request node যোগ করুন এবং সেটিকে যেকোনো public JSON API-তে point করান।
https://api.github.com/zen-এ একটি GET করলে one-line string ফেরত আসে, যা যথেষ্ট। - একটি Respond to Webhook node যোগ করুন। এরপর Webhook node-এর Respond option হিসেবে "Using Respond to Webhook node" সেট করুন, যাতে caller HTTP node-এর output ফিরে পায়।
- উপরের ডানদিকে Publish-এ click করুন এবং call করুন:
curl -X POST https://n8n.example.com/webhook/hello। আপনার zen line ফিরে আসা উচিত—POST in, API call, response out। অধিকাংশ বাস্তব automation-এর গঠন এমনই। পুরোনো guide-গুলোতে এখানে Active toggle চালু করতে বলা হয়; n8n 2.0-এ সেই toggle-এর বদলে Publish এবং Unpublish এসেছে।
একটি scheduled variant-এ Webhook node-এর বদলে Schedule Trigger ব্যবহার করা হয় এবং তার পরিবর্তে একটি model endpoint call করা হয়। একই VPS-এ চলা Ollama-এর মতো self-hosted model ব্যবহার করে nightly summariser তৈরি করা সহজ।
ইউজার ম্যানেজমেন্ট, বেসিক অথ নয়
পুরোনো n8n guide-গুলোতে N8N_BASIC_AUTH_ACTIVE=true সেট করতে বলা হয়। n8n 1.0-এ ওই variable-গুলো সরিয়ে দেওয়া হয়েছে এবং এখন সেগুলো কোনো কাজ করে না। বর্তমানে authentication হলো owner account: প্রথমবার editor load করলে n8n আপনাকে email ও password দিয়ে একটি owner account তৈরি করতে বাধ্য করে। এই gate বাধ্যতামূলক; anonymous mode নেই। প্রথম boot-এর পরপরই এটি তৈরি করুন, অন্য কাউকে URL দেওয়ার আগে। docker compose up থেকে প্রথম form submission পর্যন্ত যে কেউ instance-এ পৌঁছাতে পারলে সেটি claim করতে পারে। এর ওপর reverse-proxy basic-auth layer যোগ করা অতিরিক্ত সুরক্ষা হিসেবে যুক্তিসংগত। তবে এটি second factor, প্রকৃত authentication নয়। Owner account এবং এই guide-এর বাকি সবকিছু free community edition-এ চলে। পরে granular role-সহ অতিরিক্ত user বা SSO দরকার হলে, পরিকল্পনা করার আগে কোন n8n feature-এর জন্য paid licence প্রয়োজন পড়ে নিন।
ব্যাকআপ: প্রথমে এনক্রিপশন কি, তারপর ডেটাবেস
দুটি জিনিসের ব্যাকআপ রাখা প্রয়োজন এবং এগুলোর গুরুত্ব সমান নয়।
N8N_ENCRYPTION_KEY। n8n-এ আপনি যে সমস্ত ক্রেডেনশিয়াল, API টোকেন, ডেটাবেস পাসওয়ার্ড এবং OAuth সিক্রেট সংরক্ষণ করেন, তার সবকিছুই এই কি (key) দিয়ে এনক্রিপ্ট করা থাকে। এটি ছাড়া Postgres-এর ওয়ার্কফ্লোগুলো অকেজো: ভিন্ন কোনো কি ব্যবহার করে নতুন সার্ভারে ডেটাবেস রিস্টোর করলে n8n কোনো ক্রেডেনশিয়ালই ডিক্রিপ্ট করতে পারবে না, এবং এটি পুনরুদ্ধারের বা রিসেট করার কোনো উপায় নেই। আপনার .env ফাইলে এই কি-টি থাকে; এটি তৈরি করার দিনই সার্ভারের বাইরে কোথাও এটি কপি করে রাখুন, পাসওয়ার্ড ম্যানেজার এন্ট্রি এর জন্য সবচেয়ে উপযুক্ত। এটিই সেই ব্যাকআপ যা প্রকৃতপক্ষে সবচেয়ে গুরুত্বপূর্ণ।
Postgres ডেটাবেস, যা ওয়ার্কফ্লো, এক্সিকিউশন হিস্ট্রি এবং এনক্রিপ্ট করা ক্রেডেনশিয়ালগুলোর জন্য প্রয়োজন:
docker compose exec -T postgres pg_dump -U n8n -d n8n \
| gzip > n8n-db-$(date +%F).sql.gzএটি একটি নির্দিষ্ট সময়সূচী অনুযায়ী চালান এবং ডাম্প ফাইলটি সার্ভারের বাইরে কপি করে রাখুন। নতুন কোনো VPS-এ রিস্টোর করতে হলে: স্ট্যাকটি একবার চালু করুন যাতে ডেটাবেস তৈরি হয়, n8n বন্ধ করুন, psql ব্যবহার করে ডাম্পটি লোড করুন, একই N8N_ENCRYPTION_KEY ফাইলটি .env-এ রাখুন এবং n8n চালু করুন। একই কি এবং ডাম্প থাকলে একটি সচল ইনস্ট্যান্স পাওয়া যাবে; নতুন কি ব্যবহার করলে ওয়ার্কফ্লোগুলো কোনো ক্রেডেনশিয়ালই ব্যবহার করতে পারবে না।
আপগ্রেড: tag নির্দিষ্ট করুন
Compose file-এ ইচ্ছাকৃতভাবে n8nio/n8n:2.29.10-এর বদলে latest নির্দিষ্ট করা হয়েছে। n8n বেশিরভাগ সপ্তাহেই একটি নতুন minor version প্রকাশ করে এবং কখনও কখনও version-গুলোর মধ্যে database schema বা node-এর আচরণ পরিবর্তন করে। তাই latest ব্যবহার করলে unattended pull শুরু হওয়ার সঙ্গে সঙ্গে আপনার database migrate করা এমন একটি build এনে দিতে পারে। একটি version নির্দিষ্ট করুন, version বাড়ানোর আগে release notes পড়ুন—n8n সেখানে breaking change-গুলো উল্লেখ করে—এবং পরিকল্পনা অনুযায়ী upgrade করুন:
docker compose exec -T postgres pg_dump -U n8n -d n8n | gzip > pre-upgrade.sql.gz
# edit the image tag in docker-compose.yml, then:
docker compose pull n8n
docker compose up -d n8n
docker compose logs -f n8nMajor-version পরিবর্তনের সময় এটি সবচেয়ে গুরুত্বপূর্ণ। উদাহরণস্বরূপ, 2.0 line ডিফল্টভাবে N8N_BLOCK_ENV_ACCESS_IN_NODE-কে true-এ পরিবর্তন করেছে। ফলে process.env পড়ে এমন যেকোনো Code node নীরবে access হারায়, যতক্ষণ না আপনি সেটিকে আবার false-এ সেট করেন। একই release settings file-এ কঠোর permission প্রয়োগ করা শুরু করেছে, ডিফল্টভাবে task runner সক্রিয় করেছে এবং workflow-এর Activate toggle-এর বদলে Publish চালু করেছে। Major boundary অতিক্রম করার আগে 2.0 breaking-changes page পড়ুন। n8n start হওয়ার সময় প্রয়োজনীয় database migration স্বয়ংক্রিয়ভাবে চালায়। এই কারণেই upgrade-এর আগে pg_dump নেওয়া ঐচ্ছিক নয়। Credentials .env-এ একটি key দিয়ে encrypted অবস্থায় থাকে এবং data Postgres-এ থাকে। তাই container-গুলো disposable: upgrade করতে container প্রতিস্থাপন করুন, আর rollback করতে আগের tag নির্দিষ্ট করে dump restore করুন।
ব্যর্থতার ধরন এবং যে বার্তাগুলো দেখবেন
The requested webhook "POST hello" is not registered. প্রকাশিত নয় এমন workflow-এর webhook কল করলে, অথবা কেউ শুনছে না এমন test path কল করলে 404 দেখা যায়। Test path (/webhook-test/...) শুধু তখনই সাড়া দেয়, যখন আপনি "Listen for test event"-এ ক্লিক করেছেন; production path (/webhook/...) শুধু workflow প্রকাশিত হওয়ার পরে সাড়া দেয়। পাশের This webhook is not registered for GET requests. Did you mean to make a POST request? বোঝায় method ভুল: nodeটি POST প্রত্যাশা করছে, কিন্তু আপনি GET পাঠিয়েছেন।
Webhook URL-এ :5678 বা localhost দেখা যাচ্ছে। Nodeটি https://n8n.example.com:5678/webhook/... বা http://localhost:5678/... দেখায়। WEBHOOK_URL সেট করা নেই বা ভুল, তাই n8n আপনার public base-এর বদলে N8N_HOST:N8N_PORT থেকে address তৈরি করেছে। WEBHOOK_URL=https://n8n.example.com/ সেট করুন, docker compose up -d দিয়ে container পুনরায় তৈরি করুন, তাহলে port আর দেখা যাবে না।
ব্রাউজারে There was a problem loading init data দেখা যাচ্ছে। Editor লোড হয়েছে, কিন্তু নিজের backend API-তে পৌঁছাতে পারছে না। Proxy-এর পেছনে এটি প্রায় সবসময় ভুল N8N_HOST বা WEBHOOK_URL, proxy-তে WebSocket-এর Upgrade header না পাঠানো, অথবা আপনি যেভাবে সংযোগ করছেন তার সঙ্গে N8N_PROTOCOL-এর অমিলের কারণে ঘটে। Public-facing চারটি variable-এর মান এবং proxy Upgrade ও Connection forward করছে কি না নিশ্চিত করুন।
Container পুনরায় চালু হতে থাকলে log-এ password authentication failed for user "n8n" দেখা যায়। n8n যে password পাঠাচ্ছে, তা database initialisation-এর সময় ব্যবহৃত password-এর সঙ্গে মেলে না। গুরুত্বপূর্ণ বিষয় হলো: Postgres POSTGRES_PASSWORD শুধু খালি data directory initialisation-এর সময় পড়ে। Stack একবার চালানোর পরে .env-এ POSTGRES_PASSWORD পরিবর্তন করলে বিদ্যমান postgres_data volume-এ পুরোনো password-ই থেকে যায়। আগের password ফিরিয়ে দিন। অথবা রাখার মতো কোনো data না থাকলে docker compose down এবং docker volume rm ব্যবহার করে postgres volume মুছে ফেলুন, তারপর নতুন করে চালু করুন।
শুরু করার সময় EACCES: permission denied, open '/home/node/.n8n/config' দেখা যায়। n8n node user (UID 1000) হিসেবে চলে এবং নিজের config directory-তে লিখতে পারে না। Host-এর এমন folder bind-mount করলে এই সমস্যা হয়, যা (./n8n_data:/home/node/.n8n) root-এর মালিকানাধীন। উপরে দেখানো named volume ব্যবহার করুন। Bind mount ব্যবহার করতেই হলে আগে sudo chown -R 1000:1000 ./n8n_data চালান।
শুরু করার সময় Permissions 0644 for n8n settings file /home/node/.n8n/config are too wide. Changing permissions to 0600.. দেখা যায়। 2.x line থেকে n8n ডিফল্টভাবে ওই settings file-এ 0600 প্রয়োগ করে এবং boot-এর সময় নিজেই তা ঠিক করে। এই log line-এর অর্থ হলো n8n ইতিমধ্যে mode সংশোধন করেছে। সাধারণত bind mount-এর পরে, অথবা restore করার সময় file-টি ঢিলেঢালা permission-সহ ফিরিয়ে আনার পরে এটি দেখা যায়। কোনো পদক্ষেপের প্রয়োজন নেই। আপনার filesystem সত্যিই permission সমর্থন না করলে তবেই N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=false সেট করুন।
Mismatching encryption keys দেখা গেলে fuller line-এ বলা থাকে যে settings file-এর encryption key /home/node/.n8n/config আপনার environment-এর N8N_ENCRYPTION_KEY-এর সঙ্গে মেলে না। Environment-এর key n8n আগের কোনো run-এ data volume-এ লিখে রাখা key-এর থেকে আলাদা। সাধারণত variable সেট না থাকায় n8n আগের boot-এ একটি random key তৈরি করে, পরে আপনি অন্য একটি key সেট করলে এই সমস্যা হয়। .env-এ আসল key ফিরিয়ে দিন। অথবা, সংরক্ষিত credential রাখার সত্যিই প্রয়োজন না থাকলে, n8n_data volume-এর ভেতরের config file মুছে n8n-কে নতুন key তৈরি করতে দিন। এতে বিদ্যমান credential আর পড়া যাবে না।
Secure cookie সম্পর্কিত login banner: Your n8n server is configured to use a secure cookie, however you are either visiting this via an insecure URL, or using Safari. আপনি N8N_PROTOCOL=https সেট করেছেন, কিন্তু plain HTTP-তে n8n-এ পৌঁছেছেন। সাধারণত HTTPS proxy ব্যবহার না করে সরাসরি IP ও port-এ গেলে এটি ঘটে। https://n8n.example.com/ ব্যবহার করে n8n-এ প্রবেশ করুন। সত্যিই HTTPS ব্যবহার করা সম্ভব না হলে তবেই N8N_SECURE_COOKIE=false সেট করুন। Internet-facing server-এ এটি কখনো সেট করবেন না।
এই workflow-গুলোর ভেতরে language model ব্যবহার করতে Claude এবং n8n দিয়ে AI workflow তৈরি করা দেখুন।
FAQ
n8n-এর জন্য SQLite নাকি Postgres ব্যবহার করব?
n8n পরীক্ষা করে দেখা এবং একসঙ্গে একটি workflow চালানো ব্যক্তিগত instance-এর জন্য SQLite (default) যথেষ্ট। যেসব কাজের ওপর আপনি নির্ভর করেন, সেগুলোর জন্য Postgres ব্যবহার করুন: concurrency হলে SQLite-এর single writer lock database is locked ঘটায়, আর Postgres-এর backup pg_dump দিয়ে পরিষ্কারভাবে নেওয়া যায়। পরে migration manual, তাই গুরুত্বপূর্ণ server হলে শুরু থেকেই Postgres ব্যবহার করুন।
n8n-এর webhook কখনো trigger হয় না কেন?
প্রায় সব ক্ষেত্রেই কারণ হলো WEBHOOK_URL। এটি unset বা ভুল হলে n8n N8N_HOST:N8N_PORT থেকে তৈরি webhook address দেখায়। এতে প্রায়ই :5678 বা localhost থাকে। Address-গুলো বৈধ মনে হলেও Internet থেকে সেগুলোতে পৌঁছানো যায় না। তাই caller-এর request কখনো server-এ আসে না। WEBHOOK_URL=https://n8n.example.com/ সেট করুন এবং নিশ্চিত করুন যে node যে URL দেখাচ্ছে, তাতে কোনো port নেই। দ্বিতীয় কারণ হলো এমন workflow-এর production URL ব্যবহার করা, যেটি আপনি publish করেননি। এতে The requested webhook ... is not registered. ফেরত আসে।
n8n-এ কী কী backup রাখতে হবে?
দুটি জিনিস। আপনার .env file-এর N8N_ENCRYPTION_KEY, কারণ সংরক্ষিত প্রতিটি credential এটি দিয়ে encrypted থাকে। এটি হারালে credential-গুলো আর কখনো decrypt করা যায় না। এটি তৈরি করার দিনই server-এর বাইরে কপি করে রাখুন। দ্বিতীয়টি হলো workflow, history এবং credential থাকা Postgres database-এর একটি pg_dump। Restore করতে দুটিই প্রয়োজন: একই key এবং dump।
n8n-কে HTTPS-এর পেছনে কীভাবে রাখব?
n8n port 5678-এ plain HTTP পরিবেশন করে। সামনে থাকা reverse proxy TLS termination করে। n8n-কে 127.0.0.1:5678-এ bind করুন, যাতে শুধু proxy এতে পৌঁছাতে পারে। এরপর automatic certificate-সহ Traefik অথবা Let's Encrypt certificate-সহ nginx ব্যবহার করুন। N8N_PROTOCOL=https এবং WEBHOOK_URL=https://your-host/ সেট করুন। Proxy যেন WebSocket-এর Upgrade header forward করে, তা নিশ্চিত করুন। তা না হলে editor সাড়া দেওয়া বন্ধ করে।
n8n নিরাপদে কীভাবে upgrade করব?
latest-এর পরিবর্তে নির্দিষ্ট image tag pin করুন। প্রথমে একটি pg_dump নিন, কারণ n8n start হওয়ার সময় স্বয়ংক্রিয়ভাবে migration চালায়। Breaking change-এর জন্য release notes পড়ুন। এরপর tag পরিবর্তন করে docker compose pull n8n && docker compose up -d n8n চালান। Container পরিবর্তনযোগ্য, তাই আগের tag pin করে এবং upgrade-এর আগের dump restore করে rollback করা যায়।