2022年12月13日 星期二

在 Rocky Linux 8上搭建 Flask Web 產品環境

學習目標:
  • 在 Rocky Linux 8 平台上,使用 Nginx + Gunicorn 平台,搭建 Flask Web 產品環境。
  • 使用 Python 3.9 版本。
  • 預備知識:Rocky Linux 8 作業系統安裝與設定。

實作流程
  1. 在 Rocky Linux 8 上,設置 Python 3.9 版本:
    # alternatives --list
    # dnf module -y install python39
    # alternatives --list
    # alternatives --config python
    # alternatives --config python3
    There are 2 programs which provide 'python3'.
    
      Selection    Command
    -----------------------------------------------
    *  1           /usr/bin/python3.6
     + 2           /usr/bin/python3.9
    
    Enter to keep the current selection[+], or type selection number: 2
    
    # yum install -y python39-*
    
  2. 安裝 Nginx 服務 Web 套件,使用 v1.20 版本:
    # dnf module reset nginx:1.20
    # dnf module enable nginx:1.20
    # dnf module switch-to nginx:1.20
    # dnf module list nginx
    # yum install nginx-*
    
  3. 安裝 Flask 與 Gunicorn 套件:
    # pip3 install flask gunicorn
    
  4. 建立與設定 Flask 產品環境目錄:
    # mkdir -p /usr/share/nginx/webapp
    # semanage fcontext -a -t httpd_sys_content_t "/usr/share/nginx/webapp(/.*)?"
    # restorecon -Rvv /usr/share/nginx/webapp
    
  5. 試作兩個運行的檔案 application.py 與 wsgi.py:
    # vim /usr/share/nginx/webapp/application.py
    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return 'Hello World!'
    
    # vim /usr/share/nginx/webapp/wsgi.py
    from application import app
    
    if __name__ == '__main__':
        app.run(debug=False)
    
    # restorecon -Rvv /usr/share/nginx/webapp
    
  6. 測試 Flask 與 Gunicorn 是否可以正常運作:(使用溜覽器觀看結果)
    # cd /usr/share/nginx/webapp
    # flask run --host '0.0.0.0'
    (停止方式:Ctrl + C)
    # gunicorn --workers 4 --bind 0.0.0.0:5000 wsgi:app
    (停止方式:Ctrl + C)
    
  7. 自定系統服務,啟動 Gunicorn 產品運作環境:
    # vim /etc/systemd/system/webapp.service
    [Unit]
    Description=webapp.service - A Flask application run with Gunicorn.
    After=network.target
    
    [Service]
    User=nginx
    Group=nginx
    Environment="PATH=/usr/local/bin"
    WorkingDirectory=/usr/share/nginx/webapp/
    ExecStart=/usr/local/bin/gunicorn --workers 3 --bind unix:/run/gunicorn/webapp.sock wsgi:app
    
    [Install]
    WantedBy=multi-user.target
    
    # systemctl daemon-reload
    # mkdir -p /run/gunicorn/
    # chown nginx:nginx /run/gunicorn/
    # systemctl enable --now webapp.service
    # semanage fcontext -a -t httpd_var_run_t "/var/run/gunicorn/webapp.sock"
    # restorecon -Rvv /var/run/gunicorn/webapp.sock
    
  8. 設定 Nginx 服務,新增一個 Web 服務站台,對應 Gunicorn 服務:
    # vim /etc/nginx/conf.d/webapp.conf
    server {
            listen 80;
            server_name webapp.example.com;
    
            access_log /var/log/nginx/webapp_access.log;
            error_log /var/log/nginx/webapp_error.log;
    
            location / {
                    proxy_pass http://unix:/run/gunicorn/webapp.sock;
                    proxy_redirect off;
                    proxy_set_header Host $host:80;
                    proxy_set_header X-Real-IP $remote_addr;
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            }
    }
    
    # nginx -t
    # systemctl enable --now nginx
    
  9. 設定防火牆,允許外來的連線:
    # firewall-cmd --add-service=http
    # firewall-cmd --add-service=https
    # firewall-cmd --runtime-to-permanent
    
參考文獻:
  1. https://dev.to/brandonwallace/deploy-flask-the-easy-way-with-gunicorn-and-nginx-jgc
  2. https://gunicorn.org/