DevToolBox免费
博客

PocketBase 完全指南:单文件开源后端

20 min read作者 DevToolBox Team
TL;DR

PocketBase 是一个可移植的开源后端,只需单个可执行文件。它内置 SQLite 数据库、实时订阅、内置认证(邮箱/密码和 OAuth2)、文件存储和完整的管理面板 UI。下载一个二进制文件并运行,即可获得完整的后端。可使用 JavaScript hooks 或 Go 框架扩展。可部署到 Docker、fly.io、Railway 或普通 VPS。

关键要点
  • PocketBase 是一个单文件可执行的开源后端,零依赖
  • 内置 SQLite 数据库、REST API、实时订阅和管理面板
  • 支持邮箱/密码和 OAuth2 认证,开箱即用
  • 通过 JavaScript hooks 或 Go 框架模式扩展
  • 部署到 Docker、fly.io、Railway 或任何 VPS
  • 适合 MVP、个人项目和中小型应用

什么是 PocketBase?

PocketBase 是一个开源的后端应用,整个后端打包在单个可执行文件中。它由 Go 语言编写,内置 SQLite 数据库、实时订阅、用户认证、文件存储和一个完整的管理面板。你只需下载一个二进制文件并运行,就能获得功能完备的后端服务。

PocketBase 的核心理念是简单性。没有复杂的依赖管理,没有数据库服务器配置,没有微服务架构。一个文件就是你的整个后端。

安装与设置

安装 PocketBase 非常简单。从 GitHub Releases 页面下载适合你操作系统的二进制文件,解压并运行即可。

# Download PocketBase (Linux/macOS)
wget https://github.com/pocketbase/pocketbase/releases/download/v0.25.0/pocketbase_0.25.0_linux_amd64.zip
unzip pocketbase_0.25.0_linux_amd64.zip

# Run PocketBase
./pocketbase serve

# Output:
# 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/_/

# Specify a custom host and port
./pocketbase serve --http="0.0.0.0:8080"

# Enable HTTPS with auto TLS (Let's Encrypt)
./pocketbase serve --https="yourdomain.com"

首次访问管理面板时,系统会提示你创建管理员账户。PocketBase 将所有数据存储在 pb_data 目录中。

集合与数据模式

PocketBase 使用"集合"(Collections)来组织数据,类似于数据库表。集合有三种类型:Base(普通数据)、Auth(用户认证数据)和 View(只读视图)。你可以通过管理面板或 API 来创建和管理集合。

每个集合自动包含 id、created 和 updated 字段。支持的字段类型包括:text、number、bool、email、url、date、select、relation、file、json 和 editor。

// Collection schema example (as defined in admin UI or via API)
// Collection: "posts"
{
  "name": "posts",
  "type": "base",
  "schema": [
    { "name": "title",    "type": "text",     "required": true },
    { "name": "content",  "type": "editor",   "required": true },
    { "name": "slug",     "type": "text",     "unique": true },
    { "name": "tags",     "type": "select",   "options": {
        "values": ["tech", "tutorial", "news"],
        "maxSelect": 5
    }},
    { "name": "author",   "type": "relation", "options": {
        "collectionId": "users",
        "maxSelect": 1
    }},
    { "name": "cover",    "type": "file",     "options": {
        "maxSelect": 1,
        "maxSize": 5242880,
        "mimeTypes": ["image/jpeg", "image/png", "image/webp"]
    }},
    { "name": "published","type": "bool",     "default": false },
    { "name": "views",    "type": "number",   "default": 0 }
  ]
}

通过 REST API 进行 CRUD 操作

PocketBase 自动为每个集合生成完整的 REST API。你可以使用标准的 HTTP 方法来创建、读取、更新和删除记录。

# List records with filtering, sorting, and pagination
curl "http://127.0.0.1:8090/api/collections/posts/records?\
  filter=(published=true)&\
  sort=-created&\
  page=1&\
  perPage=20&\
  expand=author"

# Get a single record by ID
curl "http://127.0.0.1:8090/api/collections/posts/records/RECORD_ID"

# Create a record
curl -X POST "http://127.0.0.1:8090/api/collections/posts/records" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer USER_TOKEN" \
  -d '{"title":"My Post","content":"Hello world","published":true}'

# Update a record
curl -X PATCH "http://127.0.0.1:8090/api/collections/posts/records/RECORD_ID" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer USER_TOKEN" \
  -d '{"title":"Updated Title"}'

# Delete a record
curl -X DELETE "http://127.0.0.1:8090/api/collections/posts/records/RECORD_ID" \
  -H "Authorization: Bearer USER_TOKEN"

PocketBase 的过滤语法支持各种操作符:=, !=, >, >=, <, <=, ~(模糊匹配), !~(模糊不匹配)。你可以用 && 和 || 组合条件。

JavaScript SDK

PocketBase 官方提供 JavaScript SDK,支持浏览器和 Node.js 环境。SDK 封装了 REST API,提供类型安全的接口。

// Install the SDK
// npm install pocketbase

import PocketBase from 'pocketbase';

const pb = new PocketBase('http://127.0.0.1:8090');

// --- List records with filtering ---
const posts = await pb.collection('posts').getList(1, 20, {
  filter: 'published = true',
  sort: '-created',
  expand: 'author',
});
console.log(posts.items);
console.log(posts.totalItems);

// --- Get a single record ---
const post = await pb.collection('posts').getOne('RECORD_ID', {
  expand: 'author',
});

// --- Get first matching record ---
const featured = await pb.collection('posts').getFirstListItem(
  'slug = "hello-world"'
);

// --- Create a record ---
const newPost = await pb.collection('posts').create({
  title: 'My First Post',
  content: '<p>Hello PocketBase!</p>',
  published: true,
  author: pb.authStore.record?.id,
});

// --- Update a record ---
await pb.collection('posts').update('RECORD_ID', {
  title: 'Updated Title',
  views: post.views + 1,
});

// --- Delete a record ---
await pb.collection('posts').delete('RECORD_ID');

实时订阅

PocketBase 内置实时功能,基于 Server-Sent Events (SSE)。你可以订阅集合变更,实时接收创建、更新和删除事件。

import PocketBase from 'pocketbase';

const pb = new PocketBase('http://127.0.0.1:8090');

// Subscribe to all changes in the "posts" collection
pb.collection('posts').subscribe('*', (e) => {
  console.log(e.action); // "create", "update", or "delete"
  console.log(e.record); // the changed record
});

// Subscribe to changes on a specific record
pb.collection('posts').subscribe('RECORD_ID', (e) => {
  console.log('Record changed:', e.record);
});

// Unsubscribe from a specific collection
pb.collection('posts').unsubscribe('*');

// Unsubscribe from all subscriptions
pb.collection('posts').unsubscribe();

// React example: realtime chat messages
// useEffect(() => {
//   pb.collection('messages').subscribe('*', (e) => {
//     if (e.action === 'create') {
//       setMessages(prev => [...prev, e.record]);
//     }
//   });
//   return () => pb.collection('messages').unsubscribe();
// }, []);

认证

PocketBase 内置认证系统,支持邮箱/密码登录和 OAuth2 社交登录。认证集合自动处理密码哈希、Token 生成和会话管理。

邮箱/密码认证

import PocketBase from 'pocketbase';

const pb = new PocketBase('http://127.0.0.1:8090');

// --- Register a new user ---
const user = await pb.collection('users').create({
  email: 'user@example.com',
  password: 'securepassword123',
  passwordConfirm: 'securepassword123',
  name: 'John Doe',
});

// --- Login with email/password ---
const authData = await pb.collection('users').authWithPassword(
  'user@example.com',
  'securepassword123'
);
console.log(authData.token);
console.log(authData.record.id);

// --- Check auth state ---
console.log(pb.authStore.isValid);
console.log(pb.authStore.token);
console.log(pb.authStore.record);

// --- Refresh auth token ---
await pb.collection('users').authRefresh();

// --- Logout ---
pb.authStore.clear();

// --- Request password reset ---
await pb.collection('users').requestPasswordReset('user@example.com');

// --- Request email verification ---
await pb.collection('users').requestVerification('user@example.com');

OAuth2 社交登录

// OAuth2 login (Google, GitHub, Discord, etc.)
// First, configure OAuth2 providers in Admin UI > Auth collection > Options

// Browser-based OAuth2 login
const authData = await pb.collection('users').authWithOAuth2({
  provider: 'google',
});

console.log(authData.token);
console.log(authData.record);
console.log(authData.meta?.avatarURL);

// Supported OAuth2 providers:
// Google, GitHub, GitLab, Discord, Microsoft, Apple,
// Facebook, Twitter, Spotify, Twitch, Kakao, and more

文件存储

PocketBase 内置文件存储功能。你可以在集合中添加 file 类型字段来处理文件上传。文件存储在 pb_data/storage 目录中,并自动生成缩略图。

// Upload a file with a record
const formData = new FormData();
formData.append('title', 'My Photo');
formData.append('image', fileInput.files[0]);

const record = await pb.collection('photos').create(formData);

// Get the file URL
const url = pb.files.getURL(record, record.image);
// => http://127.0.0.1:8090/api/files/photos/RECORD_ID/filename.jpg

// Get a thumbnail (auto-generated)
const thumb = pb.files.getURL(record, record.image, {
  thumb: '100x100',
});

// Upload multiple files
const multi = new FormData();
multi.append('title', 'Gallery');
multi.append('images', file1);
multi.append('images', file2);
multi.append('images', file3);
const gallery = await pb.collection('galleries').create(multi);

// Delete a file by setting it to empty
await pb.collection('photos').update(record.id, {
  image: null,
});

钩子与事件处理

PocketBase 支持 JavaScript 钩子,你可以在 pb_hooks 目录中放置 .pb.js 文件来拦截事件和添加自定义逻辑。钩子在记录创建、更新、删除前后触发。

// pb_hooks/main.pb.js

// Before creating a record - validate and modify data
onRecordCreate((e) => {
  // Auto-generate a slug from the title
  if (e.record.get('title')) {
    const slug = e.record.get('title')
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-|-$/g, '');
    e.record.set('slug', slug);
  }
  e.next();
}, 'posts');

// After creating a record - send notification
onRecordAfterCreateSuccess((e) => {
  console.log('New post created:', e.record.get('title'));
  // Send email, webhook, etc.
  e.next();
}, 'posts');

// Add a custom API route
routerAdd('GET', '/api/stats', (e) => {
  const posts = arrayOf(new Record());
  $app.recordQuery('posts').all(posts);
  return e.json(200, {
    totalPosts: posts.length,
    timestamp: new Date().toISOString(),
  });
});

// Cron job: run cleanup daily at midnight
cronAdd('daily-cleanup', '0 0 * * *', () => {
  const cutoff = new Date();
  cutoff.setDate(cutoff.getDate() - 30);
  $app.dao().deleteRecordsByFilter(
    'temp_files',
    'created < "' + cutoff.toISOString() + '"'
  );
});

使用 Go 扩展

PocketBase 可以作为 Go 框架使用。将 PocketBase 导入你的 Go 项目,你可以访问所有内部 API,注册自定义路由、中间件和事件处理器。

// main.go
package main

import (
    "log"
    "net/http"

    "github.com/pocketbase/pocketbase"
    "github.com/pocketbase/pocketbase/core"
)

func main() {
    app := pocketbase.New()

    // Add a custom route
    app.OnServe().BindFunc(func(se *core.ServeEvent) error {
        se.Router.GET("/api/hello", func(e *core.RequestEvent) error {
            return e.JSON(http.StatusOK, map[string]string{
                "message": "Hello from custom Go route!",
            })
        })
        return se.Next()
    })

    // Hook into record events
    app.OnRecordCreate("posts").BindFunc(func(e *core.RecordEvent) error {
        log.Println("Creating post:", e.Record.GetString("title"))
        return e.Next()
    })

    if err := app.Start(); err != nil {
        log.Fatal(err)
    }
}
# Initialize Go module and run
go mod init myapp
go mod tidy
go run main.go serve

管理面板

PocketBase 自带一个美观的管理面板,访问 /_/ 路径即可使用。管理面板让你可以可视化地管理集合、浏览记录、配置认证、设置 API 规则等。

  • 创建、编辑和删除集合与字段
  • 浏览、搜索和过滤记录
  • 配置 API 规则(列表、查看、创建、更新、删除)
  • 管理 OAuth2 提供商和邮件模板
  • 查看日志和系统信息
  • 导入/导出集合模式
  • 管理管理员账户

API 规则与访问控制

PocketBase 使用基于规则的访问控制系统。每个集合的每个 API 操作都可以设置独立的规则。空规则表示禁止访问,@request 开头的规则可以引用当前请求上下文。

// API Rules examples (set in Admin UI for each collection)

// List/View: anyone can read published posts
// Rule: published = true

// List/View: only authenticated users
// Rule: @request.auth.id != ""

// Create: only authenticated users
// Rule: @request.auth.id != ""

// Update: only the author can update
// Rule: author = @request.auth.id

// Delete: only admins (leave blank to deny, or use admin-only)
// Rule: @request.auth.role = "admin"

// Combined: author or admin can update
// Rule: author = @request.auth.id || @request.auth.role = "admin"

// Access related records
// Rule: @request.auth.id = team.members.id

部署

PocketBase 可以部署到任何能运行单个二进制文件的环境。以下是常见的部署方式。

Docker 部署

# Dockerfile
FROM alpine:latest

ARG PB_VERSION=0.25.0

RUN apk add --no-cache \
    unzip \
    ca-certificates

ADD https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_amd64.zip /tmp/pb.zip
RUN unzip /tmp/pb.zip -d /pb/

EXPOSE 8090

CMD ["/pb/pocketbase", "serve", "--http=0.0.0.0:8090"]
# docker-compose.yml
version: "3.8"
services:
  pocketbase:
    build: .
    ports:
      - "8090:8090"
    volumes:
      - pb_data:/pb/pb_data
      - ./pb_hooks:/pb/pb_hooks
    restart: unless-stopped

volumes:
  pb_data:

fly.io 部署

# fly.toml
app = "my-pocketbase-app"
primary_region = "ord"

[build]
  dockerfile = "Dockerfile"

[mounts]
  source = "pb_data"
  destination = "/pb/pb_data"

[http_service]
  internal_port = 8090
  force_https = true

# Deploy commands:
# fly launch
# fly volumes create pb_data --size 1 --region ord
# fly deploy

Railway 部署

Railway 支持直接从 GitHub 仓库部署 Dockerfile。只需连接你的仓库,Railway 会自动构建和部署。确保添加持久化卷来挂载 pb_data 目录。

VPS + systemd 部署

# /etc/systemd/system/pocketbase.service
[Unit]
Description=PocketBase
After=network.target

[Service]
Type=simple
User=pocketbase
Group=pocketbase
WorkingDirectory=/opt/pocketbase
ExecStart=/opt/pocketbase/pocketbase serve --http=127.0.0.1:8090
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

# Enable and start
# sudo systemctl enable pocketbase
# sudo systemctl start pocketbase

备份与迁移

PocketBase 将所有数据存储在 pb_data 目录中。备份只需复制该目录。你也可以使用 API 或 SQLite 工具进行备份。

# Manual backup: copy pb_data directory
cp -r /opt/pocketbase/pb_data /backup/pb_data_$(date +%Y%m%d)

# SQLite online backup (safe while running)
sqlite3 /opt/pocketbase/pb_data/data.db ".backup /backup/data_backup.db"

# Automated backup via cron (daily at 2 AM)
# crontab -e
0 2 * * * cp -r /opt/pocketbase/pb_data /backup/pb_data_$(date +\%Y\%m\%d)

# Use the admin API for backup
curl -X POST "http://127.0.0.1:8090/api/backups" \
  -H "Authorization: Bearer ADMIN_TOKEN"

# List existing backups
curl "http://127.0.0.1:8090/api/backups" \
  -H "Authorization: Bearer ADMIN_TOKEN"

# Migrate: copy pb_data to new server and start PocketBase
scp -r /opt/pocketbase/pb_data user@newserver:/opt/pocketbase/
ssh user@newserver "/opt/pocketbase/pocketbase serve"

PocketBase vs Supabase vs Firebase

以下是 PocketBase 与其他流行 BaaS(后端即服务)平台的对比。

特性PocketBaseSupabaseFirebase
数据库SQLite (嵌入式)PostgreSQLFirestore (NoSQL)
托管自托管云托管 / 自托管仅云托管
价格免费(开源)免费层 + 付费免费层 + 按用量付费
实时SSEWebSocket (Postgres Changes)WebSocket
认证内置(邮箱 + OAuth2)内置(邮箱 + OAuth2 + 更多)内置(邮箱 + OAuth2 + 手机)
文件存储本地 / S3S3 兼容Cloud Storage
扩展性单服务器(垂直扩展)水平扩展自动扩展
语言GoTypeScript / Elixir专有
最适合MVP、个人项目、中小型应用生产应用、团队协作移动应用、快速原型

安全最佳实践

  • 使用 HTTPS: 始终在生产环境中使用 TLS。PocketBase 支持自动 Let's Encrypt 证书,或者放在 Nginx/Caddy 反向代理后面。
  • 设置 API 规则: 不要让集合的 API 规则留空。默认空规则表示拒绝访问,但请明确为每个操作设置规则。
  • 限制管理面板访问: 在生产环境中,将管理面板绑定到内部网络或使用防火墙限制 /_/ 路径的访问。
  • 定期备份: 设置自动备份策略,定期备份 pb_data 目录。
  • 使用强密码: 为管理员账户设置强密码,并设置最小密码长度要求。
  • 保持更新: 定期更新 PocketBase 到最新版本以获取安全补丁。
  • 速率限制: 使用反向代理(Nginx、Caddy)添加速率限制来防止暴力攻击。
  • S3 存储: 对于重要的文件存储,配置 S3 兼容的外部存储(如 AWS S3、Backblaze B2)而不是本地磁盘。
# Nginx reverse proxy with rate limiting
upstream pocketbase {
    server 127.0.0.1:8090;
}

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

server {
    listen 443 ssl http2;
    server_name api.example.com;

    ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;

    # Rate limiting
    location /api/ {
        limit_req zone=api burst=20 nodelay;
        proxy_pass http://pocketbase;
        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;
    }

    # Restrict admin panel to specific IPs
    location /_/ {
        allow 10.0.0.0/8;
        deny all;
        proxy_pass http://pocketbase;
        proxy_set_header Host $host;
    }

    # SSE for realtime (long-lived connections)
    location /api/realtime {
        proxy_pass http://pocketbase;
        proxy_set_header Host $host;
        proxy_buffering off;
        proxy_cache off;
        proxy_read_timeout 3600s;
    }
}

S3 兼容存储配置

PocketBase 支持将文件存储到 S3 兼容的服务中,在管理面板的 Settings > Files storage 中配置。

// S3 configuration in Admin UI > Settings > Files storage
// Endpoint:   s3.us-east-1.amazonaws.com (AWS)
//             s3.us-west-004.backblazeb2.com (Backblaze B2)
// Bucket:     my-pocketbase-files
// Region:     us-east-1
// Access Key: your-access-key
// Secret:     your-secret-key
// Force path style: true (for non-AWS providers)

完整示例:React + PocketBase

以下是一个使用 React 和 PocketBase 构建的完整 CRUD 应用示例。

// src/lib/pocketbase.ts
import PocketBase from 'pocketbase';

export const pb = new PocketBase('http://127.0.0.1:8090');

// src/hooks/usePosts.ts
import { useState, useEffect } from 'react';
import { pb } from '../lib/pocketbase';

export function usePosts() {
  const [posts, setPosts] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // Fetch initial data
    pb.collection('posts')
      .getList(1, 50, { sort: '-created', expand: 'author' })
      .then((result) => {
        setPosts(result.items);
        setLoading(false);
      });

    // Subscribe to realtime changes
    pb.collection('posts').subscribe('*', (e) => {
      if (e.action === 'create') {
        setPosts((prev) => [e.record, ...prev]);
      } else if (e.action === 'update') {
        setPosts((prev) =>
          prev.map((p) => (p.id === e.record.id ? e.record : p))
        );
      } else if (e.action === 'delete') {
        setPosts((prev) => prev.filter((p) => p.id !== e.record.id));
      }
    });

    return () => {
      pb.collection('posts').unsubscribe();
    };
  }, []);

  const createPost = async (data) => {
    return pb.collection('posts').create(data);
  };

  const deletePost = async (id) => {
    return pb.collection('posts').delete(id);
  };

  return { posts, loading, createPost, deletePost };
}

常见问题

What is PocketBase and what are its primary use cases?

PocketBase is an open-source backend that ships as a single executable file. It includes an embedded SQLite database, built-in authentication, file storage, realtime subscriptions, and an admin dashboard. Primary use cases include MVPs, side projects, internal tools, mobile app backends, and small-to-medium web applications. It is written in Go and can be extended as a Go framework or with JavaScript hooks.

How does PocketBase compare to Supabase and Firebase?

PocketBase is self-hosted and runs as a single binary with zero dependencies, while Supabase and Firebase are cloud-hosted platforms. PocketBase uses SQLite, Supabase uses PostgreSQL, and Firebase uses a proprietary NoSQL database. PocketBase is free and open-source with no usage limits. Supabase offers a generous free tier but charges for scaling. Firebase has pay-as-you-go pricing. PocketBase is ideal for smaller applications and full control, while Supabase and Firebase are better for teams needing managed infrastructure and global scaling.

Can PocketBase handle production workloads?

Yes, PocketBase can handle production workloads for small-to-medium applications. SQLite can handle thousands of concurrent readers and many writes per second. PocketBase supports WAL mode for better concurrency. For high-traffic applications, you can deploy PocketBase behind a reverse proxy like Nginx or Caddy, enable gzip compression, and use a CDN for static assets. However, PocketBase does not support horizontal scaling or multi-server clustering, so it is not suitable for applications requiring millions of concurrent users.

How do I set up authentication in PocketBase?

PocketBase provides built-in authentication for both email/password and OAuth2 providers. Create an auth collection in the admin dashboard, then use the JavaScript SDK to register and login users. For OAuth2, enable providers like Google, GitHub, or Discord in the admin panel and configure client IDs and secrets. PocketBase handles token generation, session management, and password hashing automatically. You can also customize auth rules per collection for fine-grained access control.

Does PocketBase support realtime subscriptions?

Yes, PocketBase has built-in realtime support via Server-Sent Events (SSE). You can subscribe to changes on any collection and receive create, update, and delete events in real time. The JavaScript SDK provides a simple subscribe method that handles reconnection automatically. Realtime subscriptions respect collection API rules, so users only receive events for records they have permission to access.

How do I deploy PocketBase to production?

PocketBase can be deployed anywhere that runs a single binary. Common deployment options include: Docker (using a minimal Dockerfile with the PocketBase binary), fly.io (using a Dockerfile and fly.toml with a persistent volume), Railway (connecting your GitHub repo), or a plain VPS with systemd for process management. Always mount a persistent volume for the pb_data directory, set up regular backups, and use a reverse proxy with TLS termination.

Can I extend PocketBase with custom logic?

Yes, PocketBase can be extended in two ways. First, you can use JavaScript hooks by placing .pb.js files in the pb_hooks directory. These hooks intercept events like record creation, update, and deletion, and can add custom API routes. Second, you can use PocketBase as a Go framework by importing it into your own Go project and registering custom routes, middleware, and event handlers. The Go approach gives full access to the PocketBase internals and the Go standard library.

How do I back up and migrate a PocketBase database?

PocketBase stores all data in the pb_data directory, which contains the SQLite database, uploaded files, and configuration. To back up, copy the entire pb_data directory or use the built-in backup API endpoint. For automated backups, use a cron job with sqlite3 .backup command or the PocketBase admin API. To migrate, copy pb_data to a new server and start PocketBase. Schema migrations can be managed through the admin UI or by exporting and importing collection schemas as JSON.

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

{ }JSON FormatterJSON Validator

相关文章

Supabase 指南 2026:认证、数据库、实时、存储与边缘函数

完整的 Supabase 指南,涵盖 PostgreSQL 与行级安全策略、认证(邮箱、OAuth、魔法链接)、实时订阅、文件存储、边缘函数、TypeScript 集成和生产最佳实践。

Fastify 完全指南:高性能 Node.js Web 框架

掌握 Fastify 路由、Schema 验证、插件、钩子、序列化、日志、JWT 认证与数据库集成。

Docker命令:从基础到生产的完整指南

掌握Docker的完整命令指南。含docker run/build/push、Dockerfile、多阶段构建、卷、网络、Docker Compose、安全、注册表和生产部署模式。