老实说,要想让 Dify 稳定持久地保存用户上传的 PDF、TXT、图片等媒体文件,默认的本地存储方案基本难以胜任。容器一旦重启,文件就可能丢失;多实例运行时,知识库数据无法同步;甚至预览时也会直接报错。这些问题,只要采用 S3 独立存储方案,就能从根本上得到解决。
具体而言,有几个关键配置必须到位:确认 S3 服务可用,创建一个合规的存储桶(比如dify-media),然后在配置文件里将STORAGE_TYPE改为s3,再依次填写S3_ENDPOINT、S3_REGION(通常是us-east-1)、S3_ACCESS_KEY和S3_SECRET_KEY。最后通过日志验证,只要能看见"Using S3 storage provider"且没有报错,就算大功告成。

确认S3服务可用并创建合规存储桶
首先,打开浏览器,访问你的 S3 兼容服务地址。例如,如果使用的是 MinIO,控制台地址就是http://192.168.1.100:9001,用管理员账号登录。
登录后,点击左侧的「Buckets」,然后选择「Create Bucket」。输入桶名,比如【dify-media】。这里有一个注意事项:桶名只能包含小写字母、数字和连字符(-),不能出现下划线、大写字母或点号。否则 Dify 启动时 S3 签名校验会直接失败,导致服务无法启动。
桶创建完成后,切勿随意修改桶策略。尤其是 MinIO v1.9+ 版本,默认启用了 strict 模式。自定义策略很容易把必需的s3:GetObject和s3:ListBucket权限覆盖掉,导致后续文档预览或解析异常中断。
修改Dify的.env配置启用S3存储
接下来,进入 Dify 的项目目录,找到docker/.env文件进行编辑。通常路径为/opt/dify/docker/.env。
找到STORAGE_TYPE所在区域,按顺序将以下五项配置修改正确:
① STORAGE_TYPE=s3,原来的值一般是local或opendal,直接改为s3即可。
② S3_ENDPOINT=http://192.168.1.100:9000,注意如果 S3 服务与 Dify 不在同一台宿主机上,必须填写真实的内网 IP,不能使用 localhost。并且地址要以http://开头,尾部不要带斜杠,也不要用https。
③ S3_REGION=us-east-1,MinIO 只识别这个值。填错的话启动时会报signaturedoesnotmatch错误。
④ S3_ACCESS_KEY=admin,必须与 S3 控制台的登录用户名完全一致,大小写也要严格区分。复制时需特别注意是否包含不可见的 Unicode 空格。
⑤ S3_SECRET_KEY=admin123456,如果密钥中包含$或@等特殊字符,在docker compose配置中需要用双引号将其包裹起来。
验证S3配置是否生效
配置修改完成后,先执行docker compose down停止当前服务。
然后再执行docker compose up -d重新启动所有容器。
等待约 20 秒,让服务完全启动。接着运行docker compose logs -f dify-api | grep "s3|storage"查看日志。如果能看到Using S3 storage provider,且没有出现failed to connect或signaturedoesnotmatch等报错信息,就说明配置已成功加载。这一步非常关键,建议所有管理员在修改配置后务必花两分钟验证,以免后续出现问题时需要从头排查。
