first commit, mate!
This commit is contained in:
@@ -0,0 +1,358 @@
|
||||
# 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. ✍️
|
||||
Reference in New Issue
Block a user