How To Build Your Own AI-Powered Automation Engine In AWS (Without Paying SaaS Fees)
Tired of paying for SaaS automation tools that charge by the task? Here’s how I deployed my own AI-powered automation engine on AWS — no licensing fees, no vendor lock-in, and full control over my in
Over the past couple of years, I’ve been diving deep into automation and AI agents, exploring ways to build faster, leaner systems with fewer engineering bottlenecks. Along that journey, I came across a powerful open-source tool called n8n—a no-code/low-code workflow automation platform that makes it easy to connect APIs, databases, and services into scalable, event-driven pipelines. It's become one of my go-to tools for rapidly shipping solutions, especially in early-stage environments or when working with limited resources.
What is n8n and who is it for?
n8n is a flexible automation platform designed to streamline repetitive tasks, connect disparate systems, and help teams quickly prototype and deploy backend workflows—all with minimal code. It’s especially valuable for technical leaders and CTOs looking to reduce time-to-market without sacrificing control.
Since it’s open-source and self-hostable, n8n gives teams full ownership over their data and infrastructure while offering a developer-friendly interface to build and maintain custom automations.
Whether you're automating internal ops, syncing tools like CRMs and marketing platforms, or building customer-facing integrations, n8n offers a cost-effective, extensible foundation that scales with your business.
What are the benefits of a dedicated n8n instance?
Running your own n8n instance unlocks man key benefits. Here is sample list of benefits you get with a dedicated n8n instance.
Improved performance: You are no longer bottlenecked by other tenants or platform restrictions from n8n.
Cost Control: Avoid per-task and per-user fees. Take advantage of the pay-as-you-go pricing structured offered by AWS.
Data Security and Compliance: Data lives within your VPC and you have full control over who can access the resource.
In this article I'll go over the benefits of having a dedicated host for n8n and how to set one up on a EC2 instance in AWS.
How to deploy a simple n8n agent in AWS
I recommend using a service like Terraform to deploy cloud resources for serious projects however I am creating this from scratch to show you what goes on underneath the hood.
Create your instance
To get started, login to your AWS dashboard and head over to the EC2 service.
The instant type will depend on your organization's needs however I recommend using t3.medium due to the amount of memory, especially for workflows that deal with large amounts of data. In this demo, I will be using the t3.micro because its the cheapest.
Now create a dedicated security group only allowing SSH traffic from your IP address only (we will open up the HTTPS port later). As soon as you deploy your server with a public IP, hackers will use bots to try to break into your server, these strict security protocols will greatly reduce your chances of having your server compromised.
I will also create this in its own dedicated subnet to show you the process of getting the instance available over the public internet.
Remember to auto-assign a public IP in the beginning, this is required if you want to access your machine over the internet so you can set it up with a custom domain. I wont go into setting up domains in this tutorial however having one is required to use some of the services in n8n such as the Google APIs. Make sure that is set up first and attached to a dedicated public IP.
I highly recommend creating a dedicated key pair for your instance. This allows you to quickly and securely login remotely from your device. The ED25519 algorithm is what you'd typically use in most cases. I'm using the .pem format but you can use what ever you like. Since I am on Mac I will use .pem.
Create your public subnet.
A subnet is a logical subdivision of an IP network. It breaks large network (VPC) into smaller chunks (subnets) that can have custom network security rules attached to it. I am creating a dedicated subnet for this VPC. Make sure your CIDR block for the subnet is in range with your VPC before you continue.
Create your routing table
After creating the subnet we need to create a routing table so we can direct traffic from the internet gateway to the n8n server instance. Next, you will need to edit routes and be sure that the public internet targets the gateway from IP 0.0.0.0. Once you saved the changes, head over to the subnet association tab to link it to the subnet you created for your server.
Configure Security Group for HTTP/HTTPS
In the AWS Console, navigate to your EC2 instance’s Security Groups and able traffic to port 80, 443 and 5678. 5678 is the default port used by n8n and you need to keep that open.
SSH Into Your Server
Using your key pair
ssh -i path/to/your-key.pem ec2-user@<YOUR_SERVER_IP>
Update System Packages
Before installing anything, make sure your instance is fully up to date, This ensures you have the latest security patches and package versions.
sudo yum update -y
Create the n8n-secure/certs Directory
sudo mkdir -p /etc/n8n-secure/certs
sudo chown root:root /etc/n8n-secure/certs
sudo chmod 700 /etc/n8n-secure/certs
Generate a Self-Signed Certificate
sudo openssl req -x509 -nodes -days 365 \ -newkey rsa:2048 \ -keyout /etc/n8n-secure/certs/privkey.pem \ -out /etc/n8n-secure/certs/fullchain.pem \ -subj "/C=US/ST=State/L=City/O=YourOrg/OU=IT/CN=yourdomain.com"
-days 365: valid for one year (adjust as needed)
-subj: replace with your own organizational details
3. Secure the Key File
sudo chmod 600 /etc/n8n-secure/certs/privkey.pem
Install NGINX
sudo yum install nginx -y
Update NGINX config with the following
http {
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/nginx/certs/selfsigned.crt;
ssl_certificate_key /etc/nginx/certs/selfsigned.key;
location / {
proxy_http_version 1.1; # important
proxy_set_header Upgrade $http_upgrade; # important
proxy_set_header Connection "upgrade"; # important
proxy_pass http://n8n:5678;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For
$proxy_add_x_forwarded_for;
}
}
}
These lines are important since they enable web sockets so you don't run into the infamous "Connection Lost" error inside of n8n.
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
Start and Enable the Nginx Service
Enable Nginx to start at boot and then start the service immediately:
sudo systemctl enable nginx
sudo systemctl start nginx
Check its status:
sudo systemctl status nginx
You should see output indicating active (running).
Now that's all set and done, it's time for the last phase, which involves installing docker and n8n.
Update packages and install Docker
sudo yum update -y sudo yum install -y docker sudo systemctl enable --now docker
Add your user to the Docker group (optional)
sudo usermod -aG docker ec2-user newgrp docker
3. Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.26.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose docker-compose version
4. Create folders and files
mkdir -p ~/n8n && cd ~/n8n mkdir nginx certs
Create a docker-compose.yml file
Here's a simple example (HTTPS optional):
version: "3"
services: n8n: image: n8nio/n8n:1.80.4
container_name: n8n
restart: always ports: - "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=changeme
- N8N_PUSH_BACKEND=websocket
- N8N_EXPRESS_TRUST_PROXY=true
- N8N_PROTOCOL=https
- N8N_HOST=0.0.0.0
- N8N_PORT=5678
- WEBHOOK_URL=http://<your-public-ip>:5678/
volumes:
- n8n_data:/home/node/.n8n volumes: n8n_data:
nginx:
image: nginx:latest
ports:
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./certs:/etc/nginx/certs
depends_on:
When self-hosting n8n behind a reverse proxy like NGINX or Caddy, it's important to properly configure environment variables to ensure smooth, real-time communication and correct handling of incoming requests.
Two key variables to be aware of are
N8N_PUSH_BACKEND and N8N_EXPRESS_TRUST_PROXY.
Setting N8N_PUSH_BACKEND=websocket tells n8n to use WebSockets instead of the default Server-Sent Events (SSE) for pushing updates from the backend to the frontend.
This change enables more efficient, bi-directional communication, ideal for real-time workflow execution updates and status notifications. WebSockets reduce latency and are more scalable, especially when many users are connected or when the n8n instance is embedded within another application.
On the other hand, N8N_EXPRESS_TRUST_PROXY=true instructs n8n’s internal server to trust headers forwarded by a reverse proxy. These headers, such as X-Forwarded-Proto and X-Forwarded-For, carry crucial information about the original request like whether the client connected using HTTPS.
Without this setting, n8n may incorrectly assume it’s being accessed over HTTP or from a local address, which can break redirects, webhook URLs, and OAuth flows. Enabling this flag ensures n8n respects the actual protocol and host provided by the proxy, maintaining secure and accurate routing behavior.
Run the container
docker-compose up -d
Wait a few seconds, then open https://<your-ec2-public-ip>:5678. You should see a signup/login page the n8n.
Conclusion
If you're passionate about building smarter, more scalable systems in the cloud, follow me here on LinkedIn. I regularly share insights, real-world use cases, and practical advice for developers, architects, and tech leaders navigating the future of cloud computing. Let’s connect and keep the conversation going.