使用 Apache2 代理服务器部署 Flask 应用程序

发布于 2025-01-10 14:15:01 字数 1403 浏览 0 评论 0原文

我正在尝试使用 Gunicorn 和 Apache2 中的代理服务器部署 Flask 应用程序。 Flask 应用程序在 Docker 容器中运行,但不在 Apache2 服务器中运行。

这是 Apache2 的配置。

<Macro DemoSubdomain $subdomain_name $proxy_pass_proto $proxy_pass_to>
<VirtualHost *:443>
    ServerName $subdomain_name.example.com

    ProxyPass / $proxy_pass_proto://$proxy_pass_to
    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule ^/?(.*) "ws://$proxy_pass_to/$1" [P,L]

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

    SSLEngine on
    SSLCertificateFile      /root/example.com-crt.pem
    SSLCertificateKeyFile   /root/example.com-key.pem
    SSLCertificateChainFile /root/example.com-chain.pem
</VirtualHost>
</Macro>

当 Config 中未指定 'SERVER_NAME' 时,Flask 应用程序在 'subdomain_name.example.com' 中运行,但是当调用重定向函数时,它会重定向到 localhost:17000

因此,在 Flask 应用程序中,我将 config['SERVER_NAME'] 设置为“subdomain_name.example.com”并运行 Gunicorn。但是,我收到以下错误。

/usr/local/lib/python3.10/site-packages/flask/app.py:1777: UserWarning: Current server name 'localhost:17000' doesn't match configured server name 'subdomain_name.example.com'
app_1    |   return self.url_map.bind_to_environ(
app_1    | ERROR:some_app.app.app:Exception on / [GET]

我该如何解决这个问题?

I'm trying to deploy a Flask application with Gunicorn with a Proxy Server in Apache2. The Flask application is running in a Docker container but not the Apache2 server.

Here is the configuration for Apache2.

<Macro DemoSubdomain $subdomain_name $proxy_pass_proto $proxy_pass_to>
<VirtualHost *:443>
    ServerName $subdomain_name.example.com

    ProxyPass / $proxy_pass_proto://$proxy_pass_to
    RewriteEngine on
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule ^/?(.*) "ws://$proxy_pass_to/$1" [P,L]

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

    SSLEngine on
    SSLCertificateFile      /root/example.com-crt.pem
    SSLCertificateKeyFile   /root/example.com-key.pem
    SSLCertificateChainFile /root/example.com-chain.pem
</VirtualHost>
</Macro>

The Flask application runs in the 'subdomain_name.example.com' when 'SERVER_NAME' is not specified in Config, however when calling redirect function, it redirects to localhost:17000.

So, in Flask application, I set the config['SERVER_NAME'] to 'subdomain_name.example.com' and run Gunicorn. But, I am getting the following error.

/usr/local/lib/python3.10/site-packages/flask/app.py:1777: UserWarning: Current server name 'localhost:17000' doesn't match configured server name 'subdomain_name.example.com'
app_1    |   return self.url_map.bind_to_environ(
app_1    | ERROR:some_app.app.app:Exception on / [GET]

How do I resolve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

滴情不沾 2025-01-17 14:15:01

如果您的目标是使用 https 设置一个简单的网站,我可以提供我已采取的步骤。

假设:

  • 服务器是一个“新的 Ubuntu 映像”(即在 Raspberry Pi 上)
  • 您有一个 Python Flask 应用程序
  • 您希望服务器托管 https 流量
  • 您拥有一个域名称(即 example.com)

步骤 0.

  • 配置服务器以允许 SSH 流量
# Tell Universal Firewall (ufw) to Allow SSH connections (on the server)
sudo ufw allow 22
sudo apt update
sudo reboot

步骤 1.

  • 启动 Flask 应用程序(并通过公共 IP 公开其端口)
# Connect to the server using SSH
ssh [email protected]
# Create some directories
mkdir repos/
mkdir downloads/
mkdir -p secrets/example/
# Install Python3
sudo apt-get install python3-pip
# Install Virtualenv to avoid overlapping dependencies between different python scripts
sudo apt-get install python3-virtualenv
# Create a virtual environment
virtualenv .venv/
# Enter the virtual environment
. .venv/bin/activate
# type 'deactivate' to exit the virtual environment
####################################################
#####   TESTING FIREWALL/CONFIGURING PORTS   #######
####################################################
cd repos
# Run any app to debug your firewall's effect on Ports & Public IP Address
git clone https://github.com/org-not-included/simple_flask_app
cd simple_flask_app
# Install requirements
pip3 install -r requirements.txt
# Run script in background, and write terminal output to logs
python3 main.py &> server_run_details.log & disown
# type 'cat server_run_details.log' to see the logs
# Tell ufw to Allow connections on port 4020 
sudo ufw allow 4020

通过本地 IP 测试端口

curl -X GET http://127.0.0.1:4020
# If your server has a built-in GUI/Desktop View, in a browser you can visit:
http://127.0.0.1:4020

通过 公共IP

  • 跳到文件底部(shift+g)
  • 更新'127.0.0.1'-> '0.0.0.0' (i)
  • 保存并退出 (esc :wq! Enter)
sudo vi main.py
sudo fuser -k 4020/tcp
python3 main.py &> server_run_details.log & disown
# Try hitting the public IP in a terminal
curl -X GET http://servers.public.ip.addr:4020
# Or visit the website in a browser
http://servers.public.ip.addr:4020
# Congrats your Firewall works


恭喜,您已确认您的服务器能够提供 http 流量(通过 http://[公共 IP]:[端口]< /code>)


步骤 2.

  • 设置域名,以便用户可以访问 (http://)www.example.com 而不是 http://servers.public.ip.addr :4020。

步骤 2A:

  • 告诉 DNS 提供商托管(子)域的 IP 地址
####################################################
####  CONFIGURING A DOMAIN NAME  (example.com)  ####
####################################################
# Tell your Domain Management Provider (porkbun.com, godaddy.com, etc) to point your domain name at your Public IP:
# - visit your Domain Management Provider
# - update the A Record's ANSWER to your Public IP
# - delete the CNAME Record
####################################################

步骤 2B:

  • 设置 apache2 将(子)域的流量重定向到适当的端口
# Tell ufw to Allow traffic over http (ie. port 80)
sudo ufw allow http
sudo apt update
# Install apache2
# apache2 allows your server to map the domain name to a (flask app) process running on http://localhost:[port]
sudo apt install apache2
# Remove everything from the default configuration and add your mapping for http traffic
### <VirtualHost *:80>
###         ServerName example.com
###         ServerAlias www.example.com
###         ProxyRequests Off
###         ProxyPreserveHost On
###         ProxyPass / http://localhost:4020/
###         ProxyPassReverse / http://localhost:4020/
### </VirtualHost>
sudo vi /etc/apache2/sites-available/000-default.conf 
# Install apache2 dependencies 
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_ajp
sudo a2enmod proxy_balancer
sudo a2enmod proxy_connect
sudo a2enmod proxy_html
sudo a2enmod ssl
# Tell apache2 to stop running 
sudo a2dissite 000-default.conf
# Tell apache2 to start running 
sudo a2ensite 000-default.conf
# Have the system manager restart apache2
sudo systemctl reload apache2
# Check the server logs
sudo systemctl status apache2.service

步骤 2C:

  • 测试和配置故障排除
Visit your domain in web browser:
- example.com 
- www.example.com
- http://www.example.com

# Is Apache2 is running okay?
sudo systemctl status apache2.service
# If not
## Edit Apache2 Config
sudo vi /etc/apache2/sites-available/000-default.conf 
## Restart apache2
sudo a2dissite 000-default.conf
sudo a2ensite 000-default.conf
sudo systemctl reload apache2

# Is Apache2 is running okay?
sudo systemctl status apache2.service
# If not, go to Step 2C (insert recursion joke here)

# Is your app running okay?
curl -X GET http://example.com/

# Does http work in the web browser?
http://example.com

恭喜,您已确认您的服务器能够提供 http 流量(通过 http://example.com)!


步骤 3.

  • 从您的域管理提供商下载SSH 捆绑包

步骤 4.

  • 将 SSH Bundle 的文件复制到您的服务器
scp -r /local/directory/ [email protected]:/home/ubuntu/secrets/example/

步骤 5.

  • 更新您的 apache2 配置以使用 https 流量而不是 http:
<VirtualHost *:443>
        ServerName example.com
        ServerAlias www.example.com
        SSLEngine on
        SSLCertificateFile /home/ubuntu/secrets/example/domain.cert.pem
        SSLCertificateKeyFile /home/ubuntu/secrets/example/private.key.pem
        SSLCertificateChainFile /home/ubuntu/secrets/example/intermediate.cert.pem
        ProxyRequests Off
        ProxyPreserveHost On
        ProxyPass / http://localhost: 4020
        ProxyPassReverse / http://localhost: 4020/
</VirtualHost>
sudo vi /etc/apache2/sites-available/000-default.conf
# Restart Apache2
sudo a2dissite 000-default.conf
sudo a2ensite 000-default.conf
sudo systemctl reload apache2
# Is Apache2 is running okay?
sudo systemctl status apache2.service
# Are you able to visit the SSL version in browser?
https://www.example.com


恭喜,您已确认您的服务器能够提供 https 流量(通过 https://example.com)。 com)!


步骤 6.

  • 清理

杀死 Simple Flask 应用程序:

sudo fuser -k 4020/tcp

删除示例存储库:

cd ..
rm -rf simple_flask_app

从 apache2 配置中删除示例

sudo vi /etc/apache2/sites-available/000-default.conf

If your goal is to setup a simple website with https, I can offer the steps I've taken.

Assumptions:

  • Server is a "New Ubuntu Image" (ie. on a Raspberry Pi)
  • You have a Python Flask app
  • You want the server to host https traffic
  • You own a domain name (ie. example.com)

Step 0.

  • Configure the server to allow SSH traffic
# Tell Universal Firewall (ufw) to Allow SSH connections (on the server)
sudo ufw allow 22
sudo apt update
sudo reboot

Step 1.

  • Launch Flask App (and expose its port over Public IP)
# Connect to the server using SSH
ssh [email protected]
# Create some directories
mkdir repos/
mkdir downloads/
mkdir -p secrets/example/
# Install Python3
sudo apt-get install python3-pip
# Install Virtualenv to avoid overlapping dependencies between different python scripts
sudo apt-get install python3-virtualenv
# Create a virtual environment
virtualenv .venv/
# Enter the virtual environment
. .venv/bin/activate
# type 'deactivate' to exit the virtual environment
####################################################
#####   TESTING FIREWALL/CONFIGURING PORTS   #######
####################################################
cd repos
# Run any app to debug your firewall's effect on Ports & Public IP Address
git clone https://github.com/org-not-included/simple_flask_app
cd simple_flask_app
# Install requirements
pip3 install -r requirements.txt
# Run script in background, and write terminal output to logs
python3 main.py &> server_run_details.log & disown
# type 'cat server_run_details.log' to see the logs
# Tell ufw to Allow connections on port 4020 
sudo ufw allow 4020

Testing Port via Local IP

curl -X GET http://127.0.0.1:4020
# If your server has a built-in GUI/Desktop View, in a browser you can visit:
http://127.0.0.1:4020

Testing Port via Public IP:

  • skip to bottom of file (shift+g)
  • update '127.0.0.1' -> '0.0.0.0' (i)
  • save and quit (esc :wq! enter)
sudo vi main.py
sudo fuser -k 4020/tcp
python3 main.py &> server_run_details.log & disown
# Try hitting the public IP in a terminal
curl -X GET http://servers.public.ip.addr:4020
# Or visit the website in a browser
http://servers.public.ip.addr:4020
# Congrats your Firewall works


Congrats, you've confirmed your server is able to serve http traffic (via http://[Public IP]:[Port])


Step 2.

  • Setup a domain name, so users can visit (http://)www.example.com instead of http://servers.public.ip.addr:4020.

Step 2A:

  • Tell DNS Provider to which IP Address hosts the (sub)domain
####################################################
####  CONFIGURING A DOMAIN NAME  (example.com)  ####
####################################################
# Tell your Domain Management Provider (porkbun.com, godaddy.com, etc) to point your domain name at your Public IP:
# - visit your Domain Management Provider
# - update the A Record's ANSWER to your Public IP
# - delete the CNAME Record
####################################################

Step 2B:

  • Setup apache2 to redirect traffic for (sub)domain to the appropriate port
# Tell ufw to Allow traffic over http (ie. port 80)
sudo ufw allow http
sudo apt update
# Install apache2
# apache2 allows your server to map the domain name to a (flask app) process running on http://localhost:[port]
sudo apt install apache2
# Remove everything from the default configuration and add your mapping for http traffic
### <VirtualHost *:80>
###         ServerName example.com
###         ServerAlias www.example.com
###         ProxyRequests Off
###         ProxyPreserveHost On
###         ProxyPass / http://localhost:4020/
###         ProxyPassReverse / http://localhost:4020/
### </VirtualHost>
sudo vi /etc/apache2/sites-available/000-default.conf 
# Install apache2 dependencies 
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_ajp
sudo a2enmod proxy_balancer
sudo a2enmod proxy_connect
sudo a2enmod proxy_html
sudo a2enmod ssl
# Tell apache2 to stop running 
sudo a2dissite 000-default.conf
# Tell apache2 to start running 
sudo a2ensite 000-default.conf
# Have the system manager restart apache2
sudo systemctl reload apache2
# Check the server logs
sudo systemctl status apache2.service

Step 2C:

  • Testing & Troubleshooting
Visit your domain in web browser:
- example.com 
- www.example.com
- http://www.example.com

# Is Apache2 is running okay?
sudo systemctl status apache2.service
# If not
## Edit Apache2 Config
sudo vi /etc/apache2/sites-available/000-default.conf 
## Restart apache2
sudo a2dissite 000-default.conf
sudo a2ensite 000-default.conf
sudo systemctl reload apache2

# Is Apache2 is running okay?
sudo systemctl status apache2.service
# If not, go to Step 2C (insert recursion joke here)

# Is your app running okay?
curl -X GET http://example.com/

# Does http work in the web browser?
http://example.com

Congrats, you've confirmed your server is able to serve http traffic (via http://example.com)!


Step 3.

  • Download an SSH Bundle from your Domain Management Provider.

Step 4.

  • Copy SSH Bundle's files to your server
scp -r /local/directory/ [email protected]:/home/ubuntu/secrets/example/

Step 5.

  • Update your apache2 config to use https traffic instead of http:
<VirtualHost *:443>
        ServerName example.com
        ServerAlias www.example.com
        SSLEngine on
        SSLCertificateFile /home/ubuntu/secrets/example/domain.cert.pem
        SSLCertificateKeyFile /home/ubuntu/secrets/example/private.key.pem
        SSLCertificateChainFile /home/ubuntu/secrets/example/intermediate.cert.pem
        ProxyRequests Off
        ProxyPreserveHost On
        ProxyPass / http://localhost: 4020
        ProxyPassReverse / http://localhost: 4020/
</VirtualHost>
sudo vi /etc/apache2/sites-available/000-default.conf
# Restart Apache2
sudo a2dissite 000-default.conf
sudo a2ensite 000-default.conf
sudo systemctl reload apache2
# Is Apache2 is running okay?
sudo systemctl status apache2.service
# Are you able to visit the SSL version in browser?
https://www.example.com


Congrats, you've confirmed your server is able to serve https traffic (via https://example.com)!


Step 6.

  • Cleanup

Kill the Simple Flask App:

sudo fuser -k 4020/tcp

Remove the example Repo:

cd ..
rm -rf simple_flask_app

Delete example from apache2 config

sudo vi /etc/apache2/sites-available/000-default.conf
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文