Build Your Own AI Automation with n8n: Self-Hosted, No-Code Agent A developer used the low-code tool n8n to build self-hosted AI-powered automation workflows, prioritizing data privacy and control. By deploying n8n with Docker Compose, PostgreSQL, and Redis, the developer created a flexible system that integrates various LLMs without relying on cloud services. The setup allows handling sensitive data securely while maintaining full control over the automation infrastructure. Automating workflows has always been a priority for me, especially for repetitive and error-prone manual processes. Recently, integrating AI capabilities into these automations offers a great opportunity for those, like me, who seek practical solutions. However, this integration often requires coding or complex API integrations. This is where "low-code/no-code" tools like n8n come into play. I used n8n to set up AI-powered agent flows on my own servers, without compromising data privacy and control. In this post, I will share my experience and explain how to do it step-by-step. A few years ago, I experimented with different automation tools, especially for simple data transfers and notification flows. But when AI capabilities became involved, I either found them too expensive or avoided cloud-based solutions due to data security concerns. Especially in a client project where we needed to set up an automation handling sensitive financial data, a self-hosted solution became inevitable. n8n offers a wide range of integrations and, thanks to Docker support, I can easily host it on my own server. For me, self-hosting is not just about cost advantage; it also means having complete control over my data. Especially when using AI agents, the question of how much of the data you send to LLMs is logged or used for training is always a concern. With an n8n setup under my control, I minimized these worries. Moreover, n8n's flexible structure gives me the freedom to add as many custom integrations or LLM providers as I want. This is a significant advantage for someone like me who enjoys testing different LLMs. ℹ️ Data Privacy PriorityEspecially when working with sensitive data, it's crucial to carefully review the data usage policies of cloud-based AI services. Self-hosted n8n offers more control in this regard, making it my preferred choice for critical workflows. The easiest way to run n8n on your own server is by using Docker Compose. I usually write the docker-compose.yml file myself for simple setups. This gives me flexibility and makes debugging easier in case of potential issues. The example below will be sufficient for a basic n8n setup. Here, I'm using PostgreSQL as the database because n8n working with SQLite can lead to issues like WAL bloat, especially under high load or unexpected shutdowns. I also added Redis for caching and queueing, which improves performance. First, create a directory on your server and place the docker-compose.yml file inside it: mkdir n8n-ai-automation cd n8n-ai-automation nano docker-compose.yml The docker-compose.yml content might look like this: version: '3.8' services: n8n: image: n8nio/n8n restart: always ports: - "5678:5678" environment: - N8N HOST=${N8N HOST:-localhost} - N8N PORT=5678 - N8N PROTOCOL=${N8N PROTOCOL:-http} - WEBHOOK URL=${WEBHOOK URL:-http://localhost:5678/} - DB TYPE=postgresdb - DB POSTGRESDB HOST=postgres - DB POSTGRESDB DATABASE=${POSTGRES DB:-n8n} - DB POSTGRESDB USER=${POSTGRES USER:-n8n} - DB POSTGRESDB PASSWORD=${POSTGRES PASSWORD:-n8n} - N8N BASIC AUTH ACTIVE=true - N8N BASIC AUTH USER=${N8N USER:-admin} - N8N BASIC AUTH PASSWORD=${N8N PASSWORD:-admin password change me} - QUEUE BULL REDIS HOST=redis - QUEUE BULL REDIS PORT=6379 - N8N METRICS ENABLED=true For monitoring metrics with tools like Prometheus volumes: - n8n data:/home/node/.n8n depends on: - postgres - redis Resource limits are important to protect against OOM killer deploy: resources: limits: memory: 2G reservations: memory: 1G postgres: image: postgres:15 restart: always environment: - POSTGRES DB=${POSTGRES DB:-n8n} - POSTGRES USER=${POSTGRES USER:-n8n} - POSTGRES PASSWORD=${POSTGRES PASSWORD:-n8n} volumes: - postgres data:/var/lib/postgresql/data deploy: resources: limits: memory: 512M reservations: memory: 256M redis: image: redis:7 restart: always volumes: - redis data:/data deploy: resources: limits: memory: 256M reservations: memory: 128M volumes: n8n data: postgres data: redis data: This file defines the n8n, PostgreSQL, and Redis services. I configure n8n's database connection information and basic authentication settings using environment variables. Don't forget to use N8N BASIC AUTH ACTIVE and the user/password variables for security. Additionally, I specified the amount of memory to be allocated to each service with limits and reservations under deploy.resources . This is critical, especially in VPS environments, to prevent excessive resource consumption and OOM-killed errors. Last month, I saw a build container for one of my side products get OOM-killed due to a sleep 360 command in its CI/CD pipeline, so defining resource limits from the start has become a habit. After saving the file, you can start the services with the docker compose up -d command: docker compose up -d Within a few minutes, you can access the n8n interface at http://localhost:5678 . If you are using a reverse proxy like Nginx , you will need to adjust the N8N HOST and N8N PROTOCOL variables accordingly. I usually set up SSL termination with Nginx and publish n8n under an address like https://automations.mysite.com . n8n's power comes from its ability to create complex workflows through a visual interface without writing code. We can set up our first AI agent flow using a scenario where an incoming email is summarized and a notification is sent to Slack. This was a simple but effective method I used in a client project to quickly triage support emails. Trigger: To start the workflow, we can use an "Email" trigger. I usually set up a "Webhook" trigger and route emails from another service e.g., Mailgun or a simple email parser I wrote to this webhook. However, n8n also has its own "IMAP Email" or "Gmail" nodes. For simplicity, let's start with a "Manual Trigger" and then connect it to a real trigger later. LLM Node: Under the "AI" category, you will find many LLM Large Language Model nodes. I usually use "OpenAI" or "Generic LLM" nodes. The "Generic LLM" node provides access to different LLMs via OpenRouter or your own custom APIs. Drag and drop this node onto the canvas. Prompt Engineering: Inside the LLM node, we will enter a System Prompt and User Prompt to instruct it to summarize the email. Prompt engineering is critical here. While using AI for production planning in a manufacturing company's ERP, I repeatedly tested how detailed and guiding the prompts needed to be. System Prompt example: You are an AI assistant that summarizes incoming customer support emails. Focus on the main issue, the customer's name if available , and any urgent requests. Keep the summary concise, maximum 3 sentences. User Prompt example: Summarize the following email: --- Subject: About the Defective Product From: Ayşe Yılmaz