Ddmt-Blog Setup and Configuration Guide
Prerequisites
- A Gitea instance (or any Git host with webhook support)
- Docker and Docker Compose (recommended), or Bun installed locally
- An SSH deploy key with read access to your content repository
Quick Start with Docker
The fastest way to get running:
git clone https://github.com/ddmt/Ddmt-Blog.git
cd Ddmt-Blog
cp .env.example .env
# Edit .env with your configuration
docker compose up -d
The blog will be available at http://localhost:4321.
Environment Variables
All configuration is done through environment variables in the .env file.
Site Settings
| Variable | Default | Description |
|---|---|---|
SITE_URL | http://0.0.0.0:4321 | Public URL of your blog |
SITE_TITLE | My Blog | Blog title shown in header |
SITE_DESCRIPTION | A blog powered by Bun + Astro | Default meta description |
SITE_AUTHOR | ddmt | Default author name |
SITE_LOCALE | zh-CN | HTML lang attribute |
Webhook Settings
| Variable | Default | Description |
|---|---|---|
WEBHOOK_SECRET | change-me-in-production | Secret for Gitea webhook signature verification |
Git Sync Settings
| Variable | Default | Description |
|---|---|---|
GIT_REPO_URL | (empty) | SSH URL of your content repository. Leave empty to disable auto-sync. |
GIT_DEPLOY_KEY | (empty) | SSH private key for repository access. Leave empty to disable auto-sync. |
Server Settings
| Variable | Default | Description |
|---|---|---|
PORT | 4321 | Port the Bun server listens on |
Gitea Webhook Configuration
- Go to your repository Settings > Webhooks > Add Webhook
- Set the target URL to
http://your-server:4321/api/webhook - Set the secret to match your
WEBHOOK_SECRET - Select “Push events” as the trigger
- Content type:
application/json
The webhook will trigger a pull and rebuild on every push.
Content Structure
All content lives in the content/ directory:
content/
posts/2026/05/my-article.md # Blog posts
pages/about.md # Template pages
data/friends.yaml # Structured data
data/site.json # Auto-generated site info
assets/images/ # Static images
Writing a Post
Create a Markdown file in content/posts/yyyy/mm/:
---
title: "My New Post"
date: 2026-05-15
description: "A short description for SEO."
category: "tech"
tags: ["tutorial", "web"]
cover: "/assets/images/cover.jpg"
pinned: false
draft: false
---
Your content here...
Frontmatter Fields
| Field | Required | Description |
|---|---|---|
title | Yes | Post title |
date | Yes | Publication date |
description | No | Short description for meta tags |
category | No | Post category (default: “uncategorized”) |
tags | No | Array of tags |
cover | No | Cover image URL |
pinned | No | Pin to top of homepage |
draft | No | Exclude from build |
Template Pages
Pages use content from content/pages/ and optional data from content/data/:
about.md— Renders the About pagefriends.md+data/friends.yaml— Renders Friends page with link groups
Friends Data Format
groups:
- title: "Blogroll"
links:
- name: "Example Blog"
avatar: "https://example.com/avatar.png"
description: "A great blog about things"
url: "https://example.com"
Docker Deployment
Dockerfile
The Dockerfile copies the project (excluding dist/, content/, and dev files), installs git, and starts the server. Content is synced and built at startup.
Docker Compose
services:
blog:
build: .
ports:
- "4321:4321"
env_file: .env
volumes:
- blog-content:/app/content
restart: unless-stopped
The content/ volume persists your blog content across container restarts. On first start, if GIT_REPO_URL is configured, the container will clone the repository automatically.
Building and Running
docker compose build
docker compose up -d
Logs
docker compose logs -f blog
Manual Deployment (Without Docker)
bun install
# Edit .env
bun run build
bun run start
Reverse Proxy (Nginx)
server {
listen 80;
server_name blog.example.com;
location / {
proxy_pass http://127.0.0.1:4321;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Troubleshooting
Webhook not triggering rebuilds:
- Check that
WEBHOOK_SECRETmatches in both.envand Gitea - Verify the webhook URL is reachable from Gitea
- Check server logs:
docker compose logs blog
Content not appearing:
- Ensure
GIT_REPO_URLandGIT_DEPLOY_KEYare set correctly - Check that the deploy key has read access to the repository
- Verify the content directory structure matches the expected layout
Search not working:
- Pagefind indexes are built at build time
- Rebuild after adding new content:
bun run build