--- title: "Ddmt-Blog Setup and Configuration Guide" date: 2026-05-15 description: "Step-by-step guide to deploy and configure Ddmt-Blog with Docker, environment variables, and Gitea webhooks." category: "tech" tags: ["tutorial", "docker", "gitea", "deployment"] author: "ddmt" --- ## 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: ```bash 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 1. Go to your repository Settings > Webhooks > Add Webhook 2. Set the target URL to `http://your-server:4321/api/webhook` 3. Set the secret to match your `WEBHOOK_SECRET` 4. Select "Push events" as the trigger 5. 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/`: ```markdown --- 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 page - `friends.md` + `data/friends.yaml` -- Renders Friends page with link groups ### Friends Data Format ```yaml 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 ```yaml 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 ```bash docker compose build docker compose up -d ``` ### Logs ```bash docker compose logs -f blog ``` ## Manual Deployment (Without Docker) ```bash bun install # Edit .env bun run build bun run start ``` ## Reverse Proxy (Nginx) ```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_SECRET` matches in both `.env` and Gitea - Verify the webhook URL is reachable from Gitea - Check server logs: `docker compose logs blog` **Content not appearing:** - Ensure `GIT_REPO_URL` and `GIT_DEPLOY_KEY` are 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`