Moonglade
Blog system of https://edi.wang, runs on Microsoft Azure
Install / Use
/learn @EdiWang/MoongladeREADME
🌙 Moonglade Blog
Moonglade is a personal blogging platform built for developers, optimized for seamless deployment on Microsoft Azure. It features essential blogging tools: posts, comments, categories, tags, archives, and pages.
🚀 Deployment
This blogging system must not be used to serve users in mainland China or to publish content prohibited by Chinese law or any applicable regulations.
- Stable Code: Always use the Release branch. Avoid deploying from
master. - Security: Enable HTTPS and HTTP/2 on your web server for optimal security and performance.
- Deployment Options: While Azure is recommended, Moonglade can run on any cloud provider or on-premises.
Quick Azure Deploy (App Service on Linux)
Get started in 10 minutes with minimal Azure resources using our automated deployment script.
Quick Local Deploy (Docker)
For local testing or small-scale use, deploy Moonglade using Docker:
docker compose up -d
Full Azure Deployment
This mirrors how edi.wang is deployed, utilizing a variety of Azure services for maximum speed and security. No automated script is provided—manual resource creation is required.
🛠️ Development
| Tools | Alternatives | |----------------------------|----------------------------------------------------------------------------------------------------| | Visual Studio 2026 | VS Code + .NET 10.0 SDK | | SQL Server 2025 | LocalDB, PostgreSQL, or MySQL |
Database Setup
Tip: SQL Server Express (free) is sufficient for most production uses.
| Database | Example Connection String (appsettings.json > ConnectionStrings > MoongladeDatabase) |
|------------------|----------------------------------------------------------------------------------------------|
| SQL Server | Server=(local);Database=moonglade;Trusted_Connection=True; |
| MySQL | Server=localhost;Port=3306;Database=moonglade;Uid=root;Pwd=***; |
| PostgreSQL | User ID=***;Password=***;Host=localhost;Port=5432;Database=moonglade;Pooling=true; |
Change ConnectionStrings:DatabaseProvider in appsettings.json to match your database type.`
- SQL Server:
SqlServer - MySQL:
MySql - PostgreSQL:
PostgreSql
Build & Run
- Build and run
./src/Moonglade.sln - Access your blog:
- Home:
https://localhost:10210 - Admin:
https://localhost:10210/admin- Default username:
admin - Default password:
admin123
- Default username:
- Home:
⚙️ Configuration
Most settings are managed in
appsettings.json. For blog settings, use the/admin/settingsUI.
Authentication
- By default: Local accounts (manage via
/admin/settings/account) - Microsoft Entra ID (Azure AD) supported. Setup guide
Captcha Shared Key
Please update the default key in appsettings.json:
"CaptchaSettings": {
"SharedKey": "<your value>"
}
To generate a shared key, please see this document
Image Storage
Configure the ImageStorage section in appsettings.json to choose where blog images are stored.
Azure Blob Storage (Recommended)
Create an Azure Blob Storage container with appropriate permissions:
{
"Provider": "azurestorage",
"AzureStorageSettings": {
"ConnectionString": "YOUR_CONNECTION_STRING",
"ContainerName": "YOUR_CONTAINER_NAME"
}
}
- Enable CDN in admin settings for faster image delivery.
File System (Not recommended)
Windows:
{
"Provider": "filesystem",
"FileSystemPath": "C:\\UploadedImages"
}
Linux:
{
"Provider": "filesystem",
"FileSystemPath": "/app/images"
}
When using the file system, ensure the path exists and has appropriate permissions. If the path does not exist, Moonglade will attempt to create it.
Leave the FileSystemPath empty to use the default path (~/home/moonglade/images on Linux or %UserProfile%\moonglade\images on Windows).
Comment Moderation
Local Moderation Provider
For basic keyword filtering, use the built-in local provider:
"ContentModerator": {
"Provider": "Local",
"LocalKeywords": "fuck|shit",
"ApiEndpoint": "",
"ApiKey": ""
}
Remote Content Moderator
e.g. Moonglade.ContentSecurity Azure Function:
"ContentModerator": {
"Provider": "remote",
"ApiEndpoint": "<Your Azure Function Endpoint>",
"ApiKey": "<Your Azure Function Key>",
"ApiKeyHeader": "x-functions-key"
}
Note: You can also implement your own content moderation API by mimicking the interface of Moonglade.ContentSecurity. You are not limited to Azure!
Email Notifications
For notifications on new comments, replies and webmentions, use Moonglade.Email Azure Function:
"Email": {
"ApiEndpoint": "",
"ApiKey": ""
}
Enable notifications in the admin portal.
More Settings
📡 Protocols & Standards
| Name | Feature | Status | Endpoint |
|--------------|---------------|-------------|-----------------|
| RSS | Subscription | Supported | /rss |
| Atom | Subscription | Supported | /atom |
| OPML | Subscription | Supported | /opml |
| Open Search | Search | Supported | /opensearch |
| FOAF | Social | Supported | /foaf.xml |
| Webmention | Social | Supported | /webmention |
| Reader View | Reader Mode | Supported | N/A |
| u-card | SEO | Supported | N/A |
| IndexNow | SEO | Supported | N/A |
| Dublin Core | SEO | Basic | N/A |
| RSD | Discovery | Deprecated | N/A |
| MetaWeblog | Blogging | Deprecated | N/A |
| Pingback | Social | Deprecated | N/A |
Health Check
To ensure your Moonglade instance is running, you can use the health check endpoint:
GET /health
This endpoint returns a simple JSON response indicating the status of your Moonglade instance.
Related Skills
tmux
338.7kRemote-control tmux sessions for interactive CLIs by sending keystrokes and scraping pane output.
claude-opus-4-5-migration
83.6kMigrate prompts and code from Claude Sonnet 4.0, Sonnet 4.5, or Opus 4.1 to Opus 4.5
terraform-provider-genesyscloud
Terraform Provider Genesyscloud
blogwatcher
338.7kMonitor blogs and RSS/Atom feeds for updates using the blogwatcher CLI.
