Astro作品集博客

stefanbraum.de — Astro 作品集模板

作者 braum-me

个人作品集与博客站点源码,基于 Astro 5 SSR 与 Node 适配器,采用森林绿暗色主题,支持德语/英语双语与动态 OG 图片生成,可通过 Docker 自托管。

看看你的网站会是什么样

浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。

3 个预览视图
桌面端首页1 / 3
桌面端截图首屏预览

由服务器浏览器实际访问页面后截取。

全部页面与视图 3

截图用于了解视觉与布局,交互效果请以实际项目为准。

采集于 2026-09-30查看来源

值得关注的模板亮点

从已有项目资料中,快速了解它的特点。

01

Astro 5 SSR 搭配 @astrojs/node standalone 适配器,TypeScript 严格模式

02

Tailwind 4 森林绿暗色主题,自托管 Inter、Geist、JetBrains Mono 可变字体

03

德语默认、英语位于 /en/ 的双语 i18n,字典结构由类型约束保持一致

04

博客基于 Astro Content Collections 管理 Markdown 文章,并提供 RSS 输出

05

通过 Satori 与 @resvg/resvg-js 在 /api/og.png 动态生成 OG 图片

06

附带 Dockerfile 与 docker-compose 示例,支持 Coolify 自托管部署

模板详细介绍

该仓库是 stefanbraum.de 个人站点的完整源码,定位为作品集与博客合一的个人网站。技术栈以 Astro 5 为核心,使用 @astrojs/node 适配器以 standalone 模式运行服务端渲染,TypeScript 开启严格模式,样式由 Tailwind 4 通过 @tailwindcss/vite 提供。站点默认语言为德语(根路径 /),英语镜像位于 /en/ 下,界面文案存放于 src/i18n 的 de.ts 与 en.ts,并通过 Translations 类型强制两份字典结构一致;博客文章正文本身不区分语言,/en/blog 列表页会明确提示文章为德语。博客内容使用 Astro Content Collections 管理 Markdown 文章,另有 src/data 存放案例、技能、时间线、认证等类型化数据。视觉上采用森林绿暗色主题,自托管 Inter、Geist、JetBrains Mono 可变字体,使用 GSAP 与 ScrollTrigger 做入场动画,并以懒加载的 Three.js 实现环境着色器与技能球效果。动态 OG 图片由 Satori 配合 @resvg/resvg-js 在 /api/og.png 端点生成。代码格式与检查由 Biome 负责,包管理使用 pnpm。部署方面提供 Dockerfile,构建为非 root 的 Node 22 Alpine 镜像,standalone 服务器从环境变量读取 HOST 与 PORT,容器内默认端口 4321,无持久化状态,日志输出到 stdout,也可按 README 步骤部署到 Coolify。README 同时说明 MIT 许可仅覆盖代码与配置,博客文章、案例描述与 i18n 文案等内容版权归作者所有,若作为模板 fork 需替换自有内容。

Astro作品集博客

适合你的项目吗?

适用场景

  • 搭建个人作品集与博客合一的站点,展示案例、技能、时间线与认证信息
  • 需要德语与英语双语界面、但博客正文保持单一语言的个人网站
  • 希望以 Docker 或 Coolify 自托管 Astro SSR 站点的开发者
  • 需要动态生成社交分享 OG 图片与 RSS 订阅源的博客项目

适合人群

  • 熟悉 Astro、TypeScript 与 Tailwind 的前端开发者
  • 希望以 MIT 代码为基础、替换自有内容后发布个人站点的用户
  • 需要自托管、无持久化状态容器部署方案的个人项目

上手与定制指南

结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。

  1. 1

    使用 pnpm 安装依赖,pnpm dev 默认在 http://localhost:5556 启动开发服务器

  2. 2

    复制 .env.example 为 .env,生产环境至少需设置 PUBLIC_SITE_URL,用于 canonical、OG 与 RSS

  3. 3

    可选配置 UMAMI_SCRIPT_URL 与 UMAMI_WEBSITE_ID 接入自托管 Umami 统计

  4. 4

    Docker 镜像以非 root 的 Node 22 Alpine 运行,standalone 服务器读取 HOST 与 PORT,容器内默认端口 4321

  5. 5

    MIT 许可仅覆盖代码与配置,博客文章、案例描述与 i18n 文案等内容需替换为自有内容

查看仓库使用说明

授权与来源资料

使用条件与限制

免费使用 · 保留许可声明

本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。

使用时需要遵守

  • 允许免费使用、修改、商用和分发该版本代码。
  • 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
  • 代码按现状提供;担保与责任限制以原许可证及适用法律为准。

额外费用与待核对事项

  • MIT 许可仅覆盖代码与配置;博客文章、案例描述与 i18n 文案等内容版权归作者所有,不随代码许可授权。
  • 若将本项目作为模板 fork 使用,需将 src/content/blog/ 的博客文章、src/data/ 的案例描述以及 src/i18n/ 的文案替换为自有内容。
  • 可选接入自托管 Umami 统计,需自行提供 Umami 脚本 URL 与站点 ID;不配置则不影响站点运行。
  • 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
  • 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
查看原文依据

Permission is hereby granted, free of charge

许可证原文

Die MIT-Lizenz deckt nur Code und Konfiguration ab.

README 原文

bitte den Content (Blog-Posts in `src/content/blog/`, Case-Beschreibungen in `src/data/`, Texte in `src/i18n/`) durch eigenen ersetzen

README 原文

UMAMI_SCRIPT_URL

README 原文
https://github.com/braum-me/stefanbraum.de/blob/main/LICENSEhttps://github.com/braum-me/stefanbraum.de/blob/main/README.md

DeepSeek 根据仓库许可证和 README 整理 ·2026-10-01。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。

项目核对记录与介绍依据

模板资料

来源平台
GitHub
资料与维护参考分
资料较完整 · 85 / 100
技术栈
Astro
网站类型
作品集 · 博客
这个分数如何计算

本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。

这个项目需要核对什么

记录的仓库更新时间
2026-09-28
截图检查日期
2026-10-01

已收录演示链接。请用你的内容与屏幕尺寸检查;有演示不代表表单、认证或支付已经可用。

目录记录的主要技术栈是 Astro。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。

查看具体选型方法 →

介绍的制作与核对状态

介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。

已完成服务器许可规则与 AI 来源核对;未经过人工编辑审核。

查看当时使用的来源资料

SHA-256: e470ac906a5cbdc2e77721dca2c2fc2d7f413d02785a14db291e4b04239a6a6e

2026-10-01T13:33:33.311Z

来源文件 / 仓库
# stefanbraum.de

Personal site source. Astro 5 SSR with the Node adapter, TypeScript strict, Tailwind 4. Forest-green dark theme, two locales (`de` default, `en` under `/en/`), self-hosted blog, dynamic OG-image generation.

**Live:** [stefanbraum.de](https://stefanbraum.de)

![Preview](.github/preview.jpg)

## Stack

- [Astro 5](https://astro.build) with `@astrojs/node` (standalone mode)
- TypeScript strict (`noUnusedLocals`, `noUncheckedIndexedAccess`)
- Tailwind 4 via `@tailwindcss/vite`
- Self-hosted variable fonts (Inter, Geist, JetBrains Mono)
- [Satori](https://github.com/vercel/satori) + `@resvg/resvg-js` for dynamic OG images
- GSAP + ScrollTrigger for entry animations
- Three.js (lazy-loaded) for ambient shader and skill sphere
- Astro Content Collections for the blog (Markdown)
- [Biome](https://biomejs.dev) for format + lint
- pnpm

## Local development

```bash
pnpm install
pnpm dev          # http://localhost:5556
pnpm check        # astro check (type errors, accessibility hints)
pnpm build        # production build
pnpm lint         # biome
pnpm format       # biome format --write
```

## Project layout

```
src/
├─ components/      # Astro components (Hero, Cases, Skills, etc.)
├─ content/blog/    # Markdown posts (Astro Content Collection)
├─ data/            # Typed data (cases, skills, timeline, certifications)
├─ i18n/            # Locale dictionaries (de, en) + helpers
├─ layouts/         # BaseLayout
├─ pages/           # Route handlers
│  ├─ api/og.png.ts # Dynamic OG image endpoint
│  ├─ blog/         # Blog listing + detail
│  ├─ en/           # English mirror routes
│  └─ rss.xml.ts    # RSS feed
├─ scripts/         # Client-side animation
└─ styles/global.css
```

## Environment

Copy `.env.example` to `.env` and fill the values you need. All variables are optional except `PUBLIC_SITE_URL` for production.

| Variable           | Purpose                                            |
| ------------------ | -------------------------------------------------- |
| `PUBLIC_SITE_URL`  | Canonical site URL (used in canonical, OG, RSS)    |
| `UMAMI_SCRIPT_URL` | Self-hosted Umami script URL (analytics, optional) |
| `UMAMI_WEBSITE_ID` | Umami site ID (analytics, optional)                |

## Deploy

The included `Dockerfile` produces a non-root, production-ready Node 22 Alpine image. The standalone server reads `HOST` and `PORT` from the environment.

### Container basics

- Internal port: `4321` (Astro Node-Adapter standalone default)
- Bind host: `0.0.0.0` (set via `HOST` env)
- Healthcheck endpoint: `/` returns 200

### docker-compose

```yaml
services:
  web:
    build: .
    environment:
      HOST: 0.0.0.0
      PORT: 4321
      PUBLIC_SITE_URL: https://example.com
    ports:
      - "4321:4321"
```

### Coolify

1. New Resource → Public Repository → repository URL
2. Branch: `main`
3. Build pack: `Dockerfile` (auto-detected)
4. Port mapping: container exposes `4321`
5. Environment variables: at minimum set `PUBLIC_SITE_URL`. Coolify injects `HOST=0.0.0.0` automatically; otherwise add it explicitly
6. Deploy

The container has no persistent state. Logs go to stdout.

## Internationalization

Astro 5 native i18n.

- `de` (default) → `/`
- `en` → `/en/`

UI strings live in `src/i18n/de.ts` and `src/i18n/en.ts`. Blog post bodies are language-neutral; the listing on `/en/blog` carries an explicit notice that posts are in German.

To translate a string, edit both dictionaries. The `Translations` type in `de.ts` enforces structural parity.

## License

MIT — see [LICENSE](./LICENSE).

Inhalte (Briefings, Blog-Posts, Texte): © 2026 Stefan Braum, alle Rechte vorbehalten. Die MIT-Lizenz deckt nur Code und Konfiguration ab. Wer den Stack als Template forken will: gerne, aber bitte den Content (Blog-Posts in `src/content/blog/`, Case-Beschreibungen in `src/data/`, Texte in `src/i18n/`) durch eigenen ersetzen.
反馈内容错误

看看同类模板

对比同技术栈与用途的模板,找到更适合的视觉与内容结构。