Integrating a Local Agentic RAG Chatbot with Langflow, Node, and Caddy
I recently added an Agentic RAG (Retrieval-Augmented Generation) Chatbot to this website. The twist? The entire pipeline—the LLM, the embeddings model, the vector database, and the orchestration logic—runs locally on my Windows machine. No cloud dependencies.
This post breaks down how I transitioned a prototype built in the Langflow Desktop UI into a robust, headless background service that serves my production website safely.
The Challenge: Going from Desktop App to Headless Service
Prototyping in Langflow is incredible. You can drag and drop LLM nodes, vector stores like ChromaDB, and document loaders to build a complex RAG pipeline in minutes. However, running the desktop application 24/7 as the backend for a website isn't practical. I needed:
- Headless Execution: Langflow needed to run in the background without a GUI.
- Auto-Start on Boot: It had to run as a Windows Service (since my home server runs Windows).
- Security: The API keys and endpoints needed to be hidden from the frontend.
- Rate Limiting: I needed a way to throttle requests to prevent my local GPU from being overwhelmed.
1. Isolating the Langflow Environment
The first step was extracting Langflow from the desktop application sandbox. I created a dedicated Python virtual environment (venv) and installed the Langflow package. However, Langflow relies on a SQLite database to store flow configurations and encrypted API keys.
I migrated the desktop app's SQLite database (database.db) to a local directory for my backend project. The tricky part was the Fernet encryption secret. Langflow uses a secret_key file to encrypt keys before storing them. I had to locate this key in the desktop app's AppData cache and inject it into my headless environment.
2. Running as a Windows Service with node-windows
Windows Services run under the LocalSystem account, which means they don't have access to your personal user directories like C:\Users\username\AppData. To solve this, I wrote a Node.js wrapper script (run-langflow.js) that uses child_process.spawn to start the Langflow Python process.
Crucially, this wrapper injects custom environment variables to trick Langflow into using my project folder as its home directory:
const childEnv = Object.assign({}, process.env, {
USERPROFILE: 'C:\\path\\to\\backend\\local-home',
LOCALAPPDATA: 'C:\\path\\to\\backend\\local-home\\AppData\\Local',
APPDATA: 'C:\\path\\to\\backend\\local-home\\AppData\\Roaming',
LANGFLOW_DATABASE_URL: 'sqlite:///C:\\path\\to\\backend\\local-home\\.langflow\\langflow.db',
LANGFLOW_SECRET_KEY: 'my-extracted-secret-key'
});
I then used the node-windows package to register this script as a native Windows Service (RockyLangflowService) that starts automatically on boot.
3. The Node.js Middleware Proxy
You should never expose a Langflow API endpoint directly to the web, as it requires passing your API key in the request headers from the client. Instead, I built a lightweight Express.js middleware server (server.js).
This backend does three things:
- Rate Limiting: Uses
express-rate-limitto restrict requests to 5 per minute per IP. - Authentication: Attaches the required
x-api-keyheader securely on the server side before forwarding the request to Langflow. - Response Formatting: Extracts the generated text from Langflow's deeply nested JSON response and returns it to the frontend in a standard, easy-to-parse format.
4. Tying it all together with Caddy
Finally, I configured Caddy to route traffic to the Node.js middleware. My Caddyfile routes any request hitting /chat-api/* to the Express server running on port 3001, which then talks to the Langflow service on port 7860.
The result is a fast, secure, and entirely local RAG pipeline integrated directly into the neon aesthetic of this site. If you ask the chatbot in the corner a question, you're talking directly to a model running on a GPU sitting just a few feet away from me.
Note on Context: If you try the chatbot and find its context lacking, it's because the RAG documents (like my FAQ and Website Guide) are still being actively tuned and embedded. The pipeline is live, but the knowledge base is a work in progress!
— Rakesh Ganesan
Rocky's Labs · 03 Jun 2026