Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/moritzrinow/coreblog
Super simple blog engine using S3. No database required.
https://github.com/moritzrinow/coreblog
blazor blog blog-engine blogs cms s3
Last synced: about 2 months ago
JSON representation
Super simple blog engine using S3. No database required.
- Host: GitHub
- URL: https://github.com/moritzrinow/coreblog
- Owner: moritzrinow
- License: mit
- Created: 2024-10-29T16:01:53.000Z (2 months ago)
- Default Branch: master
- Last Pushed: 2024-11-25T15:59:51.000Z (about 2 months ago)
- Last Synced: 2024-11-25T16:43:15.258Z (about 2 months ago)
- Topics: blazor, blog, blog-engine, blogs, cms, s3
- Language: C#
- Homepage: https://coreblog-demo.moritzrinow.com
- Size: 865 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGE.md
- License: LICENSE
Awesome Lists containing this project
README
# CoreBlog
CoreBlog is a super simple blog engine, that does not require a database.
All you need is an S3 bucket.Demo: https://coreblog-demo.moritzrinow.com
- ✅ Multiple themes including dark and white modes
- ✅ Supports multiple languages including `en`, `de`, `es`, `it`, `fr`, `uk`, `ru`
- ✅ SEO friendly
- ✅ Low resource requirements (100MiB RAM)
- ✅ No database required
- ✅ Multiple fonts available
- ✅ Allows embedding assets in posts
- ✅ Docker image
- ✅ Mobile friendly
- ❌ Sadly no custom UI to edit the blog yet (planned for the future)
- See [Manage your blog with Terraform](#manage-your-blog-with-terraform)
- ❌ No real-time blog/post updates (data is pulled in intervals)---
- [Configuration](#configuration)
- [Install with Docker](#install-with-docker)
- [S3 bucket layout and file formats](#s3-bucket-layout-and-file-formats)
- [Blog manifest (`blog.json`)](#blog-manifest-blogjson)
- [Post manifest (`post-id.json`)](#post-manifest-post-idjson)
- [Embedding images (assets)](#embedding-images-assets)
- [Manage your blog with Terraform](#manage-your-blog-with-terraform)---
## Configuration
`coreblog.yaml`:
```yaml
s3:
endpoint: 'https://fsn1.your-objectstorage.com'
region: 'fsn1'
bucketName: 'my-blog' # Required, should be private
assetBucketName: 'my-blog-assets' # Optional, must be publicly accessible
accessKey: 'HDY...'
secretKey: 'r78...'
syncPeriodMinutes: 60 # Every hour blog and post metadata is pulled from S3
postContentCacheTtlMinutes: 60 # Post content is cached in-memory
```---
## Install with Docker
Create a `coreblog.yaml` file with your configurations.
Run the docker container:
```text
docker run -p 5000:5000 -v /my/coreblog.yaml:/coreblog/coreblog.yaml devmojo/coreblog
```You can specify a different path for the config file:
```text
docker run devmojo/coreblog --config /path/to/config.yaml
```Or specify everything with environment variables:
- CB_S3__Endpoint
- CB_S3__Region
- CB_S3__BucketName
- CB_S3__AssetBucketName
- CB_S3__AccessKey
- CB_S3__SecretKey
- CB_SyncPeriodMinutes
- CB_PostContentCacheTtlMinutes---
## S3 bucket layout and file formats
```text
blog.json
posts/
post-1.json
post-1.md
post-2.json
post-2.md
```The S3 bucket stores 3 different kind of files:
- 1 blog manifest file (`blog.json`)
- Contains metadata about the blog
- N post manifest files (`posts/post-id.json`)
- Contains metadata about a post
- N post content files (`posts/post-id.md`)
- Contains the post content written in Markdown### Blog manifest (`blog.json`):
```json5
{
"title": "CoreBlog Demo",
"author": "CoreBlog",
"description": "Welcome to the CoreBlog demo!",
"homepage": "https://github.com/moritzrinow/coreblog",
// Your personal homepage
"theme": "standard",
"language": "en",
// Controls language of UI elements
"fontFamily": "Roboto Mono",
"additionalPageMeta": {
// You can use this to perform things like Google site verifications
}
}
```If the property `homepage` is specified, a link named 'About Me' will be displayed in the header.
Supported themes:
- `material`
- `material-dark`
- `standard`
- `standard-dark` (used in demo)
- `default`
- `dark`
- `humanistic`
- `humanistic-dark`
- `software`
- `software-dark`Supported fonts:
- `Roboto Mono`
- `Roboto`
- `sans-serif`Supported languages:
- `en` (English)
- `de` (German)
- `es` (Spanish)
- `it` (Italian)
- `fr` (French)
- `uk` (Ukrainian)
- `ru` (Russian)If you want to display a **favicon**, you have to put a file named `favicon.ico` in the asset bucket.
### Post manifest (`post-id.json`):
```json5
{
"id": "example-1",
// URL slug, must be same as file prefix
"title": "How to host your own managed Kubernetes cluster in the cloud",
"language": "en",
// Language of the actual content
"summary": "In this post I will show you how to host your own Kubernetes cluster in the cloud.",
"published": true,
"hidden": false,
// Can be used to have unlisted posts
"date": "2024-11-21",
"thumbnail": "welcome.jpg",
// Image stored in asset bucket
"tags": [
"kubernetes",
"cloud"
]
}
```### Embedding images (assets)
If you want to make use of static assets, such as images, an optional second S3 bucket comes into play.
It **must** be publicly accessible to serve the assets directly.
To include assets in your blog-post Markdown, use relative links prefixed with `assets/`:
```markdown
The following is an image from my assets bucket:
[My Image](assets/my-image.png)
```Links starting with `assets/` will be rewritten to point to the S3 asset-bucket directly.
---
## Manage your blog with Terraform
Since your whole blog consists of simple files stored in S3, we can make use of the
[AWS Terraform Provider](https://registry.terraform.io/providers/hashicorp/aws/latest) to streamline the management
of our blog.You can use your IDE of choice to edit your Markdown/JSON files and let Terraform sync that with S3.
Same goes for the assets.Your Terraform module structure:
```text
main.tf
blog.tf
blog-posts/
post-1.json
post-1.md
post-2.json
post-2.md
blog-assets/
favicon.ico
```Example provider configuration for [S3 on Hetzner](https://docs.hetzner.com/storage/object-storage/overview):
```terraform
// Provider requirements...provider "aws" {
region = local.s3_region
access_key = var.s3_access_key
secret_key = var.s3_secret_key
skip_region_validation = true
skip_requesting_account_id = true
skip_metadata_api_check = true
skip_credentials_validation = true
endpoints {
s3 = "https://fsn1.your-objectstorage.com"
}
}
````blog.tf`:
```terraform
// Main bucket
resource "aws_s3_bucket" "blog" {
bucket = "my-blog"
}// Asset bucket
resource "aws_s3_bucket" "blog_assets" {
bucket = "my-blog-assets"
}// ACL to allow public-read access to asset bucket
resource "aws_s3_bucket_acl" "blog_assets" {
bucket = aws_s3_bucket.blog.id
acl = "public-read"
}// Our blog manifest (blog.json)
resource "aws_s3_object" "blog_manifest" {
bucket = aws_s3_bucket.blog.bucket
key = "blog.json"
content = jsonencode({
title = "CoreBlog Demo"
author = "CoreBlog"
description = "Welcome to the CoreBlog demo!"
homepage = "https://github.com/moritzrinow/coreblog"
theme = "standard-dark"
language = "en"
fontFamily = "Roboto Mono"
additionalPageMeta = {}
})
}// Post manifest files
resource "aws_s3_object" "blog_posts_manifest" {
for_each = fileset("${path.module}/blog-posts", "*.json")
bucket = aws_s3_bucket.blog.bucket
key = "posts/${each.value}"
source = "${path.module}/blog-posts/${each.value}"
etag = filemd5("${path.module}/blog-posts/${each.value}")
}// Post content files
resource "aws_s3_object" "blog_posts_content" {
for_each = fileset("${path.module}/blog-posts", "*.md")
bucket = aws_s3_bucket.blog.bucket
key = "posts/${each.value}"
source = "${path.module}/blog-posts/${each.value}"
etag = filemd5("${path.module}/blog-posts/${each.value}")
}// Blog assets
resource "aws_s3_object" "blog_assets" {
for_each = fileset("${path.module}/blog-assets", "*")
bucket = aws_s3_bucket.blog_assets.bucket
key = each.value
source = "${path.module}/blog-assets/${each.value}"
etag = filemd5("${path.module}/blog-assets/${each.value}")
}```
If you modify or add files in the specified directories, Terraform will ensure the specific changes are synced with S3.