Docker运行uvicorn服务浏览器访问报ERR_CONNECTION_REFUSED错误
问题原因
连接被拒绝是两个核心配置错误共同导致的:
- 服务监听地址配置错误:从启动日志可以看到uvicorn默认绑定了
127.0.0.1地址,这个地址是容器内部的本地回环地址,仅能接收容器内部进程发起的请求,宿主机的请求无法到达该监听端口。服务要对外提供访问必须绑定0.0.0.0地址,接收所有网卡的入站请求。 - Docker端口未做映射:运行容器时没有添加端口映射参数,容器是网络隔离的环境,内部监听的端口默认不会对宿主机开放,必须显式指定端口映射规则,才能把容器内的端口绑定到宿主机端口上。
修复步骤
按顺序修改配置即可解决问题:
- 修改
main.py中的uvicorn启动参数,显式指定监听地址为0.0.0.0,修改最后一段启动代码为:
修改后重新启动服务,看到日志输出if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=int(os.environ['PORT']))Uvicorn running on http://0.0.0.0:5000就说明监听地址配置正确。 - 重新构建Docker镜像,让代码修改在镜像中生效:
docker build -t memeified-docker-server . - 运行容器时添加
-p参数做端口映射,将宿主机的5000端口映射到容器的5000端口:
执行完这步再在宿主机访问docker run -p 5000:5000 memeified-docker-serverhttp://127.0.0.1:5000就能正常连通了。
额外提示(不影响本次连接问题,但会导致后续功能异常):
- 当前CORS中间件的
allow_headers配置格式错误,传入的是一整个长字符串而非列表,会导致跨域请求校验失败,建议修改为:app.add_middleware( CORSMiddleware, allow_origins=['*'], allow_headers=["Origin", "X-Requested-With", "Content-Type", "Accept"], ) /entries接口中的for循环是多余逻辑,遍历结果集时第一次循环就会执行return,虽然现在返回结果看起来正常,但属于无意义的冗余代码,直接返回结果即可:@app.get('/entries') def getEntries(): client = MongoClient(CONNECTION_URL) databaseMongo = client.get_database(DATABASE_NAME) collectionMongo = databaseMongo.get_collection(NEWS_COLLECTION) result = list(collectionMongo.find()) return {'data': result}
内容的提问来源于stack exchange,提问作者cyruslk
相关产品推荐
相关产品推荐

