MinIO設定をCoolify対応に整備し、bucket自動作成を追加
compose:
- MinIOにヘルスチェック(mc ready)を追加し、api/workerはhealthyを待つように変更
- 全認証情報を${VAR:-default}でパラメータ化し、Coolifyの環境変数/シークレットで上書き可能に
- MINIO_SERVER_URL / MINIO_BROWSER_REDIRECT_URL でリバースプロキシ背後の公開URLに対応
- workerの依存先をapiからpostgres+minioに修正し、起動順序のデッドロックを解消
API:
- S3StorageにensureBucket()を追加(HeadBucket→なければCreateBucket、冪等)
- runtime起動時にbucketを自動作成し、minio-init依存を必須ではなくした
.env.exampleにMinIO関連変数を追記
This commit is contained in:
@@ -5,9 +5,11 @@ import { dirname, normalize, relative, resolve } from "node:path";
|
||||
import { pipeline } from "node:stream/promises";
|
||||
import { Readable } from "node:stream";
|
||||
import {
|
||||
CreateBucketCommand,
|
||||
CompleteMultipartUploadCommand,
|
||||
CreateMultipartUploadCommand,
|
||||
GetObjectCommand,
|
||||
HeadBucketCommand,
|
||||
HeadObjectCommand,
|
||||
PutObjectCommand,
|
||||
S3Client,
|
||||
@@ -35,6 +37,7 @@ export interface StorageAdapter {
|
||||
downloadToFile(key: string, filePath: string): Promise<void>;
|
||||
getObject(key: string): Promise<StoredObject | null>;
|
||||
headObject(key: string): Promise<{ sizeBytes: number; contentType: string } | null>;
|
||||
ensureBucket?(): Promise<void>;
|
||||
}
|
||||
|
||||
function contentTypeForPath(path: string) {
|
||||
@@ -126,6 +129,26 @@ export class S3Storage implements StorageAdapter {
|
||||
});
|
||||
}
|
||||
|
||||
// Idempotently create the configured bucket so the service is self-contained
|
||||
// and does not depend on an external init step (e.g. a separate minio-init
|
||||
// container) before it can store objects. Safe to call on every startup.
|
||||
async ensureBucket() {
|
||||
const bucket = this.appConfig.S3_BUCKET;
|
||||
try {
|
||||
await this.client.send(new HeadBucketCommand({ Bucket: bucket }));
|
||||
return;
|
||||
} catch (error: any) {
|
||||
const notFound = error?.$metadata?.httpStatusCode === 404 || error?.name === "NotFound" || error?.name === "NoSuchBucket";
|
||||
if (!notFound) {
|
||||
// Re-throw unexpected errors (auth, network) so they surface loudly.
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
// us-east-1 / "auto" regions must NOT send a LocationConstraint.
|
||||
await this.client.send(new CreateBucketCommand({ Bucket: bucket }));
|
||||
}
|
||||
|
||||
|
||||
async createUploadPlan(key: string, contentType: string, sizeBytes: number) {
|
||||
const partSizeBytes = 16 * 1024 * 1024;
|
||||
const partCount = Math.ceil(sizeBytes / partSizeBytes);
|
||||
|
||||
Reference in New Issue
Block a user