스토리지
ObjectOS가 파일을 저장하는 위치 — 로컬 디스크, S3, R2, MinIO, Spaces.
스토리지
ObjectOS 파일(첨부 파일, 업로드, 생성된 문서)은 스토리지 서비스를 통해 흐릅니다 — 두 가지 어댑터를 갖춘 플러그형 추상화 계층으로, 로컬 파일 시스템(기본값)과 S3 호환(프로덕션)을 제공합니다.
이 서비스는 @objectstack/service-storage에서 제공되며
standalone 및 프로젝트 부팅 시 기본적으로 활성화됩니다.
사용자가 상호작용하는 방식
| 인터페이스 | 동작 |
|---|---|
| Console 파일/이미지 필드 | 브라우저가 presigned URL을 통해 스토리지로 직접 업로드 |
REST /api/v1/storage/* | 프로그래밍 방식의 업로드/다운로드 엔드포인트 |
객체 file / image 필드 | 업로드 위젯으로 렌더링되며, 메타데이터는 sys_file에 유지됨 |
파일은 레코드에 원시 경로로 저장되는 것이 아니라 sys_file 시스템 객체에서 추적됩니다.
이를 통해 데이터 모델이 스토리지 백엔드로부터 분리됩니다.
로컬 파일 시스템 (기본값)
적합한 용도: 개발, 단일 노드 배포, 데모.
// 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
});standalone 모드(프로젝트 없이 os start)에서는 런타임이
.objectstack/data/uploads/ 아래에 로컬 스토리지를 자동으로 구성합니다.
루트 디렉터리는 OS_STORAGE_ROOT 환경 변수로 재정의할 수 있습니다.
프로덕션 적합성은 배포 형태에 따라 달라집니다:
- ✅ 데스크톱 앱, 단일 노드 내부 도구, 엣지 / 온프레미스
어플라이언스 —
uploads/디렉터리가 파일 시스템 백업에 포함되어 있는 한 (또는 데스크톱 앱의 경우 사용자가 관리하는 동기화 폴더에 위치하는 한) 로컬 스토리지로 충분합니다. - ❌ 멀티 노드, 멀티 AZ, 또는 리전 간 내구성이 필요한 경우 — S3 호환 스토리지를 사용하세요.
S3 호환 (프로덕션)
적합한 용도: 프로덕션, 멀티 노드, 내구성 + 수명 주기 관리.
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)
},
});AWS SDK는 일반적인 체인에서 자격 증명을 읽습니다:
| 소스 | 환경 변수 |
|---|---|
| 표준 환경 변수 | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION |
| 세션 토큰 | AWS_SESSION_TOKEN |
| 공유 구성 | ~/.aws/credentials, AWS_PROFILE |
| IAM 역할 | EC2 / ECS / EKS / Lambda에서 자동 — 구성 불필요 |
Cloudflare R2
new StorageServicePlugin({
adapter: 's3',
s3: {
bucket: 'my-bucket',
region: 'auto',
endpoint: 'https://<account-id>.r2.cloudflarestorage.com',
forcePathStyle: false,
},
});자격 증명: R2 액세스 키 ID + 시크릿으로, 표준 AWS_*
환경 변수나 시크릿 관리자를 통해 전달합니다.
MinIO (자체 호스팅)
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 버킷 정책
스토리지는 presigned PUT/GET URL을 사용합니다. 권장 버킷 정책:
- 모든 퍼블릭 액세스 차단.
- CORS: ObjectOS 호스트명에서의
PUT/GET허용. - 수명 주기: 미완료 멀티파트 업로드는 1~7일 후 만료;
temp=true태그가 지정된 객체는 24시간 후 만료. - 버전 관리 + Object Lock: 선택 사항이며, 규정 준수 배포에 권장됩니다.
REST 인터페이스
@objectstack/client가 이를 호출하므로 — 일반적으로 직접 호출할 필요는 없습니다:
| 메서드 | 경로 | 용도 |
|---|---|---|
| POST | /api/v1/storage/upload/presigned | presigned 업로드 URL 가져오기 |
| POST | /api/v1/storage/upload/complete | 완료된 업로드 커밋 |
| POST | /api/v1/storage/upload/chunked | 청크 업로드 시작 |
| PUT | /api/v1/storage/upload/chunked/:uploadId/chunk/:i | 청크 업로드 |
| POST | /api/v1/storage/upload/chunked/:uploadId/complete | 청크 업로드 완료 |
| GET | /api/v1/storage/upload/chunked/:uploadId/progress | 진행 상황 폴링 |
| GET | /api/v1/storage/files/:fileId/url | presigned 다운로드 URL 가져오기 |
파일별 권한 부여는 보안 플러그인의 권한 평가기가 sys_file 객체를 대상으로
처리하므로 — 별도의 스토리지 계층 ACL이 필요하지 않습니다.
실시간 구성
설정 서비스가 활성화되어 있으면(기본적으로 활성화됨), 관리자는 재시작 없이 Console → Configuration → Storage에서 스토리지 어댑터를 교체할 수 있습니다:
- 어댑터, 버킷, 리전, 엔드포인트 선택;
- 자격 증명 붙여넣기(
sys_setting에 저장 시 암호화됨); - 저장하기 전에 Test connection 클릭.
변경 사항은 다음 요청부터 적용됩니다 — 재시작이 필요 없습니다.
사이징
| 리소스 | 기본값 | 조정 가능 여부 |
|---|---|---|
| Presigned URL TTL | 1시간 | presignedTtl 플러그인 옵션 |
| 청크 업로드 세션 TTL | 24시간 | sessionTtl 플러그인 옵션 |
| 최대 단일 파트 업로드 | 백엔드 제한 (S3 = 5 GB) | — |
| 최대 청크 업로드 | 백엔드 제한 (S3 = 5 TB) | — |
다음 단계
- System settings — 실시간 구성 및 스토리지 교체에 사용되는 설정 서비스
- Production Readiness — 객체 스토리지 내구성 및 백업을 포함하는 체크리스트
@objectstack/service-storageon GitHub — 소스 및 전체 옵션 참조