Flask url_for 没有在 docker/docker-compose 下组成正确的 url

Flask url_for doesn't compose correct url under docker/docker-compose

我在 Docker 容器 运行 中有一个 Flask 应用程序 运行。当我使用 url_for 为 API 创建外部 url 时,它 returns docker 服务名称而不是绝对路径。

例如

endpoint = url_for('api_v1.get_me_the_data', sn=123, 
                _external=True, _scheme="https")

returns 类似于 https://app-primary:8000/api/v1/devices/123

其他详情:

我试过 SERVER_NAME,但没有骰子。有没有简单的方法来解决这个问题?或者我应该为 url_for 编写一个包装函数吗?

由于您在容器内以及 Nginx 后面有 python 应用程序,因此您可能需要使用 ProxyFix,它会做两件事:

  • 通过阅读 REMOTE_ADDR
  • 获取客户端 IP 而不是 nginx 容器 IP
  • 通过阅读设置主机名HTTP_HOST

接下来您需要确保 nginx 发送这些 Headers:

proxy_set_header Host            $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

我有类似的问题。我正在使用 uwsgi 提供烧瓶应用程序,在另一个容器中与 nginx 交谈。我的密码重置功能发送了 links,其中包含容器名称而不是域名。 尝试使用 test_request_contest 和 'SERVER_NAME' 配置变量但惨遭失败。 link 仍在本地主机上。 最终对我有用的是一种快速(非常)肮脏的方法:

def create_external_link(link):
    # splits after 'http(s)'
    linkParts = link.split("//")
    linkLeft = linkParts[0]
    linkRight = linkParts[1]
    # from the right part (after 'http://') take whats after 'containerName/' doing only one split
    linkRight = linkRight.split("/",1)[1]
    fullLink = linkLeft + '//example.com/' + linkRight
    return fullLink

然后在创建 link 之前将其进一步传递给例如邮件模板:

link = create_external_link(url_for('blueprint.endpoint', **kwargs, _external=True))

一旦找到更好的解决方案,请尽快使用,这是一个丑陋的 hack。