~/projects/self-hosted-ai-infrastructure/README.md
Self-Hosted AI Infrastructure Platform
Designed and deployed a private AI infrastructure platform using Ubuntu Server, Docker, Ollama, PostgreSQL, Cloudflare Tunnel, and n8n to run local AI models, automate workflows, and build intelligent business applications.
- Cloudflare Tunnel
- 1
- inbound firewall ports
- 0
- apps & services hosted
- 9+
- self-monitoring
- Live
cat architecture.flow
System Architecture
The platform follows a layered self-hosted AI architecture designed for security, scalability, and operational flexibility. External users access services through Cloudflare Tunnel, which securely connects to the private Ubuntu Server environment without exposing internal services directly to the internet.
self-hosted-ai-architecture.png

Infrastructure Layer
Ubuntu Server hosts Docker containers that isolate and manage AI services, automation workflows, databases, and supporting applications.
AI Processing Layer
Ollama provides local Large Language Model inference using Qwen and Llama models, enabling private AI processing without sending sensitive information externally.
Automation Layer
n8n acts as the workflow orchestration engine, connecting AI models, APIs, databases, and business applications.
Data Layer
PostgreSQL provides persistent storage for workflow data, AI interactions, application records, and automation history.
cat problem.md
Business Problem
Cloud-based AI platforms provide powerful capabilities but introduce challenges around privacy, operational cost, and dependency on external providers.
This project focused on designing a self-hosted AI environment capable of running local language models, managing automation workflows, securely exposing internal services, and providing a foundation for future AI-powered applications.
cat solution.md
Solution
The platform was deployed on Ubuntu Server using Docker containers, creating an isolated and maintainable environment where AI services, databases, and automation components can operate independently.
Ollama provides the AI inference layer by running Large Language Models locally instead of sending sensitive information to external AI services. Deployed models include Qwen 2.5, Qwen Vision models, and Llama models capable of document understanding, text generation, image analysis, and structured information extraction.
ls ./components
Architecture Decisions
Docker
Provides containerized deployment for AI services, databases, automation engines, and supporting applications.
Ollama
Runs local Large Language Models including Qwen and Llama models for private AI inference.
n8n
Acts as the workflow orchestration layer connecting AI models, APIs, databases, and business applications.
PostgreSQL
Provides persistent storage for AI conversations, workflow data, application records, and automation history.
Cloudflare Tunnel
Provides secure HTTPS access without exposing internal services directly to the public internet.
Ubuntu Server
Provides the underlying Linux infrastructure for hosting and managing the complete AI platform.
Gotenberg
Headless Chromium-based document conversion service — renders HTML into PDF on demand for CRFs, financial reports, and automated briefings across multiple production apps.
OCR Microservice
A FastAPI + pytesseract service for extracting text from receipts and invoices, feeding the AI expense automation pipeline.
Speech-to-Text
A local faster-whisper service transcribes voice notes for TALA and the Executive Assistant, so audio never leaves the host.
curl -s /api/infrastructure | jq .status
Live Infrastructure Monitoring
This platform monitors itself: a live status dashboard at /infrastructure groups the production containers into applications, automation and AI services, and databases, and runs a health check on each one. Services on the shared Docker network get a real HTTP probe with a timeout (n8n, OCR, Ollama, speech-to-text, PDF rendering, TALA and NCCT Reports). Services on isolated networks, such as the blog and the databases, are checked through Docker's own health state, so the portfolio never needs a route into them. A 401 from an app behind Cloudflare Access counts as healthy, because it proves the app is answering. Latency is reported per check — no third-party monitoring service, just a Next.js API route checking the same containers it's sitting next to.
It's a deliberately small piece of infrastructure, but a concrete one: open the dashboard and see actual, current status rather than a static claim about uptime.
cat security.md
Security Architecture
Instead of exposing internal applications directly through firewall ports, Cloudflare Tunnel creates an encrypted connection between the private infrastructure and external users.
This architecture reduces attack surface while allowing secure access to services such as n8n automation and portfolio applications.
Automation credentials follow the same least-privilege principle: the n8n daily-briefing workflow reaches the host through its own dedicated SSH key rather than a personal one, restricted with a forced command on the server side so that key can run exactly two whitelisted, read-only operations — nothing else, even if the credential itself were ever compromised.
Not every service runs in a container, and that's deliberate: the two highest-traffic production applications run as systemd-supervised bare processes directly on the host instead of Docker, trading container isolation for simpler logs, faster restarts, and one less layer between a source change and the running process — a call made per-service based on operational needs, not a blanket rule.
docker ps --format '{{.Names}}'
Applications Built On This Platform
This isn't a lab environment for one demo — it's the production backbone for a portfolio of real, independently-running applications.
Liquidation Tracker
A production financial operations platform (invoices, cash advances, liquidations, recurring bills) with database-driven RBAC and a daily n8n-automated operations briefing.
Project ATLAS
A separate production application plus its own demo deployment, running alongside Liquidation Tracker on the same host.
TALA
A personal work hub behind Cloudflare Access, with local speech-to-text, LLM task parsing and a staff follow-up email loop.
Executive Assistant
A Telegram assistant built from n8n workflows, Claude and a pgvector memory, delivering morning briefs, nudges and voice capture.
NCCT Reports Generator
An internal HTTP service that turns weekly program grids into regulator-ready Excel and PDF compliance reports.
Ghost Blog
A self-hosted publishing platform holding a migrated 15-year archive, and the output target for an AI-assisted publishing pipeline.
This Portfolio
The site you're on is itself hosted here, including its own live self-monitoring dashboard.
AI Expense Automation
A complete document processing pipeline built using Telegram, n8n, the OCR microservice, Ollama, PostgreSQL, and AppSheet.
n8n Daily Briefing Automation
A scheduled n8n workflow that reaches into production over a dedicated, forced-command-restricted SSH key to pull real activity and pending-work stats, then emails a summary and posts a rendered PDF to Telegram — entirely self-contained, no external server required.
cat /etc/cloudflared/config.yml
Public Access & Routing
Every public hostname is routed through a single Cloudflare Tunnel config — no inbound firewall ports opened on the host at all.
- ›n8n.melardenio.com → n8n automation
- ›myportfolio.melardenio.com → This portfolio
- ›tripticket.melardenio.com → Project ATLAS
- ›alltvliquidations.melardenio.com → Liquidation Tracker
- ›blog.melardenio.com → Ghost blog
cat package.json | jq .stack
Technology Stack
Platform
AI & Documents
Automation & Data
Engineering Skills Demonstrated
echo $EXIT_STATUS
Project Outcome
outcome.log
One self-hosted Ubuntu server now runs every application on this site, with private local AI inference, document rendering and automation shared across all of them, and nothing exposed through an open inbound port.
The platform is observable from the outside (the live dashboard and status page are public) and every automation credential on it is scoped to exactly the job it does.