359 lines
8.2 KiB
Markdown
359 lines
8.2 KiB
Markdown
# Blogging CMS
|
||
|
||
A lightweight, self-hosted blogging platform built with Go, HTML/CSS/JS, and MariaDB. Designed for digital sovereignty and easy Coolify deployment.
|
||
|
||
## Features
|
||
|
||
- ✍️ **Markdown Support** – Write posts in Markdown with live preview
|
||
- 📝 **Two Post Types** – Full blog posts or quick micro-posts
|
||
- 🏷️ **Tagging & Categories** – Organize content flexibly
|
||
- 🔍 **Full-Text Search** – Quick post discovery
|
||
- 📡 **RSS Feed** – Auto-generated feed for subscribers
|
||
- 👤 **User Management** – Multiple authors with role-based access
|
||
- 💬 **Comments** – Moderated comment system
|
||
- 🎨 **Material Design 3** – Modern, responsive UI
|
||
- 🔒 **Session-Based Auth** – Secure user authentication
|
||
- 📱 **Mobile Responsive** – Works on all devices
|
||
- 🐳 **Docker Ready** – One-command deployment on Coolify
|
||
|
||
## Architecture
|
||
|
||
```
|
||
blogging-cms/
|
||
├── main.go # Go backend with HTTP handlers & DB
|
||
├── go.mod / go.sum # Go dependencies
|
||
├── Dockerfile # Multi-stage Docker build
|
||
├── docker-compose.yml # Full stack (app + MariaDB)
|
||
├── .env.example # Configuration template
|
||
├── README.md # This file
|
||
├── .gitignore # Git configuration
|
||
├── templates/ # HTML templates
|
||
│ ├── home.html # Homepage
|
||
│ ├── post.html # Single post view
|
||
│ ├── category.html # Category listing
|
||
│ └── dashboard.html # Admin dashboard
|
||
├── static/ # Frontend assets
|
||
│ ├── css/
|
||
│ │ └── material.css # Material Design 3 stylesheet
|
||
│ └── js/
|
||
│ └── app.js # Frontend logic & API client
|
||
└── .github/
|
||
└── workflows/ # CI/CD (optional)
|
||
```
|
||
|
||
## Quick Start
|
||
|
||
### Prerequisites
|
||
|
||
- Docker & Docker Compose
|
||
- Or: Go 1.21+, MariaDB 11.0+
|
||
|
||
### With Docker (Recommended)
|
||
|
||
1. Clone the repository:
|
||
```bash
|
||
git clone https://github.com/kalvin0x8d0/blogging-cms.git
|
||
cd blogging-cms
|
||
```
|
||
|
||
2. Configure environment:
|
||
```bash
|
||
cp .env.example .env
|
||
# Edit .env with your settings
|
||
nano .env
|
||
```
|
||
|
||
3. Start the stack:
|
||
```bash
|
||
docker-compose up -d
|
||
```
|
||
|
||
4. Access the application:
|
||
- Homepage: `http://localhost:8080`
|
||
- Dashboard: `http://localhost:8080/dashboard`
|
||
|
||
### Without Docker
|
||
|
||
1. Install dependencies:
|
||
```bash
|
||
go mod download
|
||
```
|
||
|
||
2. Configure MariaDB:
|
||
```bash
|
||
# Create database and user
|
||
mysql -u root -p
|
||
CREATE DATABASE blogging_cms;
|
||
CREATE USER 'cms_user'@'localhost' IDENTIFIED BY 'secure_password';
|
||
GRANT ALL PRIVILEGES ON blogging_cms.* TO 'cms_user'@'localhost';
|
||
FLUSH PRIVILEGES;
|
||
```
|
||
|
||
3. Set environment variables:
|
||
```bash
|
||
export DB_HOST=localhost
|
||
export DB_USER=cms_user
|
||
export DB_PASSWORD=secure_password
|
||
export DB_NAME=blogging_cms
|
||
export PORT=8080
|
||
export SITE_URL=http://localhost:8080
|
||
export SESSION_KEY=generate-random-key-here
|
||
```
|
||
|
||
4. Run the application:
|
||
```bash
|
||
go run main.go
|
||
```
|
||
|
||
## Deployment on Coolify
|
||
|
||
### Prerequisites
|
||
|
||
- Coolify instance running
|
||
- Git repository (GitHub, GitLab, Gitea, etc.)
|
||
- Domain name (optional but recommended)
|
||
|
||
### Steps
|
||
|
||
1. **Create Coolify Project**
|
||
- New Project → Select "Docker Compose"
|
||
|
||
2. **Connect Repository**
|
||
- Link your Git repository with the blogging-cms code
|
||
- Point to the root directory
|
||
|
||
3. **Configure Environment**
|
||
- Add environment variables from `.env.example`:
|
||
```
|
||
DB_HOST=mariadb
|
||
DB_USER=cms_user
|
||
DB_PASSWORD=your_secure_password
|
||
DB_NAME=blogging_cms
|
||
SITE_URL=https://your-domain.com
|
||
SESSION_KEY=generate-random-key
|
||
```
|
||
|
||
4. **Deploy**
|
||
- Coolify automatically picks up `docker-compose.yml`
|
||
- Sets up MariaDB and Go application
|
||
- Configure reverse proxy (Caddy) in Coolify settings
|
||
|
||
5. **Health Checks**
|
||
- Coolify monitors `/` endpoint for health
|
||
- Application includes built-in healthcheck
|
||
|
||
## API Reference
|
||
|
||
### Authentication
|
||
|
||
**POST** `/auth/register`
|
||
```json
|
||
{
|
||
"username": "author",
|
||
"email": "author@example.com",
|
||
"password": "secure_password"
|
||
}
|
||
```
|
||
|
||
**POST** `/auth/login`
|
||
```json
|
||
{
|
||
"email": "author@example.com",
|
||
"password": "secure_password"
|
||
}
|
||
```
|
||
|
||
### Posts
|
||
|
||
**GET** `/api/posts?page=1`
|
||
- Get paginated list of published posts
|
||
|
||
**GET** `/api/posts/{id}`
|
||
- Get single post by ID
|
||
|
||
**POST** `/api/posts`
|
||
- Create new post (requires auth)
|
||
```json
|
||
{
|
||
"title": "Post Title",
|
||
"content": "# Markdown content",
|
||
"excerpt": "Brief summary",
|
||
"type": "post",
|
||
"category": "Technology",
|
||
"tags": ["go", "blogging"],
|
||
"published": false
|
||
}
|
||
```
|
||
|
||
**PUT** `/api/posts/{id}`
|
||
- Update post (requires ownership)
|
||
|
||
**DELETE** `/api/posts/{id}`
|
||
- Delete post (requires ownership)
|
||
|
||
### Comments
|
||
|
||
**POST** `/api/comments`
|
||
```json
|
||
{
|
||
"post_id": "post-uuid",
|
||
"content": "Comment text"
|
||
}
|
||
```
|
||
|
||
### Search
|
||
|
||
**GET** `/api/search?q=query`
|
||
- Full-text search across posts
|
||
|
||
### Feeds
|
||
|
||
**GET** `/feed`
|
||
- RSS feed of all published posts
|
||
|
||
## Configuration
|
||
|
||
### Environment Variables
|
||
|
||
| Variable | Description | Default |
|
||
|----------|-------------|---------|
|
||
| `DB_HOST` | Database hostname | `mariadb` |
|
||
| `DB_PORT` | Database port | `3306` |
|
||
| `DB_USER` | Database user | `cms_user` |
|
||
| `DB_PASSWORD` | Database password | Required |
|
||
| `DB_NAME` | Database name | `blogging_cms` |
|
||
| `PORT` | Application port | `8080` |
|
||
| `SITE_URL` | Public site URL | `http://localhost:8080` |
|
||
| `SESSION_KEY` | Session encryption key | `dev-session-key` |
|
||
|
||
## Development
|
||
|
||
### Local Development
|
||
|
||
```bash
|
||
# Install Go
|
||
brew install go # macOS
|
||
# or download from golang.org
|
||
|
||
# Clone repository
|
||
git clone <repo-url>
|
||
cd blogging-cms
|
||
|
||
# Install dependencies
|
||
go mod tidy
|
||
|
||
# Start MariaDB (Docker)
|
||
docker run -d \
|
||
-e MYSQL_ROOT_PASSWORD=root \
|
||
-e MYSQL_DATABASE=blogging_cms \
|
||
-p 3306:3306 \
|
||
mariadb:11.0
|
||
|
||
# Run application
|
||
go run main.go
|
||
```
|
||
|
||
### Building Docker Image
|
||
|
||
```bash
|
||
docker build -t blogging-cms:latest .
|
||
```
|
||
|
||
### Testing
|
||
|
||
```bash
|
||
# Unit tests (not yet implemented)
|
||
go test ./...
|
||
|
||
# Integration tests with docker-compose
|
||
docker-compose -f docker-compose.test.yml up
|
||
```
|
||
|
||
## Markdown Syntax
|
||
|
||
Supported Markdown features:
|
||
|
||
- **Headers**: `# H1`, `## H2`, etc.
|
||
- **Bold**: `**text**`
|
||
- **Italic**: `*text*`
|
||
- **Code**: `` `inline` `` or code blocks with triple backticks
|
||
- **Lists**: `- item` or `1. item`
|
||
- **Links**: `[text](url)`
|
||
- **Images**: ``
|
||
- **Blockquotes**: `> quote`
|
||
|
||
## Security Considerations
|
||
|
||
- Passwords are hashed (consider using bcrypt in production)
|
||
- Session tokens are encrypted
|
||
- CSRF protection via sessions
|
||
- SQL injection protection via prepared statements
|
||
- XSS protection via template escaping
|
||
- Comments are moderated before publication
|
||
|
||
### Hardening for Production
|
||
|
||
1. **Use HTTPS** – Configure in reverse proxy (Caddy)
|
||
2. **Change SESSION_KEY** – Generate secure random key
|
||
3. **Use strong DB password** – At least 32 characters
|
||
4. **Enable backups** – MariaDB volume backups
|
||
5. **Rate limiting** – Add reverse proxy rules
|
||
6. **Content Security Policy** – Configure in Dockerfile
|
||
|
||
## Performance
|
||
|
||
- Lightweight Go binary (~10MB)
|
||
- Efficient MariaDB queries with indexing
|
||
- Static asset caching
|
||
- Lazy-loaded comments
|
||
- Paginated post listings
|
||
|
||
## Troubleshooting
|
||
|
||
### Database Connection Error
|
||
```
|
||
Error: dial tcp mariadb:3306: connect: connection refused
|
||
```
|
||
Solution: Ensure MariaDB container is running and healthy
|
||
```bash
|
||
docker-compose logs mariadb
|
||
```
|
||
|
||
### Posts Not Displaying
|
||
- Check `published=true` in database
|
||
- Verify database query with: `mysql -h mariadb -u cms_user -p`
|
||
|
||
### Static Files 404
|
||
- Ensure `static/` and `templates/` directories exist
|
||
- Check file permissions: `ls -la static/`
|
||
|
||
## Contributing
|
||
|
||
1. Fork the repository
|
||
2. Create feature branch: `git checkout -b feature/name`
|
||
3. Commit changes: `git commit -m "Add feature"`
|
||
4. Push: `git push origin feature/name`
|
||
5. Create Pull Request
|
||
|
||
## License
|
||
|
||
MIT License. See LICENSE file for details.
|
||
|
||
## Acknowledgments
|
||
|
||
- Material Design 3 guidelines
|
||
- Go standard library
|
||
- Gorilla toolkit
|
||
- Docker community
|
||
|
||
## Author
|
||
|
||
**Kalvin** – Civic technologist and digital sovereignty advocate.
|
||
- GitHub: [@kalvin0x8d0](https://github.com/kalvin0x8d0)
|
||
- Fediverse: [@kalvin@social.obulou.org](https://social.obulou.org/@kalvin)
|
||
- Personal site: [obulou.org](https://obulou.org)
|
||
|
||
---
|
||
|
||
**Remember**: This is your space. Own your content. Self-host with care. ✍️
|