用过 Sealos 云开发的同学,想必都很熟悉函数式编程,喜欢 Sealos 云开发的那种完全不用关心路由,开发快,上线快,调试快,越用越简单越简单越用的感觉。它就像一个温柔的保姆,帮你打理好了所有的家务事 (路由、部署、调试),让你专注于写代码的快乐。

现在更强大的保姆来了,Sealos Devbox 新增了云开发框架,它不仅继承了 Laf 的优秀基因,还自带 “变形金刚” 属性 - 不依赖数据库和对象存储,还能打包成镜像到处运行。

之前使用云开发的小伙伴们,可以无缝迁移到 Devbox 云开发框架,之前怎么玩的,现在还怎么玩,几乎没有学习成本。

话不多说,直接上教程!

快速开始

Sealos Devbox 中开发云开发应用非常简单,首先进入 Sealos 桌面,然后打开 Devbox:

新建一个项目,运行环境选择 Laf,CPU 调整到 1C、内存 2G 就够了,系统会自动分配 HTTPS 域名,通过该域名即可访问 Devbox 中的 2342 端口。

选择框架后点击创建,几秒钟即可启动开发环境。

在操作选项中选择使用 Cursor 连接:

首次打开会提示安装 Devbox 插件,安装后即可自动连接开发环境。

是不是非常简单?直接省略了配置域名解析、申请 SSL 证书,配置网关等与开发无关的繁琐操作,爽!

Cursor 中的目录结构如下:

  • dist 目录是 pnpm build 的构建产物,我们无需关心
  • functions 目录是重点,所有接口函数都必须写在这里
  • 路由规则:functions 目录下的文件路径即为接口路由

    • 例如 functions/hello.ts 对应路由 /hello
    • functions/user/info.ts 对应路由 /user/info
  • 每个接口文件必须定义默认导出函数:

    • export default async function
    • export default function

这种开发体验与云开发完全一致,原汁原味,可以无缝迁移。

functions 目录自带了一个 hello world 示例接口。我们可以通过 pnpm dev 运行项目:

现在回到 Devbox 界面,进入 Laf 开发环境的详情页面:

复制外网地址,并在末尾加上 /hello 访问 (例如本文中的 https://fgatxwcjmxep.sealoshzh.site/hello):

就这么简单,一个 Hello World 接口就跑起来了!Devbox 云开发环境不仅保持了原汁原味的开发体验,还提供了更多灵活的特性:

  • FunctionCache:管理函数缓存
  • FunctionModule:管理模块缓存
  • FunctionExecutor:管理代码执行

想了解更多高级特性,欢迎访问项目仓库 https://github.com/HUAHUAI23/simple-web 查看详细文档。

进阶教程

Devbox 云开发环境虽然提供了原生的开发体验,不依赖数据库和对象存储等服务,但实际应用开发中往往需要用到这些基础设施。下面我们就来看看如何结合 Sealos 的数据库、对象存储等服务,打造一个丝滑的开发体验。

使用 MongoDB 数据库

首先需要在 Sealos 数据库服务中创建一个 MongoDB 6.0 实例。创建时需要记录以下重要信息:

  • 数据库内网连接串 (注意保护好密码,不要泄露)
  • 如果需要使用 MongoDB Compass 等专业工具连接,还需要开启数据库的外网访问

下面我们通过一个示例来演示如何使用 MongoDB。我们会把数据库客户端代码放在 functions 目录外面,因为数据库客户端、对象存储客户端、定时任务等基础设施代码不需要直接暴露为 API。

首先打开 Cursor 的终端,然后执行以下命令将 pnpm 的源替换为国内淘宝源:

pnpm config set registry https://registry.npmmirror.com

然后执行命令 pnpm install mongodb 安装 MongoDB 客户端,然后在 client 目录下创建 mongodb.ts 文件,写入 MongoDB 客户端代码。

将 uri 替换为你的数据库内网连接串
import { MongoClient } from 'mongodb'

// 生产环境切记将密码和用户 替换成从环境变量中获取,切记不要在代码中写死泄露密码
// const username = process.env.MONGO_USERNAME
// const password = process.env.MONGO_PASSWORD
// const uri = `mongodb://${username}:${password}@test-mongodb.ns-1k9qk3v6.svc:27017`
const uri = "mongodb://root:4vvt29kl@test-db-mongodb.ns-g7res18a.svc:27017"

// 创建 MongoDB 客户端实例
export const client = new MongoClient(uri)

functions 目录下创建 mongodb-test.ts 文件,写入 MongoDB 测试代码。

import { FunctionContext } from 'simple-web23'
import { client } from '../client/mongodb'

export default async function (ctx: FunctionContext) {
    const database = client.db('test')
    const collection = database.collection('test')

    // 创建测试数据
    console.log('--- 创建测试数据 ---')
    const insertResult = await collection.insertMany([
        { name: '张三', age: 25, city: '北京' },
        { name: '李四', age: 30, city: '上海' }
    ])
    console.log('插入数据结果:', insertResult)

    // 查询所有数据
    console.log('\\n--- 查询所有数据 ---')
    const allDocs = await collection.find({}).toArray()
    console.log('所有数据:', allDocs)

    // 查询单个数据
    console.log('\\n--- 查询单个数据 ---')
    const oneDoc = await collection.findOne({ name: '张三' })
    console.log('查询张三的数据:', oneDoc)

    // 更新数据
    console.log('\\n--- 更新数据 ---')
    const updateResult = await collection.updateOne(
        { name: '张三' },
        { $set: { age: 26, city: '深圳' } }
    )
    console.log('更新结果:', updateResult)

    // 查看更新后的数据
    const updatedDoc = await collection.findOne({ name: '张三' })
    console.log('更新后的张三数据:', updatedDoc)

    // 删除数据
    console.log('\\n--- 删除数据 ---')
    const deleteResult = await collection.deleteOne({ name: '李四' })
    console.log('删除结果:', deleteResult)

    // 最终查询所有数据
    console.log('\\n--- 最终数据 ---')
    const finalDocs = await collection.find({}).toArray()
    console.log('最终所有数据:', finalDocs)

    return { message: '测试完成' }
}

一切准备 ok 后,在 Cursor 终端运行 pnpm dev 命令,然后浏览器访问 mongodb-test 接口,可以看到 MongoDB 的测试结果。

上面这些代码全是 AI 帮我写的,我只需要指挥它干活就行。

使用 Sealos 对象存储

在开始使用对象存储之前,我们需要先在 Sealos 对象存储服务中创建一个存储桶。创建过程中,请务必记录以下关键信息:

  • 访问密钥 (Access Key)
  • 密钥 (Secret Key)
  • 内外网访问地址
  • 存储桶名称

接下来,让我们一步步完成对象存储的配置和使用。

首先安装 S3 客户端依赖:

pnpm install @aws-sdk/client-s3

然后在 client 目录下创建 s3.ts 文件,写入 S3 客户端代码。

请将 s3Client 中的 region、endpoint、accessKeyId、secretAccessKey 替换为你自己的配置。
import { S3Client, ListObjectsV2Command, PutObjectCommand, _Object } from "@aws-sdk/client-s3"

// 创建 S3 客户端
// 生产环境切记将密码和用户 替换成从环境变量中获取,切记不要在代码中写死泄露密码
// const accessKeyId = process.env.S3_ACCESS_KEY_ID
// const secretAccessKey = process.env.S3_SECRET_ACCESS_KEY

const s3Client = new S3Client({
    region: "cn-north-1", // 例如 "ap-northeast-1"
    endpoint: "http://object-storage.objectstorage-system.svc.cluster.local", // 例如 "https://s3.amazonaws.com" 或自定义endpoint
    credentials: {
        accessKeyId: "xxxxxxxxxx",
        secretAccessKey: "xxxxxxxxxx"
    },
    // 如果使用自定义endpoint(比如MinIO),可能需要以下配置
    forcePathStyle: true, // 强制使用路径样式而不是虚拟主机样式
})

// 列出 bucket 中的文件
async function listFiles(bucketName: string) {
    try {
        const command = new ListObjectsV2Command({
            Bucket: bucketName,
        })

        const response = await s3Client.send(command)

        // 打印文件列表
        response.Contents?.forEach((file: _Object) => {
            console.log(`文件名: ${file.Key}, 大小: ${file.Size} bytes`)
        })

        return response.Contents
    } catch (error) {
        console.error("列出文件失败:", error)
        throw error
    }
}

// 上传文件到 S3
async function uploadFile(bucketName: string, key: string, fileContent: Buffer) {
    try {
        const command = new PutObjectCommand({
            Bucket: bucketName,
            Key: key,
            Body: fileContent,
        })

        const response = await s3Client.send(command)
        console.log("文件上传成功:", response)
        return response
    } catch (error) {
        console.error("文件上传失败:", error)
        throw error
    }
}

export { listFiles, uploadFile }

functions 目录下创建 s3-test.ts 文件,写入 S3 测试代码。

import { FunctionContext } from 'simple-web23'
import { listFiles, uploadFile } from '../client/s3'

export default async function (ctx: FunctionContext) {
    const bucketName = 'ehq1gpr0-test'
    const fileName = 'test.txt'
    const fileContent = Buffer.from('Hello World')
    await uploadFile(bucketName, fileName, fileContent)
    await listFiles(bucketName)
    return 'success'
}

请将 bucketName 替换为你自己的存储桶名称。

一切准备就绪后,在 Cursor 终端运行 pnpm dev 命令,然后浏览器访问 s3-test 接口,便可以看到对象存储的测试结果。

上面的代码也全是 AI 帮我写的。

完整的代码请访问 https://github.com/HUAHUAI23/simple-web-demo 查看。

结语

Sealos 非常强大,除了我们刚刚体验的数据库和对象存储服务,它还提供了丰富的应用生态和中间件支持。通过 Devbox 云开发环境,你可以轻松地将这些服务无缝对接,打造一个完整的开发链路。

不论是快速开发原型,还是构建生产级应用,Sealos 都能为你提供顺畅的开发体验。

去吧骚年,去用 Sealos Devbox 构建属于你的精彩应用,加油,你们是最胖的!


米开朗基杨
169 声望26 粉丝