关于 how-to-run-astro-ssr-and-pocketbase-on-the-same-server
这篇技能指南介绍如何在同一服务器上运行 Astro SSR 与 PocketBase,面向构建动态网站的开发者。示例通过 Go 和 Echo 将未由 PocketBase 处理的请求代理到 Astro。
主要功能
- 01配置 PocketBase 与 Echo
- 02设置 Astro Node SSR
- 03从集合读取记录
- 04创建列表与详情路由
- 05构建并部署到同一实例
适用场景
- 01为 Astro 页面提供 PocketBase 数据
- 02在单台服务器部署 API 与 SSR 网站
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ rodydavis/ skills --skill how-to-run-astro-ssr-and-pocketbase-on-the-same-server安装后在 Claude Code 中输入/how-to-run-astro-ssr-and-pocketbase-on-the-same-server确认已加载。
详细介绍
如何在同一台服务器上运行 Astro SSR 和 PocketBase
本文将介绍如何在同一台服务器上托管 PocketBase 和 Astro SSR 模式。PocketBase 确实可以在服务器上渲染模板,但需要使用 Go Templates 或通过静态站点生成(SSG)预先构建。
你也可以修改此方案,改用自己选择的 Web 服务器或框架(Next.js、SvelteKit、Qwik、Angular)。
开始之前,请确保已在本地安装最新版本的 Node 和 Go。
开始使用
在终端中运行以下命令以创建基础项目:
mkdir pocketbase_astro_ssr
cd pocketbase_astro_ssr
mkdir server
mkdir www
这将在项目中创建 server 和 www 文件夹,分别供 Astro 和 PocketBase 使用。
设置服务
在 server/main.go 创建文件,并使用以下内容更新它:
package main
import (
"log"
"net/http/httputil"
"net/url"
"github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/core"
)
func main() {
app := pocketbase.New()
app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
proxy := httputil.NewSingleHostReverseProxy(&url.URL{
Scheme: "http",
Host: "localhost:4321",
})
e.Router.Any("/*", echo.WrapHandler(proxy))
e.Router.Any("/", echo.WrapHandler(proxy))
return nil
})
if err := app.Start(); err != nil {
log.Fatal(err)
}
}
这里我们使用 Go 扩展 PocketBase,并利用 Echo 路由器集成和反向代理处理所有尚未由 PocketBase 定义的请求,并将其转发给 Astro。
接下来,在终端中运行以下命令来安装依赖项:
go mod init server
go mod tidy
现在,我们可以启动服务,然后继续设置客户端:
go run main.go serve
你应该会看到以下内容。请注意,这将在调试模式下运行,因此会开始显示所有 SQL 语句:
2023/11/09 10:28:52 Server started at http://127.0.0.1:8090
├─ REST API: http://127.0.0.1:8090/api/
└─ Admin UI: http://127.0.0.1:8090/_/
集合
打开 Admin UI URL,创建新的管理员用户后,创建名为 items 的新集合,并添加以下元数据:
列名称
列类型
列设置
title
纯文本
![]()
然后更新 API 规则,允许列表和查看操作读取数据。
![]()
这仅用于示例;在生产应用中,你会依靠身份验证来设置 ACL。
创建 3 条新记录,并填入占位数据。
![]()
创建客户端
现在,我们可以创建用于连接 PocketBase 并提供所有 Web 流量服务的客户端。
进入 www 目录,并在终端中运行以下命令:
npm create astro@latest
根据提示输入以下内容:
问题
答案
应将新项目创建到哪里?
.
你想如何开始新项目?
Empty
安装依赖项吗?
Yes
你打算编写 TypeScript 吗?
Yes
TypeScript 严格程度如何?
Strict
初始化新的 git 仓库吗?
No
当然,你可以根据需要进行自定义。接下来,在终端中运行以下命令安装所需依赖项:
npm i -D @astrojs/node
npm i pocketbase
接下来,更新 www/astro.config.mjs,并使用以下内容:
import { defineConfig } from "astro/config";
import nodejs from "@astrojs/node";
// https://astro.build/config
export default defineConfig({
adapter: nodejs({
mode: "standalone",
}),
output: "server",
});
运行 Web 服务器时,这将使用服务器端渲染(SSR),而不是静态站点生成(SSG)。
UI
布局
我们可以先为所有路由创建一个共享布局。在 www/src/layouts/Root.astro 创建文件,并使用以下内容更新它:
---
interface Props {
title: string;
}
const { title } = Astro.props;
---
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>{title}</title>
</head>
<body>
<slot />
</body>
</html>
路由
现在,我们可以通过更新以下文件 www/src/pages/index.astro 来更新索引 / 路由:
---
import Root from "../layouts/Root.astro";
import PocketBase from "pocketbase";
const pb = new PocketBase("http://127.0.0.1:8090");
const items = pb.collection("items");
const records = await items.getFullList();
---
<Root title="Items">
<h1>Items</h1>
<ul>
{
records.map((record) => (
<li>
<a href={`/items/${record.id}`}>{record.title}</a>
</li>
))
}
</ul>
</Root>
这将在服务端调用 items 集合,并在客户端以 0 JS 渲染。
接下来,创建文件 www/src/pages/[...slug].astro,并按以下内容更新:
---
import Root from "../layouts/Root.astro";
import PocketBase from "pocketbase";
const slug = Astro.params.slug!;
const id = slug.split("/").pop()!;
const pb = new PocketBase("http://127.0.0.1:8090");
const items = pb.collection("items");
const records = await items.getList(1, 1, {
filter: `id = '${id}'`,
});
if (records.items.length === 0) {
return new Response("Not found", { status: 404 });
}
const {title} = records.items[0];
---
<Root {title}>
<a href="/">Back</a>
<h1>{title}</h1>
</Root>
这与之前几乎相同,不过现在如果找不到条目,我们可以返回正确的 404 响应。
运行
现在,我们可以使用以下命令运行 Web 服务:
npm run dev
你应该会看到以下内容:
> dev
> astro dev
🚀 astro v3.4.4 started in 67ms
┃ Local http://localhost:4321/
┃ Network use --host to expose
然后,打开 PocketBase URL http://127.0.0.1:8090,你应该会看到索引路由和详情路由的以下内容:
![]()
![]()
总结
现在,你可以分别为服务端和客户端构建新的二进制文件,并将它们部署在同一个服务实例上。🎉
你可以在这里找到最终代码。