Speicher
Wo ObjectOS Dateien ablegt — lokale Festplatte, S3, R2, MinIO, Spaces.
Speicher
ObjectOS-Dateien (Anhänge, Uploads, generierte Dokumente) laufen durch den Speicherdienst — eine austauschbare Abstraktion mit zwei Adaptern: lokales Dateisystem (Standard) und S3-kompatibel (Produktion).
Der Dienst wird von @objectstack/service-storage bereitgestellt und ist
in Standalone- und Projekt-Boots standardmäßig aktiviert.
Wie Benutzer damit interagieren
| Oberfläche | Verhalten |
|---|---|
| Console Datei-/Bildfelder | Der Browser lädt über vorab signierte URLs direkt in den Speicher hoch |
REST /api/v1/storage/* | Programmatische Upload-/Download-Endpunkte |
Objektfelder file / image | Werden als Upload-Widgets gerendert; Metadaten bleiben in sys_file erhalten |
Dateien werden im Systemobjekt sys_file nachverfolgt — niemals als
rohe Pfade in Ihren Datensätzen. Das entkoppelt Ihr Datenmodell vom
Speicher-Backend.
Lokales Dateisystem (Standard)
Geeignet für: Entwicklung, Single-Node-Deployments, Demos.
// objectstack.config.ts (or wherever you assemble plugins)
import { StorageServicePlugin } from '@objectstack/service-storage';
new StorageServicePlugin({
adapter: 'local',
local: {
rootDir: './uploads',
baseUrl: 'http://localhost:3000', // for presigned URLs
signingSecret: process.env.OS_STORAGE_SIGNING_SECRET, // optional; auto-generated if omitted
},
presignedTtl: 3600, // seconds — TTL for presigned URLs
sessionTtl: 86400, // seconds — TTL for chunked upload sessions
});Im Standalone-Modus (os start ohne Projekt) konfiguriert die Laufzeitumgebung
den lokalen Speicher automatisch unter .objectstack/data/uploads/. Überschreiben
Sie das Stammverzeichnis mit der Umgebungsvariable OS_STORAGE_ROOT.
Die Produktionstauglichkeit hängt von der Form des Deployments ab:
- ✅ Desktop-Apps, interne Single-Node-Tools, Edge-/On-Prem-Appliances —
lokaler Speicher ist in Ordnung, solange das Verzeichnis
uploads/in Ihr Dateisystem-Backup einbezogen wird (oder bei Desktop-Apps in einem vom Benutzer kontrollierten Sync-Ordner liegt). - ❌ Multi-Node, Multi-AZ oder alles, was regionsübergreifende Beständigkeit benötigt — verwenden Sie S3-kompatiblen Speicher.
S3-kompatibel (Produktion)
Geeignet für: Produktion, Multi-Node, Beständigkeit + Lifecycle-Management.
pnpm add @aws-sdk/client-s3 @aws-sdk/s3-request-presignerimport { StorageServicePlugin } from '@objectstack/service-storage';
new StorageServicePlugin({
adapter: 's3',
s3: {
bucket: 'my-bucket',
region: 'us-east-1',
// omit credentials to use the AWS SDK's default chain
// (env, ~/.aws, IAM role)
},
});Das AWS SDK liest Anmeldedaten aus seiner üblichen Kette:
| Quelle | Umgebungsvariable |
|---|---|
| Standard-Umgebung | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION |
| Session-Token | AWS_SESSION_TOKEN |
| Gemeinsame Konfiguration | ~/.aws/credentials, AWS_PROFILE |
| IAM-Rolle | Automatisch auf EC2 / ECS / EKS / Lambda — keine Konfiguration |
Cloudflare R2
new StorageServicePlugin({
adapter: 's3',
s3: {
bucket: 'my-bucket',
region: 'auto',
endpoint: 'https://<account-id>.r2.cloudflarestorage.com',
forcePathStyle: false,
},
});Anmeldedaten: R2 Access Key ID + Secret, übergeben über die Standard-
AWS_*-Umgebungsvariablen oder Ihren Secret Manager.
MinIO (selbst gehostet)
new StorageServicePlugin({
adapter: 's3',
s3: {
bucket: 'my-bucket',
region: 'us-east-1',
endpoint: 'http://minio.internal:9000',
forcePathStyle: true,
},
});DigitalOcean Spaces
new StorageServicePlugin({
adapter: 's3',
s3: {
bucket: 'my-bucket',
region: 'nyc3',
endpoint: 'https://nyc3.digitaloceanspaces.com',
forcePathStyle: false,
},
});S3-Bucket-Policy
Der Speicher verwendet vorab signierte PUT-/GET-URLs. Empfohlene Bucket-Policy:
- Jeglichen öffentlichen Zugriff blockieren.
- CORS:
PUT/GETvon Ihren ObjectOS-Hostnamen erlauben. - Lifecycle: unvollständige Multipart-Uploads nach 1–7 Tagen ablaufen lassen;
mit
temp=truemarkierte Objekte nach 24 Stunden ablaufen lassen. - Versioning + Object Lock: optional, empfohlen für Compliance-Deployments.
REST-Oberfläche
@objectstack/client ruft diese auf — normalerweise greifen Sie nicht direkt darauf zu:
| Methode | Pfad | Zweck |
|---|---|---|
| POST | /api/v1/storage/upload/presigned | Eine vorab signierte Upload-URL abrufen |
| POST | /api/v1/storage/upload/complete | Einen abgeschlossenen Upload festschreiben |
| POST | /api/v1/storage/upload/chunked | Chunked-Upload beginnen |
| PUT | /api/v1/storage/upload/chunked/:uploadId/chunk/:i | Einen Chunk hochladen |
| POST | /api/v1/storage/upload/chunked/:uploadId/complete | Chunked-Upload abschließen |
| GET | /api/v1/storage/upload/chunked/:uploadId/progress | Fortschritt abfragen |
| GET | /api/v1/storage/files/:fileId/url | Eine vorab signierte Download-URL abrufen |
Die Autorisierung pro Datei wird vom Permission-Evaluator des Security-Plugins
gegen das Objekt sys_file abgewickelt — Sie benötigen keine separaten
ACLs auf Speicherebene.
Live-Konfiguration
Wenn der Settings-Dienst aktiviert ist (standardmäßig der Fall), kann ein Administrator den Speicheradapter in Console → Configuration → Storage ohne Neustart austauschen:
- Adapter, Bucket, Region, Endpunkt auswählen;
- Anmeldedaten einfügen (im Ruhezustand verschlüsselt in
sys_setting); - vor dem Speichern auf Test connection klicken.
Die Änderung gilt ab der nächsten Anfrage — kein Neustart erforderlich.
Dimensionierung
| Ressource | Standard | Anpassbar |
|---|---|---|
| TTL für vorab signierte URLs | 1 Stunde | Plugin-Option presignedTtl |
| TTL für Chunked-Upload-Sitzungen | 24 Stunden | Plugin-Option sessionTtl |
| Maximaler Single-Part-Upload | Vom Backend vorgegeben (S3 = 5 GB) | — |
| Maximaler Chunked-Upload | Vom Backend vorgegeben (S3 = 5 TB) | — |
Wie es weitergeht
- System settings — Live-Konfiguration und der Settings-Dienst, der bei Speicher-Wechseln verwendet wird
- Production Readiness — Checkliste, die die Beständigkeit von Objektspeicher und Backups umfasst
@objectstack/service-storageon GitHub — Quellcode und vollständige Optionsreferenz