Перейти к содержанию

Хранилище S3

Приложение поддерживает любое S3-совместимое хранилище. Для переключения на S3:

cp .env.example .env
# отредактируй .env

Общие параметры

STORAGE_TYPE=s3
S3_BUCKET_NAME=<your-bucket>
S3_ACCESS_KEY_ID=<your-key>
S3_SECRET_ACCESS_KEY=<your-secret>
S3_REGION=<your-region>

# Endpoint URL (пустой для AWS)
S3_ENDPOINT_URL=https://<your-endpoint>

# Path-style addressing (True для MinIO, False для облачных провайдеров)
S3_FORCE_PATH_STYLE=False

# Время жизни presigned-ссылки в секундах (по умолчанию 1 час)
S3_PRESIGNED_EXPIRES=3600

Примеры для провайдеров

Yandex Cloud

S3_ENDPOINT_URL=https://storage.yandexcloud.net
S3_REGION=ru-central1
S3_BUCKET_NAME=<your-bucket>
S3_ACCESS_KEY_ID=<идентификатор_ключа>
S3_SECRET_ACCESS_KEY=<секретный_ключ>
S3_FORCE_PATH_STYLE=False

Ключи создаются в Yandex Cloud Console → Сервисные аккаунты → Создать ключ доступа.

AWS S3

S3_ENDPOINT_URL=              # оставь пустым!
S3_REGION=<your-region>
S3_BUCKET_NAME=<your-bucket>
S3_ACCESS_KEY_ID=<your-key>
S3_SECRET_ACCESS_KEY=<your-secret>
S3_FORCE_PATH_STYLE=False

Ключи — в AWS IAM → Users → Security credentials → Access keys.

MinIO (self-hosted / Docker)

S3_ENDPOINT_URL=http://<minio-host>:<minio-api-port>
S3_REGION=us-east-1
S3_BUCKET_NAME=<your-bucket>
S3_ACCESS_KEY_ID=<minio-user>
S3_SECRET_ACCESS_KEY=<minio-password>
S3_FORCE_PATH_STYLE=True

Запуск MinIO в Docker:

docker run -p 9000:9000 -p 9001:9001 \
  -e MINIO_ROOT_USER=<minio-user> \
  -e MINIO_ROOT_PASSWORD=<minio-password> \
  minio/minio server /data --console-address ":9001"

Создай бакет через MinIO Console (http://<minio-host>:<minio-console-port>) или mc mb.

Selectel

S3_ENDPOINT_URL=https://s3.selcloud.ru
S3_REGION=ru-1
S3_BUCKET_NAME=<your-bucket>
S3_ACCESS_KEY_ID=<your-key>
S3_SECRET_ACCESS_KEY=<your-secret>
S3_FORCE_PATH_STYLE=False

Как это работает

  1. Загрузка: файл через boto3.upload_fileobj() попадает в S3-бакет под уникальным ключом uploads/{uuid}.{ext}
  2. Скачивание: приложение генерирует presigned URL через generate_presigned_url() с заголовком Content-Disposition: attachment. Это работает даже если бакет приватный — ссылка действует S3_PRESIGNED_EXPIRES секунд.
  3. Удаление: при удалении документа из проекта файл удаляется из S3 через delete_object().