运行 两个不同域上的两个 Flask 应用程序使用 apache2 和 WSGI

Running two Flask apps on two different domains using apache2 and WSGI

我在 Ubuntu 18.04 上有两个 python (3.6) Flask 应用程序 运行,我正在尝试使用 Apache2 (v2.4.29) 将这两个应用程序提供给两个不同的应用程序域 – app1domain.com 和 app2domain.com。我有两个 .conf 文件,我一直在尝试修改它们以使其正常工作。它们目前看起来像这样(第二个用 app2 替换 app1):

WSGIDaemonProcess app1 python-home=/var/www/app1/venv user=brett group=sudo home=/ threads=5
WSGIScriptAlias / /var/www/app1/app.wsgi
WSGIProcessGroup app1
WSGIApplicationGroup %{GLOBAL}

<VirtualHost *:80>

    ServerAdmin myemail@outlook.com
    ServerName app1domain.com
    ServerAlias www.app1domain.com

    <Directory /var/www/app1>
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =app1domain.com [OR]
    RewriteCond %{SERVER_NAME} =www.app1domain.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

<VirtualHost *:443>

        ServerName app1domain.com
        ServerAlias www.app1domain.com
        ServerAdmin myemail@outlook.com

        LogLevel debug
        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        Include /etc/letsencrypt/options-ssl-apache.conf

        SSLCertificateFile /etc/letsencrypt/live/app1domain.com/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/app1domain.com/privkey.pem
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

这是我卡住的地方,这是我尝试过的方法:

  1. 如果两个 conf 文件都采用上面显示的格式,app1 将提供给两个 https://app1domain.com and https://app2domain.com,而 app2 将不会显示。
  2. 如果我禁用 app1 的 conf,app2 将提供给两者 https://app1domain.com and https://app2domain.com,这表明至少 conf 文件 'work' 和应用程序都正常工作。
  3. 根据我的调查,我发现很多 conf 文件的 <VirtualHost> 标签内都有 WSGI 指令。如果我对两个 confs 都这样做,默认的 Apache2 页面将显示在两个域上。
  4. 我已经尝试了 <VirtualHost> 标签以及嵌套的 <Directory> 标签内外的几乎所有 WSGI 指令组合。大多数只是导致默认的 apache2 页面。

我是否遗漏了其他需要更改的选项?我在这里做错了什么?

我也一直在寻找一些关于如何解释这些 conf 文件的好文档,选项的实际作用,所以如果有人能指出我一些东西,特别是如果它涵盖 WSGI,我会很高兴。

事后看来很明显。原来这个问题是我盲目相信 certbot 自动生成新的 VirtualHost 和重定向的结果,而我并没有真正考虑它是如何工作的。

如果您查看问题中的示例 .conf 文件,它起作用的原因是因为 WSGI 指令是在 <VirtualHost> 标记的范围之外创建的,这允许它们被两者拾取虚拟主机。但与此同时,因为它们是全局创建的,所以 .conf 文件中的 WSGI 指令按字母顺序首先覆盖其他指令,因此 app1 出现在 app1domain.com 和 app2domain.com.

当我将 WSGI 指令移动到 <VirtualHost> 标签内时,我将它移动到 <VirtualHost *:80> 标签内,因为我发现的所有示例都是这样做的(因为它们没有使用 SSL ).当我这样做时,RewriteEngine 没有 运行ning 应用程序,而是将请求重定向到网站的 https 版本。由 <VirtualHost *:443> 获取,您会注意到我没有关于如何 运行 该应用程序的说明,因此我们得到一个默认页面。

最后我重写了我的.conf文件如下:

<VirtualHost *:80>

    ServerAdmin myemail@outlook.com
    ServerName app1domain.com
    ServerAlias www.app1domain.com

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    RewriteEngine on
    RewriteCond %{SERVER_NAME} =app1domain.com [OR]
    RewriteCond %{SERVER_NAME} =www.app1domain.com
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

<VirtualHost *:443>

    ServerName app1domain.com
    ServerAlias www.app1domain.com
    ServerAdmin myemail@outlook.com

    WSGIDaemonProcess app1 python-home=/var/www/app1/venv user=brett group=sudo home=/ threads=5
    WSGIScriptAlias / /var/www/app1/app.wsgi

    <Directory /var/www/app1>
        WSGIProcessGroup app1
        WSGIApplicationGroup %{GLOBAL}
        Require all granted
    </Directory>

    LogLevel debug
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    Include /etc/letsencrypt/options-ssl-apache.conf

    SSLCertificateFile /etc/letsencrypt/live/app1domain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/app1domain.com/privkey.pem

</VirtualHost>