Documents
Home>Documents>Dev>Backend

Self-Hosted S3-Compatible Image Storage with MinIO

5 min readFeb 21, 2026Feb 22, 2026

Why MinIO

Storing blog images requires object storage. AWS S3 is too costly, and a local filesystem doesn't scale. MinIO is an S3-compatible open-source storage solution that you can self-host.

MinIO Architecture

graph TD
    A[클라이언트 브라우저] -->|이미지 업로드| B[FastAPI Backend]
    B -->|저장| C[MinIO Server]
    C -->|URL 반환| B
    B -->|URL 저장| D[PostgreSQL]

    A -->|이미지 조회| E[Nginx]
    E -->|프록시| C

FastAPI MinIO Client

from minio import Minio

class MinIOStorage:
    def __init__(self):
        self.client = Minio(
            endpoint="minio:9000",
            access_key=os.environ["MINIO_ACCESS_KEY"],
            secret_key=os.environ["MINIO_SECRET_KEY"],
            secure=False
        )
        self.bucket = "blog-images"

    async def upload_image(self, file: UploadFile) -> str:
        file_id = str(uuid.uuid4())
        ext = file.filename.split('.')[-1]
        object_name = f"images/{file_id}.{ext}"

        self.client.put_object(
            self.bucket,
            object_name,
            file.file,
            file.size,
            content_type=file.content_type
        )
        return f"/storage/{object_name}"

Docker Compose Configuration

services:
  minio:
    image: minio/minio
    command: server /data --console-address ":9001"
    volumes:
      - minio_data:/data
    environment:
      MINIO_ROOT_USER: admin
      MINIO_ROOT_PASSWORD: password
    ports:
      - "9000:9000"
      - "9001:9001"

MinIO Usage in Contextifier

The early version of Contextifier uploaded PPT images to MinIO. That was later switched to local storage — it was simply too complex.

MinIO is a core infrastructure component actively used across multiple projects, including hr_blog2.0 and XGen.

Tags
MinIOS3ObjectStorageImageDocker