{"id":15002494,"url":"https://github.com/ediwang/moonglade","last_synced_at":"2026-03-12T07:03:10.194Z","repository":{"id":34471429,"uuid":"168287048","full_name":"EdiWang/Moonglade","owner":"EdiWang","description":"Blog system of https://edi.wang, runs on Microsoft Azure","archived":false,"fork":false,"pushed_at":"2025-04-02T13:11:50.000Z","size":27424,"stargazers_count":531,"open_issues_count":2,"forks_count":139,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-04-06T06:01:36.646Z","etag":null,"topics":["aspnet-core","azure","azure-app-service","azure-blob-storage","azure-sql-database","blog","entity-framework-core","entra-id","sql-server"],"latest_commit_sha":null,"homepage":"https://edi.wang","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EdiWang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-01-30T05:51:33.000Z","updated_at":"2025-04-02T13:03:48.000Z","dependencies_parsed_at":"2023-10-23T05:20:22.074Z","dependency_job_id":"c1ce7b5c-c596-411b-aa70-09bc4f0162ad","html_url":"https://github.com/EdiWang/Moonglade","commit_stats":{"total_commits":6821,"total_committers":19,"mean_commits":359.0,"dds":0.03591848702536282,"last_synced_commit":"d0bfbbb47d8a94771236f8b642670df8e6d54e5b"},"previous_names":[],"tags_count":58,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EdiWang%2FMoonglade","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EdiWang%2FMoonglade/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EdiWang%2FMoonglade/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EdiWang%2FMoonglade/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EdiWang","download_url":"https://codeload.github.com/EdiWang/Moonglade/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248695318,"owners_count":21146952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aspnet-core","azure","azure-app-service","azure-blob-storage","azure-sql-database","blog","entity-framework-core","entra-id","sql-server"],"created_at":"2024-09-24T18:50:47.119Z","updated_at":"2026-02-12T05:20:53.866Z","avatar_url":"https://github.com/EdiWang.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🌙 Moonglade Blog\n\n**Moonglade** is a personal blogging platform built for developers, optimized for seamless deployment on [**Microsoft Azure**](https://azure.microsoft.com/en-us/). It features essential blogging tools: posts, comments, categories, tags, archives, and pages.\n\n## 🚀 Deployment\n\n\u003e 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.\n\n- **Stable Code:** Always use the [Release](https://github.com/EdiWang/Moonglade/releases) branch. Avoid deploying from `master`.\n- **Security:** Enable **HTTPS** and **HTTP/2** on your web server for optimal security and performance.\n- **Deployment Options:** While Azure is recommended, Moonglade can run on any cloud provider or on-premises.\n\n### Quick Azure Deploy (App Service on Linux)\n\nGet started in 10 minutes with minimal Azure resources using our [automated deployment script](https://github.com/EdiWang/Moonglade/wiki/Quick-Deploy-on-Azure).\n\n### Quick Local Deploy (Docker)\n\nFor local testing or small-scale use, deploy Moonglade using Docker:\n\n```bash\ndocker compose up -d\n```\n\n### Full Azure Deployment\n\nThis mirrors how [edi.wang](https://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.\n\n![Azure Architecture](https://cdn.edi.wang/web-assets/ediwang-azure-arch-visio-oct2024.svg)\n\n## 🛠️ Development\n\n| Tools                      | Alternatives                                                                                       |\n|----------------------------|----------------------------------------------------------------------------------------------------|\n| [Visual Studio 2026](https://visualstudio.microsoft.com/) | [VS Code](https://code.visualstudio.com/) + [.NET 10.0 SDK](http://dot.net)           |\n| [SQL Server 2025](https://www.microsoft.com/en-us/sql-server/) | [LocalDB](https://learn.microsoft.com/en-us/sql/database-engine/configure-windows/sql-server-express-localdb?view=sql-server-ver16\u0026WT.mc_id=AZ-MVP-5002809), PostgreSQL, or MySQL |\n\n### Database Setup\n\n\u003e **Tip:** SQL Server Express (free) is sufficient for most production uses.\n\n| Database         | Example Connection String (`appsettings.json \u003e ConnectionStrings \u003e MoongladeDatabase`)         |\n|------------------|----------------------------------------------------------------------------------------------|\n| SQL Server       | `Server=(local);Database=moonglade;Trusted_Connection=True;`                                  |\n| MySQL            | `Server=localhost;Port=3306;Database=moonglade;Uid=root;Pwd=***;`                             |\n| PostgreSQL       | `User ID=***;Password=***;Host=localhost;Port=5432;Database=moonglade;Pooling=true;`          |\n\nChange `ConnectionStrings:DatabaseProvider` in `appsettings.json` to match your database type.` \n\n- SQL Server: `SqlServer`\n- MySQL: `MySql`\n- PostgreSQL: `PostgreSql`\n\n### Build \u0026 Run\n\n1. Build and run `./src/Moonglade.sln`\n2. Access your blog:\n    - **Home:** `https://localhost:10210`\n    - **Admin:** `https://localhost:10210/admin`\n      - Default username: `admin`\n      - Default password: `admin123`\n\n## ⚙️ Configuration\n\n\u003e Most settings are managed in `appsettings.json`. For blog settings, use the `/admin/settings` UI.\n\n### Authentication\n\n- By default: Local accounts (manage via `/admin/settings/account`)\n- **Microsoft Entra ID** (Azure AD) supported. [Setup guide](https://github.com/EdiWang/Moonglade/wiki/Use-Microsoft-Entra-ID-Authentication)\n\n### Captcha Shared Key\n\nPlease update the default key in `appsettings.json`:\n\n```json\n\"CaptchaSettings\": {\n  \"SharedKey\": \"\u003cyour value\u003e\"\n}\n```\n\nTo generate a shared key, please see [this document](https://github.com/EdiWang/Edi.Captcha.AspNetCore?tab=readme-ov-file#shared-key-stateless-captcha-recommended-for-scalable-applications-without-dpapi)\n\n### Image Storage\n\nConfigure the `ImageStorage` section in `appsettings.json` to choose where blog images are stored.\n\n#### **Azure Blob Storage** (Recommended)\n\nCreate an [Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/blobs/) container with appropriate permissions:\n\n```json\n{\n  \"Provider\": \"azurestorage\",\n  \"AzureStorageSettings\": {\n    \"ConnectionString\": \"YOUR_CONNECTION_STRING\",\n    \"ContainerName\": \"YOUR_CONTAINER_NAME\"\n  }\n}\n```\n- Enable CDN in admin settings for faster image delivery.\n\n#### **File System** (Not recommended)\n\nWindows:\n```json\n{\n  \"Provider\": \"filesystem\",\n  \"FileSystemPath\": \"C:\\\\UploadedImages\"\n}\n```\nLinux:\n```json\n{\n  \"Provider\": \"filesystem\",\n  \"FileSystemPath\": \"/app/images\"\n}\n```\n\nWhen using the file system, ensure the path exists and has appropriate permissions. If the path does not exist, Moonglade will attempt to create it. \n\nLeave the `FileSystemPath` empty to use the default path (`~/home/moonglade/images` on Linux or `%UserProfile%\\moonglade\\images` on Windows).\n\n### Comment Moderation\n\n#### Local Moderation Provider\n\nFor basic keyword filtering, use the built-in local provider:\n\n```json\n\"ContentModerator\": {\n  \"Provider\": \"Local\",\n  \"LocalKeywords\": \"fuck|shit\",\n  \"ApiEndpoint\": \"\",\n  \"ApiKey\": \"\"\n}\n```\n\n#### Remote Content Moderator\n\ne.g. [Moonglade.ContentSecurity Azure Function](https://github.com/EdiWang/Moonglade.ContentSecurity):\n\n```json\n\"ContentModerator\": {\n  \"Provider\": \"remote\",\n  \"ApiEndpoint\": \"\u003cYour Azure Function Endpoint\u003e\",\n  \"ApiKey\": \"\u003cYour Azure Function Key\u003e\",\n  \"ApiKeyHeader\": \"x-functions-key\"\n}\n```\n\nNote: You can also implement your own content moderation API by mimicking the interface of Moonglade.ContentSecurity. You are not limited to Azure!\n\n### Email Notifications\n\nFor notifications on new comments, replies and webmentions, use [Moonglade.Email Azure Function](https://github.com/EdiWang/Moonglade.Email):\n\n```json\n\"Email\": {\n  \"ApiEndpoint\": \"\",\n  \"ApiKey\": \"\"\n}\n```\nEnable notifications in the admin portal.\n\n### More Settings\n\n- [System Settings](https://github.com/EdiWang/Moonglade/wiki/System-Settings)\n- [Security HTTP Headers](https://github.com/EdiWang/Moonglade/wiki/Security-Headers)\n\n## 📡 Protocols \u0026 Standards\n\n| Name         | Feature       | Status      | Endpoint        |\n|--------------|---------------|-------------|-----------------|\n| RSS          | Subscription  | Supported   | `/rss`          |\n| Atom         | Subscription  | Supported   | `/atom`         |\n| OPML         | Subscription  | Supported   | `/opml`         |\n| Open Search  | Search        | Supported   | `/opensearch`   |\n| Pingback     | Social        | Deprecated  | N/A             |\n| Webmention   | Social        | Supported   | `/webmention`   |\n| Reader View  | Reader Mode   | Supported   | N/A             |\n| FOAF         | Social        | Supported   | `/foaf.xml`     |\n| IndexNow     | SEO           | Supported   | N/A             |\n| RSD          | Discovery     | Deprecated  | N/A             |\n| MetaWeblog   | Blogging      | Deprecated  | N/A             |\n| Dublin Core  | SEO           | Basic       | N/A             |\n\n## Health Check\n\nTo ensure your Moonglade instance is running, you can use the health check endpoint:\n\n```\nGET /health\n```\n\nThis endpoint returns a simple JSON response indicating the status of your Moonglade instance.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fediwang%2Fmoonglade","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fediwang%2Fmoonglade","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fediwang%2Fmoonglade/lists"}