웹사이트 검색

Ubuntu 20.04에서 uWSGI 및 Nginx를 사용하여 Flask 애플리케이션을 배포하는 방법


이 튜토리얼은 다음 OS 버전에 대해 존재합니다.

  • Ubuntu 22.04(Jammy Jellyfish)
  • Ubuntu 20.04(Focal Fossa)

이 페이지에서

  1. 전제 조건
  2. 시작하기\n
  3. 필수 종속성 설치\n
  4. 가상 환경 만들기\n
  5. Flask 애플리케이션 설정\n
  6. uWSGI 구성
  7. uWSGI 구성
  8. Systemd 서비스 파일 만들기
  9. Nginx를 역방향 프록시로 구성\n
  10. Lets Encrypt SSL을 사용하여 Flask 애플리케이션 보안\n
  11. 결론

Flask는 Armin Ronacher가 개발한 Python으로 작성된 마이크로 웹 프레임워크입니다. 도구나 라이브러리가 필요하지 않기 때문에 마이크로프레임워크라고 합니다. Flask는 Python 모듈이며 웹 응용 프로그램을 쉽게 개발하는 데 도움이 되는 작고 확장하기 쉬운 코어가 있습니다.

이 튜토리얼에서는 Ubuntu 20.04에서 Uwsgi 및 Nginx를 사용하여 Flask 애플리케이션을 배포하는 방법을 배웁니다.

전제 조건

  • Ubuntu 20.04를 실행하는 서버.\n
  • 서버 IP를 가리키는 유효한 도메인 이름입니다.\n
  • 루트 암호는 서버에 구성됩니다.\n

시작하기

먼저 시스템 패키지를 최신 버전으로 업데이트하는 것이 좋습니다. 다음 명령을 실행하여 업데이트할 수 있습니다.

apt-get update -y

모든 패키지가 업데이트되면 다음 단계로 진행할 수 있습니다.

필수 종속성 설치

다음으로 플라스크 애플리케이션을 배포하는 데 필요한 몇 가지 종속 항목을 설치해야 합니다. 다음 명령으로 모두 설치할 수 있습니다.

apt-get install nginx python3-pip python3-dev python3-venv build-essential libssl-dev libffi-dev python3-setuptools -y

모든 패키지가 설치되면 다음 단계로 진행할 수 있습니다.

가상 환경 만들기

다음으로 Flask 애플리케이션을 위한 가상 환경을 만들어야 합니다. 가상 환경은 격리된 Python 환경을 만드는 데 사용되는 매우 유용한 도구입니다. 프로젝트에 특정 버전의 Python을 설치하는 데 도움이 됩니다.

먼저 다음 명령을 사용하여 Flask 애플리케이션용 디렉터리를 만듭니다.

mkdir /var/www/html/myapp

다음으로 디렉터리를 myapp로 변경하고 다음 명령을 사용하여 새 Python 가상 환경을 만듭니다.

cd /var/www/html/myapp
python3.8 -m venv myappenv

그런 다음 다음 명령을 사용하여 가상 환경을 활성화합니다.

source myappenv/bin/activate

Flask 애플리케이션 설정

이 시점에서 Python 가상 환경은 Flask 애플리케이션을 배포할 준비가 되었습니다. 다음으로 가상 환경 내에서 Flask 앱을 설정해야 합니다.

먼저 다음 명령을 사용하여 Flask 및 uWSGI를 설치합니다.

pip install uwsgi flask

다음으로 다음 명령을 사용하여 myapp.py라는 샘플 애플리케이션을 만듭니다.

nano /var/www/html/myapp/myapp.py

다음 줄을 추가합니다.

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "<h1 style='color:blue'>Hi This is My Flask Application</h1>"

if __name__ == "__main__":
    app.run(host='0.0.0.0')

완료되면 파일을 저장하고 닫습니다. 다음으로 다음 명령을 사용하여 Flask 애플리케이션을 실행합니다.

python /var/www/html/myapp/myapp.py

다음 출력이 표시되어야 합니다.

 * Serving Flask app "myapp" (lazy loading)
 * Environment: production
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)

이제 웹 브라우저를 열고 URL http://your-server-ip:5000을 사용하여 Flask 애플리케이션에 액세스합니다. 다음 화면이 표시됩니다.

이제 터미널에서 CTRL + C를 눌러 Flask 애플리케이션을 중지합니다.

uWSGI 구성

먼저 WSGI 진입점을 생성하여 uWSGI 서버와 상호 작용하는 방법을 알려줍니다.

nano /var/www/html/myapp/wsgi.py

다음 줄을 추가하여 애플리케이션에서 Flask 인스턴스를 가져옵니다.

from myapp import app

if __name__ == "__main__":
    app.run()

완료되면 파일을 저장하고 닫은 다음 uWSGI가 다음 명령을 사용하여 응용 프로그램을 제공할 수 있는지 여부를 테스트합니다.

uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app

이제 URL http://your-server-ip:5000을 사용하여 애플리케이션에 다시 액세스하십시오. 다음 화면이 표시됩니다.

이제 CTRL + C를 눌러 응용 프로그램을 중지합니다.

그런 다음 다음 명령을 실행하여 가상 환경을 종료합니다.

deactivate

uWSGI 구성

이 시점에서 uWSGI는 애플리케이션을 제공할 수 있습니다. 이제 다음 명령을 사용하여 uWSGI 구성 파일을 만듭니다.

nano /var/www/html/myapp/myapp.ini

다음 줄을 추가합니다.

[uwsgi]
module = wsgi:app

master = true
processes = 5

socket = myapp.sock
chmod-socket = 660
vacuum = true

die-on-term = true

완료되면 파일을 저장하고 닫습니다.

Systemd 서비스 파일 생성

다음으로 uWSGI 서비스를 관리하기 위해 systemd 서비스 파일을 생성해야 합니다. 다음 명령으로 만들 수 있습니다.

nano /etc/systemd/system/myapp.service

다음 줄을 추가합니다.

[Unit]
Description=uWSGI instance to serve myapp
After=network.target

[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/html/myapp
Environment="PATH=/var/www/html/myapp/myappenv/bin"
ExecStart=/var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini

[Install]
WantedBy=multi-user.target

완료되면 파일을 저장하고 닫은 후 다음 명령을 사용하여 systemd 데몬을 다시 로드합니다.

systemctl daemon-reload

다음으로 애플리케이션의 소유권을 www-data로 변경하고 다음 명령을 사용하여 적절한 권한을 설정합니다.

chown -R www-data:www-data /var/www/html/myapp
chmod -R 775 /var/www/html/myapp

그런 다음 애플리케이션을 시작하고 다음 명령을 사용하여 시스템 재부팅 시 시작되도록 활성화합니다.

systemctl start myapp
systemctl enable myapp

다음 명령을 사용하여 애플리케이션 상태를 확인할 수도 있습니다.

systemctl status myapp

다음 출력이 표시되어야 합니다.

? myapp.service - uWSGI instance to serve myapp
     Loaded: loaded (/etc/systemd/system/myapp.service; disabled; vendor preset: enabled)
     Active: active (running) since Sun 2020-09-13 08:38:08 UTC; 1min 53s ago
   Main PID: 662796 (uwsgi)
      Tasks: 6 (limit: 4691)
     Memory: 21.8M
     CGroup: /system.slice/myapp.service
             ??662796 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini
             ??662808 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini
             ??662809 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini
             ??662810 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini
             ??662811 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini
             ??662812 /var/www/html/myapp/myappenv/bin/uwsgi --ini myapp.ini


Sep 13 08:38:08 ubunt4 uwsgi[662796]: WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x55e207e7a510 pid: 662796 (default app)
Sep 13 08:38:08 ubunt4 uwsgi[662796]: *** uWSGI is running in multiple interpreter mode ***
Sep 13 08:38:08 ubunt4 uwsgi[662796]: spawned uWSGI master process (pid: 662796)
Sep 13 08:38:08 ubunt4 uwsgi[662796]: spawned uWSGI worker 1 (pid: 662808, cores: 1)
Sep 13 08:38:08 ubunt4 uwsgi[662796]: spawned uWSGI worker 2 (pid: 662809, cores: 1)
Sep 13 08:38:08 ubunt4 uwsgi[662796]: spawned uWSGI worker 3 (pid: 662810, cores: 1)
Sep 13 08:38:08 ubunt4 uwsgi[662796]: spawned uWSGI worker 4 (pid: 662811, cores: 1)
Sep 13 08:38:08 ubunt4 uwsgi[662796]: spawned uWSGI worker 5 (pid: 662812, cores: 1)

Nginx를 역방향 프록시로 구성

다음으로 Flask 애플리케이션을 제공하기 위해 Nginx를 리버스 프록시로 구성해야 합니다. 다음 명령으로 수행할 수 있습니다.

nano /etc/nginx/sites-available/flask.conf

다음 줄을 추가합니다.

server {
    listen 80;
    server_name flask.example.com;

    location / {
        include uwsgi_params;
        uwsgi_pass unix:/var/www/html/myapp/myapp.sock;
    }
}

완료되면 파일을 저장하고 닫습니다. 다음으로 다음 명령을 사용하여 Nginx에서 구문 오류가 있는지 확인합니다.

nginx -t

다음 출력이 표시되어야 합니다.

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

다음으로 다음 명령을 사용하여 Nginx 가상 호스트를 활성화합니다.

ln -s /etc/nginx/sites-available/flask.conf /etc/nginx/sites-enabled/

마지막으로 Nginx 서비스를 다시 시작하여 변경 사항을 적용합니다.

systemctl restart nginx

이 시점에서 Nginx는 Flask 애플리케이션을 제공하도록 구성됩니다.

Lets Encrypt SSL을 사용하여 Flask 애플리케이션 보호

다음으로 Lets Encrypt 무료 SSL로 애플리케이션을 보호하는 것이 좋습니다. 먼저 SSL 인증서를 설치하고 관리하려면 Certbot 클라이언트를 설치해야 합니다. 다음 명령으로 설치할 수 있습니다.

apt-get install python3-certbot-nginx -y

설치가 완료되면 다음 명령을 실행하여 Lets Encrypt SSL로 웹 사이트를 보호하십시오.

certbot --nginx -d flask.example.com

유효한 이메일 주소를 제공하고 아래와 같이 서비스 약관에 동의하라는 메시지가 표시됩니다.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for flask.example.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/flask.conf

다음으로, 아래와 같이 HTTP 트래픽을 HTTPS로 리디렉션할지 여부를 선택합니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2

2를 입력하고 Enter 키를 눌러 설치를 마칩니다. 다음 출력이 표시되어야 합니다.

Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/flask.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://flask.example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=flask.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/flask.example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/flask.example.com/privkey.pem
   Your cert will expire on 2020-10-30. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

 - We were unable to subscribe you the EFF mailing list because your
   e-mail address appears to be invalid. You can try again later by
   visiting https://act.eff.org.

이제 플라스크 웹사이트는 Lets Encrypt SSL로 보호됩니다. URL https://flask.example.com을 사용하여 Flask 애플리케이션에 액세스할 수 있습니다.

결론

축하합니다! uWSGI 및 Nginx를 사용하여 Flask 애플리케이션을 성공적으로 배포하고 Lets Encrypt SSL로 보호했습니다. 이제 Flask를 사용하여 Python 앱을 쉽게 개발하고 배포할 수 있습니다. 궁금한 점이 있으면 언제든지 문의해 주세요.