Persistent Storage
This guide demonstrates using persistent storage instead of in-memory storage. Documents are persisted across server restarts using the unstorage abstraction layer.
What it demonstrates
Section titled “What it demonstrates”- Using
UnstorageDocumentStoragefor persistent document storage - Configuring unstorage with different drivers (memory, SQLite, Redis, etc.)
- Replacing in-memory storage with a persistent storage backend
Server Setup
Section titled “Server Setup”import { createStorage } from "unstorage";import { UnstorageDocumentStorage } from "teleportal/storage";import redisDriver from "unstorage/drivers/redis";import { Server } from "teleportal/server";
// Create unstorage instance with Redis driverconst storage = createStorage({ driver: redisDriver({ base: "teleportal:", url: "redis://localhost:6379", }),});
const server = new Server({ storage: async (ctx) => { return new UnstorageDocumentStorage(storage, { keyPrefix: "doc", encrypted: ctx.encrypted, }); },});First-Party Storage Adapters
Section titled “First-Party Storage Adapters”Teleportal ships first-party storage adapters for PostgreSQL and S3 that extend AbstractDocumentStorage directly, offering better performance and tighter integration than generic unstorage drivers.
PostgreSQL (first-party)
Section titled “PostgreSQL (first-party)”import postgres from "postgres";import { PostgresDocumentStorage, ensureSchema } from "teleportal/storage/postgres";
const sql = postgres("postgres://localhost/mydb", { max: 10 });await ensureSchema(sql); // create tables once at startup
const server = new Server({ storage: async (ctx) => { return new PostgresDocumentStorage(sql, { encrypted: ctx.encrypted }); },});S3 (first-party, for file storage)
Section titled “S3 (first-party, for file storage)”S3FileStorage and S3TemporaryUploadStorage each take an S3Config (or a shared S3Http client) plus options. Pass the temporary upload store to the file store via the temporaryUploadStorage option. Works with AWS S3, Cloudflare R2, and MinIO:
import { S3FileStorage, S3Http, S3TemporaryUploadStorage } from "teleportal/storage/s3";
const s3 = new S3Http({ endpoint: "https://<account>.r2.cloudflarestorage.com", bucket: "my-bucket", region: "auto", accessKeyId: process.env.S3_ACCESS_KEY_ID!, secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!,});
const temp = new S3TemporaryUploadStorage(s3);const fileStorage = new S3FileStorage(s3, { temporaryUploadStorage: temp });Alternative Storage Backends (via unstorage)
Section titled “Alternative Storage Backends (via unstorage)”For other backends, use the unstorage abstraction layer with any of its drivers.
SQLite
Section titled “SQLite”import sqliteDriver from "unstorage/drivers/sqlite";
const storage = createStorage({ driver: sqliteDriver({ db: "./teleportal.db", }),});S3 (via unstorage)
Section titled “S3 (via unstorage)”import s3Driver from "unstorage/drivers/s3";
const storage = createStorage({ driver: s3Driver({ bucket: "my-bucket", region: "us-east-1", }),});Next Steps
Section titled “Next Steps”- Encryption at Rest - Encrypt documents in storage
- Custom Storage - Implement your own storage backend