NestJS连接LocalStack S3出现Connection refused错误(127.0.0.1:4566)
解决NestJS容器连接LocalStack S3出现ECONNREFUSED错误
问题根源
Docker容器拥有独立的网络命名空间,容器内的localhost指向容器自身,而非宿主机或其他容器。你的NestJS应用容器(test-app)尝试通过localhost.localstack.cloud:4566或localhost:4566访问LocalStack,但这两个地址在容器内部无法定位到LocalStack容器,导致连接被拒绝。
解决方案
1. 修改S3Client的Endpoint配置
直接使用LocalStack容器的名称(localstack)作为地址,Docker自定义网络会自动将容器名解析为对应IP。同时,容器间通信无需HTTPS,改用HTTP即可:
import { S3Client } from '@aws-sdk/client-s3'; import type { Provider } from '@nestjs/common'; export const S3_CLIENT_TOKEN = 'S3Client'; export const s3ClientProvider: Provider = { provide: S3_CLIENT_TOKEN, useValue: new S3Client({ endpoint: 'http://localstack:4566', // 改用容器名+HTTP协议 region: 'ap-northeast-1', credentials: { accessKeyId: 'test', // LocalStack要求非空密钥,任意字符串即可 secretAccessKey: 'test', }, forcePathStyle: true, // 必须开启,适配LocalStack的S3路径访问规则 }), };
注意:LocalStack不允许凭证字段为空,即使是测试场景也需要填写任意非空字符串;
forcePathStyle设为true是必须的,否则S3客户端会使用虚拟主机风格访问,与LocalStack默认配置不兼容。
2. 验证LocalStack服务状态
确保LocalStack容器正常启动并运行S3服务:
- 执行
docker logs localstack查看容器日志,确认出现Ready.标识 - 从宿主机执行
curl http://localhost:4566/health,检查返回结果中s3服务状态为running
3. 确认容器网络归属
验证两个容器都加入了ls自定义网络:
- 执行
docker network inspect ls,查看Containers节点下是否同时包含test-app和localstack
额外提示
- 容器间通信不需要依赖宿主机的端口映射(
4566:4566),该映射仅用于宿主机直接访问LocalStack - 如果需要从宿主机测试NestJS应用的上传功能,需为
test-app容器添加端口映射(例如3000:3000)
内容的提问来源于stack exchange,提问作者K.Hayashi
相关产品推荐
相关产品推荐

