⚡️ Aajonus.net - Static Markdown Website With Instant Full Text-Search
A brutally minimal, fully self-hosted publishing engine for text archives.
Drop .md / .txt files into a folder and you instantly get:
- Offline-first full-text search (runs in the browser, cached locally)
- A clean, fast browsing UI
- Shareable URLs + Highlighted matches
- No database, No cloud, No trackers, No CDNs
If you want something that feels like a private “Wikipedia + Spotlight search” for your own library… this is it.
Why this exists
Most “knowledge base” stacks are heavy: databases, build steps, Node pipelines, third-party search, hosted analytics, and a pile of dependencies.
This repo is the opposite:
✅ File-based (your content is just files)
✅ Privacy-native (everything stays on your server + the user’s device)
✅ Minimal surface area (Apache + PHP + vanilla JS)
✅ Fast UX (Web Worker search + IndexedDB cache)
✅ Works offline after first load (great for local networks / air-gapped setups)
Features
🔍 Search that feels instant (and stays private)
- Loads your library via
/code/loadsearch.php - Caches it in IndexedDB for 24h
- Runs queries in a Web Worker so typing stays smooth
- Shows:
- title matches
- exact text matches + context windows
- partial text matches (multi-word queries)
- Click a result → opens the page with highlighted hits + auto-scroll
🗂️ Categories without a CMS
- Folders become categories (and subcategories)
- Category bar with filtering (no reload)
🧱 Zero-bloat rendering
- Markdown is rendered server-side (Parsedown + ParsedownExtra)
- No frameworks, no build step, no external assets
🧭 SEO + sharing baked in
- Canonical URLs
sitemap.xmlauto-generated- Clean slugs based on filenames
🧩 Small but powerful extras
- “Find on Page” overlay (
findonpage.js) with next/prev match navigation - Image click-to-preview
- Optional HTTP/2 + Brotli
- Optional PHP-FPM setup for higher throughput
Quick start (the “it’s live in 3 minutes” path)
1) Install Apache + PHP
sudo apt update
sudo apt install apache2 php libapache2-mod-php -y
sudo systemctl enable --now apache2
2) Deploy the repo
Put this repo into:
/var/www/html
Your content lives in:
texts/
3) Edit config.php
Set your base URL + titles:
$baseUrl = 'https://yourdomain.com/';
$logoTitle = "YourSite";
$siteTitle = "Your Site Title";
$siteDescription = "Short description...";
4) Open the site
Visit your server IP or domain in a browser.
That’s it.
Production setup (recommended)
Enable .htaccess (pretty URLs, sitemap, HTTPS redirects, caching, etc.)
- Edit:
sudo nano /etc/apache2/apache2.conf
Find:
<Directory /var/www/>
Set:
AllowOverride All
- Enable modules + reload:
sudo a2enmod rewrite headers expires
sudo systemctl reload apache2
HTTPS (optional)
Enable HTTPS.
Let’s Encrypt (public internet)
sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
sudo systemctl restart apache2
Folder layout
/var/www/html/
├── index.php # Main application file
├── config.php # Site configuration
├── style.css # Stylesheet
├── .htaccess # Apache rewrite rules
├── code/
│ ├── Parsedown.php # Markdown parser
│ ├── ParsedownExtra.php # Extended Markdown features
│ ├── index.js # Main search & UI logic
│ ├── localsearch.js # Web Worker for search indexing
│ ├── findonpage.js # Find-in-page functionality
│ ├── findonpage.css # Find-in-page styles
│ ├── loadsearch.php # Search index generator
│ └── sitemap.php # XML sitemap generator
├── logos/
│ ├── favicon.ico
│ ├── apple-touch-icon.png
│ └── large-logo.jpg
├── imgs/ # Image assets
├── docs/ # Documents (PDFs, etc)
├── texts/ # Your Markdown content folder
│ ├── Q&A/
│ ├── Newsletters/
│ ├── Books/
│ └── ...
└── manifest.json
Content rules (simple + predictable)
Supported file types
.md(Markdown).txt(plain text)
Categories
Folders become categories:
texts/Books/We Want To Live.md
texts/Q&A/2002/2002-08-12 Something.md
texts/Newsletters/Issue 01.md
URLs / slugs
Slugs are generated from filenames:
- transliterated to ASCII
- punctuation removed
- spaces →
- - lowercased
Example:
"My Article (Final).md" → /my-article-final
If categoryInLinks = true, links include the category:
/books/my-article-final
Built-in Markdown extras
Audio / video embeds
In your .md file:
<audio controls preload="none" src="https://example.com/file.mp3"></audio>
<video controls playsinline preload="none" src="https://example.com/file.mp4"></video>
Obsidian-style image syntax
Supported:

<img src="/imgs/image.jpg" alt="image.jpg" width="600">
Also normal Markdown images work.
Permissions (recommended)
Typical safe defaults:
sudo chown -R www-data:www-data /var/www/html
# Directories: 755, Files: 644
sudo find /var/www/html -type d -exec chmod 755 {} \;
sudo find /var/www/html -type f -exec chmod 644 {} \;
Optional: Performance mode (PHP-FPM + HTTP/2)
If you’re serving a big library or high traffic, this boosts concurrency.
sudo apt install php8.3-fpm php8.3-xml php8.3-mbstring -y
sudo systemctl enable --now php8.3-fpm
sudo a2dismod php8.3
sudo a2enmod proxy_fcgi
sudo a2enconf php8.3-fpm
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo a2enmod http2
sudo systemctl restart apache2
Increase PHP-FPM capacity:
sudo nano /etc/php/8.3/fpm/pool.d/www.conf
# pm.max_children = 25
sudo systemctl restart php8.3-fpm
Enable Brotli:
sudo a2enmod brotli
sudo systemctl restart apache2
Optional: Server safety checklist
Limit journal growth:
sudo nano /etc/systemd/journald.conf
# SystemMaxUse=200M
sudo systemctl restart systemd-journald
Fail2ban:
sudo apt install fail2ban -y
sudo systemctl enable --now fail2ban
Apache fingerprint reduction:
sudo nano /etc/apache2/conf-available/security.conf
# ServerSignature Off
# ServerTokens Prod
sudo systemctl restart apache2
SEO checklist
- Set your domain in
robots.txt - Set
name+short_nameinmanifest.json - Confirm
sitemap.xmlis reachable - Confirm canonical URLs match your real domain (
$baseUrl)
Troubleshooting
“My .htaccess does nothing”
You probably need:
AllowOverride Allin/etc/apache2/apache2.confsudo a2enmod rewritesudo systemctl reload apache2
Search stuck on “Loading…”
Check that /code/loadsearch.php is reachable and not blocked by permissions.
URLs not resolving
Make sure .htaccess is enabled and Apache can read the repo directory.
Philosophy
This project is intentionally:
- boring (infrastructure you don’t have to babysit)
- portable (copy files, done)
- private (no third parties at runtime)
- fast (client-side search + worker + caching)
- minimal (the code is the feature)
License
MIT License. Free to use, modify, and distribute.
Credits
- Parsedown / ParsedownExtra for Markdown rendering (included locally)
If you build something cool with it
Fork it, remix it, strip it down even further — this repo is meant to be a base layer, not a platform.