A lightweight, file-based blog and website system designed for resource-constrained Linux environments like Raspberry Pi. No database required - all content is stored in markdown files.
====== 99% Vibe Coded ::: So no assumption should be made about security of this application. =========
- 📝 Markdown-based content management
- 🔐 Google OAuth authentication
- 🎨 Theme system with easy switching
- 📁 File-based storage (no database)
- 🔄 Automatic content indexing with file watching
- 🖥️ Admin interface for content management
- 🍓 Optimized for Raspberry Pi
- ⚡ Fast and lightweight
- Node.js v18 LTS or newer
- Linux-based system (tested on Raspberry Pi 3+)
- Google OAuth credentials
- 256MB RAM minimum
git clone [https://github.com/yourusername/markdown-blog-system.git](https://github.com/netean/Database-Free-Website-.git)
cd Database-Free-Websitenpm installCopy the example environment file and edit it with your settings:
cp .env.example .env
nano .envRequired environment variables:
GOOGLE_CLIENT_ID: Your Google OAuth client IDGOOGLE_CLIENT_SECRET: Your Google OAuth client secretGOOGLE_CALLBACK_URL: OAuth callback URL (e.g.,https://yourdomain.com/auth/google/callback)SESSION_SECRET: Random string for session encryption (generate withopenssl rand -base64 32)PORT: Server port (default: 3000)NODE_ENV: Environment mode (developmentorproduction)
- Go to Google Cloud Console
- Create a new project or select an existing one
- Enable the Google+ API
- Create OAuth 2.0 credentials:
- Application type: Web application
- Authorized redirect URIs: Add your callback URL (e.g.,
http://localhost:3000/auth/google/callback)
- Copy the Client ID and Client Secret to your
.envfile
Ensure the application has proper permissions:
# Set ownership (replace 'pi' with your username if different)
sudo chown -R pi:pi /path/to/markdown-blog-system
# Set directory permissions
chmod 755 content content/blog content/pages
chmod 755 themes themes/default
chmod 700 sessions
chmod 755 static static/admin
chmod 755 templates templates/admin
# Set file permissions
chmod 644 content/**/*.md
chmod 644 themes/**/*
chmod 644 static/**/*
chmod 644 templates/**/*The system comes with sample content. You can add your own markdown files:
# Blog posts go in content/blog/
# Format: YYYY-MM-DD-title-slug.md
echo "---
title: My First Post
date: 2025-11-13
type: blog
order: 1
published: true
---
# My First Post
Welcome to my blog!" > content/blog/2025-11-13-my-first-post.md
# Pages go in content/pages/
echo "---
title: About
type: page
published: true
---
# About
This is my about page." > content/pages/about.mdnpm startnpm run start:piThe application will be available at http://localhost:3000 (or your configured port).
- Copy the service file to systemd directory:
sudo cp markdown-blog.service /etc/systemd/system/- Edit the service file to match your setup:
sudo nano /etc/systemd/system/markdown-blog.serviceUpdate these fields:
User: Your username (default:pi)Group: Your group (default:pi)WorkingDirectory: Full path to your installationEnvironmentFile: Full path to your.envfile
- Reload systemd and enable the service:
sudo systemctl daemon-reload
sudo systemctl enable markdown-blog.service
sudo systemctl start markdown-blog.service- Check service status:
sudo systemctl status markdown-blog.service- View logs:
sudo journalctl -u markdown-blog.service -f# Start the service
sudo systemctl start markdown-blog.service
# Stop the service
sudo systemctl stop markdown-blog.service
# Restart the service
sudo systemctl restart markdown-blog.service
# Enable auto-start on boot
sudo systemctl enable markdown-blog.service
# Disable auto-start on boot
sudo systemctl disable markdown-blog.service
# View service status
sudo systemctl status markdown-blog.service
# View logs
sudo journalctl -u markdown-blog.service -n 50For production deployment with HTTPS:
- Install Nginx:
sudo apt-get update
sudo apt-get install nginx- Create Nginx configuration:
sudo nano /etc/nginx/sites-available/markdown-blogAdd this configuration:
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}- Enable the site:
sudo ln -s /etc/nginx/sites-available/markdown-blog /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx- Set up SSL with Let's Encrypt:
sudo apt-get install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com- Navigate to
http://yourdomain.com/login - Click "Sign in with Google"
- Authorize the application
- You'll be redirected to the admin dashboard
- Log in to the admin interface
- Click "Create New"
- Fill in the form:
- Title: Your content title
- Content: Markdown content
- Type: Blog or Page
- Click "Create"
- From the admin dashboard, click "Edit" next to any content item
- Modify the content
- Click "Save Changes"
- From the admin dashboard, click "Delete" next to any content item
- Confirm the deletion in the dialog
- From the admin dashboard, adjust the order numbers
- Click "Save Order"
- Navigate to Admin → Themes
- Select a theme from the available options
- Click "Activate"
You can also add/edit markdown files directly:
# Add a new blog post
nano content/blog/2025-11-13-new-post.md
# Add a new page
nano content/pages/contact.mdThe system will automatically detect changes within 5 seconds and update the index.
markdown-blog-system/
├── content/ # Markdown content files
│ ├── blog/ # Blog posts
│ └── pages/ # Static pages
├── themes/ # Theme directories
│ └── default/ # Default theme
├── templates/ # Admin interface templates
│ └── admin/
├── static/ # Static assets
│ └── admin/
├── sessions/ # Session storage (auto-created)
├── server.js # Main application entry point
├── config.js # Configuration
├── auth.js # Authentication logic
├── markdown-handler.js # Markdown processing
├── content-indexer.js # Content indexing and file watching
├── theme-manager.js # Theme management
├── security.js # Security utilities
└── .env # Environment variables (create from .env.example)
All markdown files must include front matter:
---
title: "Post Title"
date: 2025-11-13
type: blog
order: 1
published: true
tags: ["tag1", "tag2"]
------
title: "Page Title"
type: page
published: true
---- Create a new directory in
themes/:
mkdir themes/mytheme-
Create required template files:
layout.ejs- Main layoutblog-list.ejs- Blog listing pageblog-post.ejs- Individual blog postpage.ejs- Static page404.ejs- Error pagestyles.css- Theme styles
-
Create
theme.json:
{
"name": "My Theme",
"version": "1.0.0",
"templates": {
"layout": "layout.ejs",
"blogList": "blog-list.ejs",
"blogPost": "blog-post.ejs",
"page": "page.ejs",
"404": "404.ejs"
},
"styles": ["styles.css"],
"scripts": []
}- Activate via admin interface or manually edit
config/active-theme.json
Check logs:
sudo journalctl -u markdown-blog.service -n 50Common issues:
- Missing environment variables in
.env - Incorrect file permissions
- Port already in use
- Node.js not installed or wrong version
- Check file permissions on
content/directory - Verify file watching is enabled (check logs)
- Restart the service:
sudo systemctl restart markdown-blog.service
- Verify Google OAuth credentials in
.env - Check callback URL matches Google Cloud Console settings
- Ensure
SESSION_SECRETis set - Check session directory permissions (should be 700)
- Ensure you're using the
start:piscript with memory limits - Check system resources:
htop - Reduce number of active sessions
- Consider using a reverse proxy cache (Nginx)
Reset permissions:
cd /path/to/markdown-blog-system
chmod 755 content content/blog content/pages themes static templates
chmod 700 sessions
chmod 644 content/**/*.md- Use Node.js v18 LTS (best ARM optimization)
- Memory limit is set to 192MB in
start:piscript - EJS template caching is enabled in production
- File watching uses efficient chokidar (no polling)
- Session limit: 100 active sessions
- Enable Nginx caching for static assets
- Use HTTP/2 with Nginx
- Compress responses with gzip
- Minimize theme assets (CSS/JS)
- Keep content index under 1000 files for optimal performance
- Always use HTTPS in production (Let's Encrypt)
- Generate strong session secret:
openssl rand -base64 32 - Keep dependencies updated:
npm audit fix - Restrict file permissions as documented above
- Use firewall to limit access:
sudo ufw allow 80,443/tcp - Regular backups of content directory
- Monitor logs for suspicious activity
# Backup content
tar -czf backup-content-$(date +%Y%m%d).tar.gz content/
# Backup themes (if customized)
tar -czf backup-themes-$(date +%Y%m%d).tar.gz themes/
# Backup configuration
cp .env .env.backup# Restore content
tar -xzf backup-content-20251113.tar.gz
# Restore themes
tar -xzf backup-themes-20251113.tar.gz
# Restore configuration
cp .env.backup .envAdd to crontab:
crontab -eAdd this line for daily backups at 2 AM:
0 2 * * * cd /home/pi/markdown-blog-system && tar -czf /home/pi/backups/content-$(date +\%Y\%m\%d).tar.gz content/
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - See LICENSE file for details
For issues and questions:
- GitHub Issues: https://github.com/yourusername/markdown-blog-system/issues
- Documentation: https://github.com/yourusername/markdown-blog-system/wiki
Built with: