VPS中Docker部署Flask API:HTTP正常HTTPS无法访问求助
问题分析
你遇到的核心问题是:客户端向仅支持HTTP的Flask服务发起了HTTPS请求。容器内的Flask默认以HTTP模式运行,未配置SSL处理能力,当你用https://访问8080端口时,Postman会先发起SSL握手,但Flask无法识别这些SSL协议数据,将其判定为格式错误的HTTP请求,因此返回400错误,同时Postman因SSL握手失败抛出WRONG_VERSION_NUMBER异常。
解决方案
由于你的VPS已经通过Certbot配置了Apache和SSL证书,推荐使用Apache反向代理来实现HTTPS访问,这是最安全且易维护的方案;也可以选择让Flask直接处理SSL(不推荐),两种方案如下:
方案一:Apache反向代理(推荐)
利用已有的Apache SSL站点,将HTTPS请求转发给容器内的HTTP服务:
- 启用Apache必要模块
sudo a2enmod proxy proxy_http ssl - 编辑Apache SSL站点配置
打开Certbot生成的SSL站点配置文件(路径通常为/etc/apache2/sites-available/your-domain-le-ssl.conf),在<VirtualHost *:443>块中添加反向代理规则:# 示例:将https://your-domain/api/* 转发到容器的8080端口 ProxyPass /api http://localhost:8080 ProxyPassReverse /api http://localhost:8080 # 如果希望根路径直接映射,替换为: # ProxyPass / http://localhost:8080 # ProxyPassReverse / http://localhost:8080 - 重启Apache服务
sudo systemctl restart apache2 - 验证访问
现在可以通过https://myapphostwebsite.com/api/user/12345(或根路径)访问接口,无需再指定8080端口。若想进一步提高安全性,可将容器的端口映射改为仅绑定本地回环地址,避免HTTP服务直接暴露:docker run --rm -it -p 127.0.0.1:8080:5000 myapp:latest
方案二:Flask直接处理SSL(不推荐)
若不想使用反向代理,可让Flask加载Certbot生成的证书直接以HTTPS模式运行:
- 复制证书到容器可访问目录
将Certbot生成的证书文件(路径通常为/etc/letsencrypt/live/your-domain/下的fullchain.pem和privkey.pem)复制到VPS的某个目录(如/opt/certs)。 - 启动容器时挂载证书并启用SSL
docker run --rm -it -p 8080:5000 -v /opt/certs:/certs myapp:latest flask --app=app run --host=0.0.0.0 --ssl-cert=/certs/fullchain.pem --ssl-key=/certs/privkey.pem - 验证访问
此时可通过https://myapphostwebsite.com:8080/user/12345访问,但该方案需要维护容器内的证书文件,灵活性和安全性不如反向代理。
内容的提问来源于stack exchange,提问作者kabrice
相关产品推荐
相关产品推荐

