(已解决)MinIO python 获取预签名出现forbidden、errornetwork等错误

时间是26年6月13日

环境是docker minio latest

场景是使用python minio sdk 向minio创建桶,然后获取预签名。

先说最终配置

docker-compose.yml

复制代码
minio:
    image: ${MINIO_IMAGE}
    container_name: minio
    restart: unless-stopped
    volumes:
      - /root/data/docker_data/minio/data:/data
    ports:
      - "9000:9000"
      - "9001:9001"
    environment:
      MINIO_ROOT_USER: ${IMG_BED_ACCESS_KEY}
      MINIO_ROOT_PASSWORD: ${IMG_BED_SECRET_KEY}
      MINIO_API_CORS_ALLOW_ORIGIN: "*"
    command: server /data --address ":9000" --console-address ":9001"
backend:
    build:
      context: ./backend
      dockerfile: Dockerfile
    restart: unless-stopped
    volumes:
      - ./backend:/app
    depends_on:
      minio:
        condition: service_healthy
    environment:
      IMG_BED_ENDPOINT: ${IMG_BED_ENDPOINT}
      MINIO_PUBLIC_BASE_URL: ${MINIO_PUBLIC_BASE_URL}
      IMG_BED_ACCESS_KEY: ${IMG_BED_ACCESS_KEY}
      IMG_BED_SECRET_KEY: ${IMG_BED_SECRET_KEY}
      IMG_BED_BUCKET_NAME: ${IMG_BED_BUCKET_NAME}
      IMG_BED_SECURE: ${IMG_BED_SECURE}
      IMG_BED_TIMEOUT: ${IMG_BED_TIMEOUT}
      IMG_BED_STARTUP_WARMUP: ${IMG_BED_STARTUP_WARMUP}
    ports:
      - "8000:8000"

与docker-compose.yml同一目录下的.env

复制代码
# MinIO 图床服务配置

# 返回给前端的图床地址(生产环境用外网域名,本地开发用127.0.0.1)
MINIO_PUBLIC_BASE_URL=http://127.0.0.1:9000

IMG_BED_ENDPOINT=minio:9000

IMG_BED_ACCESS_KEY=night_school
IMG_BED_SECRET_KEY=night_school
IMG_BED_BUCKET_NAME=night-school
IMG_BED_SECURE=false
IMG_BED_TIMEOUT=15
# 是否在启动服务器时预热图床服务
IMG_BED_STARTUP_WARMUP=true


# MinIO 镜像配置
MINIO_IMAGE=minio/minio:latest

敲重点

IMG_BED_ENDPOINT是python后端访问minio用的网址,也就是dockercompose容器之间的访问,必须写minio:9000,不能用127.0.0.1,因为每一个容器就是一个独立ip,python容器的127.0.0.1回环地址找不到minio容器。

MINIO_PUBLIC_BASE_URL是外界访问minio用的网址,也是预签名需要携带的网址,自己本地开发则写127.0.0.1,如果是生产环境则写域名,然后用nginx代理到minio开放的端口就行。

根据上面两个网址,在python后端分别创建client,一个连接minio用于创建桶、修改策略等事务,另一个用于获取预签名。

分别对应下面的代码

复制代码
def _get_client(self) -> Minio:
        if self._client is None:
            logger.info("正在初始化 MinIO 图床服务")
            self._client = Minio(
                endpoint=self.endpoint,
                access_key=self.access_key,
                secret_key=self.secret_key,
                secure=self.secure,
            )
        return self._client

    def _get_presign_client(self) -> Minio:
        """返回用于生成预签名 URL 的客户端(使用公网地址签名,确保浏览器可访问)。"""
        if self._presign_client is not None:
            return self._presign_client
        public_endpoint = self._public_endpoint
        if public_endpoint == self.endpoint:
            self._presign_client = self._get_client()
        else:
            # region 必须指定,否则 Minio 会自动 GET /{bucket}?location= 探测区域
            self._presign_client = Minio(
                endpoint=public_endpoint,
                access_key=self.access_key,
                secret_key=self.secret_key,
                secure=self._public_secure,
                region="cn-guangzhou",
            )
        return self._presign_client

第一个访问客户端是会连接minio的,所以必须指定IMG_BED_ENDPOINT

第二个是获取预签名让外网访问minio的,所以必须指定为公网域名MINIO_PUBLIC_BASE_URL

第二个只是做了参数的配置,然后本地生成签名,没有实际连接或者调用minio,所以不会因为endpoint不正确就报错。

相关推荐
AI你一生一世2 小时前
不止于时序存储:DolphinDB 如何成为 AI 时代的工业智能底座
java·人工智能·struts·时序数据库·工业智能·dolphindb·ai基础设施
belldeep2 小时前
python:genesis-world, Genesis-Embodied-AI
人工智能·python·ai·genesis
布莱克6052 小时前
C/C++ 中变量的声明与定义:区别、联系与常见误区
c语言·开发语言·c++·声明·定义
云-缩影2 小时前
拆解 AI 图像生成应用的后端架构:ECS、OSS 和大模型 API 怎么配合
java·spring boot·后端
LabVIEW开发2 小时前
LabVIEW 局部变量为何引发竞争条件?四种同步机制
开发语言·labview
瑞克-桑切斯2 小时前
7、MySQL 慢查询排查与优化实战指南
java·服务器·数据库
benchmark_cc3 小时前
A 股、港股、美股如何建立统一的标的主数据格式?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
维克兜率天3 小时前
【维克】趋势型CTA:期货市场的“追涨杀跌“
人工智能·python
Zenova EdgeOS4 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
取名真是4 小时前
Python 算法知识点从基础到进阶
开发语言·python·算法