Ubuntu 18.04에 Flask 마이크로웹프레임워크를 이용하여 파이썬 어플리케이션을 배포하는 방법에 대해 알아본다.
Install Flask
먼저 플라스크를 설치한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | (tfKeras) founder@hilbert:~$ conda install -c anaconda flask Solving environment: done ## Package Plan ## environment location: /home/founder/anaconda3/envs/tfKeras added / updated specs: - flask The following packages will be downloaded: package | build ---------------------------|----------------- click-7.0 | py36_0 118 KB anaconda itsdangerous-1.1.0 | py36_0 26 KB anaconda werkzeug-0.14.1 | py36_0 423 KB anaconda flask-1.0.2 | py36_1 119 KB anaconda ------------------------------------------------------------ Total: 687 KB The following NEW packages will be INSTALLED: click: 7.0-py36_0 anaconda flask: 1.0.2-py36_1 anaconda itsdangerous: 1.1.0-py36_0 anaconda werkzeug: 0.14.1-py36_0 anaconda Proceed ([y]/n)? y Downloading and Extracting Packages click-7.0 | 118 KB | ################################################################################################################### | 100% itsdangerous-1.1.0 | 26 KB | ################################################################################################################### | 100% werkzeug-0.14.1 | 423 KB | ################################################################################################################### | 100% flask-1.0.2 | 119 KB | ################################################################################################################### | 100% Preparing transaction: done Verifying transaction: done Executing transaction: done | cs |
테스트를 위한 간단한 app 을 작성한다. 파일 이름은 hello.py 로 명명하였다.
hello.py
1 2 3 4 5 6 7 8 9 | from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "<h1 style='color:blue'>Hello There!</h1>" if __name__ == "__main__": app.run(host='0.0.0.0') | cs |
방화벽 설정에서 5000번 포트를 오픈한다.
다음과 같이 실행한 후, 웹브라우저에 http://your_ip:5000 이라고 입력하면 정상적으로 구동됨을 확인할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ python hello.py * Serving Flask app "hello" (lazy loading) * Environment: production WARNING: Do not use the development server in a production environment. Use a production WSGI server instead. * Debug mode: off * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) 121.126.70.51 - - [19/Jan/2019 07:47:22] "GET / HTTP/1.1" 200 - 121.126.70.51 - - [19/Jan/2019 07:47:23] "GET /favicon.ico HTTP/1.1" 404 - | cs |
Creating the WSGI Entry Point
엔트리 포인트 역할을 할 파일 wsgi.py 을 만든다. 이 파일은 uWSGI 서버와 통신을 하게 된다.
1 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ nano wsgi.py | cs |
wsgi.py
1 2 3 4 5 6 | from hello import app if __name__ == "__main__": app.run() | cs |
Configuring uWSGI
uWSGI 가 앞서 만든 앱을 정상적으로 서비스하는지 확인해보자. uwsgi 가 설치되어 있지 않은 경우에는 본문 하단의 설치법을 참고한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ uwsgi --socket 0.0.0.0:5000 --protocol=http -w wsgi:app *** Starting uWSGI 2.0.17.1 (64bit) on [Sat Jan 19 08:14:49 2019] *** compiled with version: 7.3.0 on 17 December 2018 12:05:02 os: Linux-4.15.0-1026-gcp #27-Ubuntu SMP Thu Dec 6 18:27:01 UTC 2018 nodename: hilbert machine: x86_64 clock source: unix pcre jit disabled detected number of CPU cores: 4 current working directory: /home/founder/tfKeras/birdbox detected binary path: /home/founder/anaconda3/envs/tfKeras/bin/uwsgi *** WARNING: you are running uWSGI without its master process manager *** your processes number limit is 60029 your memory page size is 4096 bytes detected max file descriptor number: 1024 lock engine: pthread robust mutexes thunder lock: disabled (you can enable it with --thunder-lock) uwsgi socket 0 bound to TCP address 0.0.0.0:5000 fd 3 Python version: 3.6.7 | packaged by conda-forge | (default, Nov 21 2018, 03:09:43) [GCC 7.3.0] *** Python threads support is disabled. You can enable it with --enable-threads *** Python main interpreter initialized at 0x564d1e65ed80 your server socket listen backlog is limited to 100 connections your mercy for graceful operations on workers is 60 seconds mapped 72920 bytes (71 KB) for 1 cores *** Operational MODE: single process *** WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x564d1e65ed80 pid: 13287 (default app) *** uWSGI is running in multiple interpreter mode *** spawned uWSGI worker 1 (and the only) (pid: 13287, cores: 1) [pid: 13287|app: 0|req: 1/1] ***.***.**.** () {36 vars in 895 bytes} [Sat Jan 19 08:14:52 2019] GET / => generated 40 bytes in 0 msecs (HTTP/1.1 200) 2 headers in 79 bytes (1 switches on core 0) | cs |
다시 웹브라우저에서 http://[your server's IP address]:5000 입력해보면 앞서와 같이 Hello There! 가 정상적 출력됨을 확인할 수 있다.
Creating a uWSGI Configuration File
프로젝트 디렉토리로 이동하여 아래 내용으로 설정 파일을 만든다.
1 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ nano birdbox.ini | cs |
설정 파일은 [uwsgi]
헤더로 시작된다. uWSGI 가 이 설정이 적용되어야함을 알게 하기 위해서다. 2가지를 지정해줘야 하는데, module 그 자체와 wsgi.py 파일에서 확장자를 제외한 wsgi 와 파일내의 callable 인 app 이 그것이다.
다음으로 uWSGI 에 마스터 모드로 시작하고 요청을 처리하기 위해 5개의 워커 프로세스를 배정한다.
테스팅 단계에서는 uWSGI 가 네트워크 포트에 노출이 되지만, 이 부분은 곧 Nginx 를 통해 실제 클라이언트 연결을 다루게 될 것이다. Nginx 가 요청을 uWSGI 로 전달하게 된다. 이러한 컴포넌트들이 동일한 컴퓨터에서 운영되므로, 더 빠르고 안전한 유닉스 소켓을 선호하게 된다. 그 소켓을 birdbox.sock 라고 부르기로 하고 프로젝트 디렉토리에 저장하기로 한다.
그리고 그 소켓의 권한을 변경해야 한다. 소켓의 그룹 소유자는 파일로부터의 정보를 읽고 쓸 수 있어야 한다. 그리고 vacuum 옵션을 통해 프로세스가 멈추게 되면 소켓을 비우도록 해야한다.
마지막 단계는 die-on-term 옵션을 정의하는 것으로, 이는 init system 과 uWSGI 가 각각의 프로세스에 대해 동일한 가정을 가지고 동작할 수 있도록 해준다.
설정이 끝났으면 파일을 저장하고 닫는다.
birdbox.ini
1 2 3 4 5 6 7 8 9 10 11 | [uwsgi] module = wsgi:app master = true processes = 5 socket = birdbox.sock chmod-socket = 660 vacuum = true die-on-term = true | cs |
Creating a systemd Unit File
이제 systemd service unit 파일을 만들자. 이 파일을 통해 Ubuntu 서버가 자동으로 uWSGI 가 시작되도록 해주고, 서버가 부팅될 때마다 플라스크 어플리케이션이 동작하도록 해준다. 먼저 /etc/systemd/system 디렉토리에 birdbox.service 파일을 생성한다.
1 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo nano /etc/systemd/system/birdbox.service | cs |
이 파일은 [Unit] 섹션부터 시작하게 되는데, 여기서는 메타데이터와 의존성을 정의하게 된다. 본 서비스의 설명을 이볅하고, init system 으로 하여금 네트워킹 타겟에 도달했을때에만 실행되도록 설정하자.
다음은 [Service] 섹션이다. 여기서는 프로세스를 실행할 사용자와 그룹을 정의하게 된다. www-data 그룹에 그룹 소유권을 부여하여 Nginx 가 uWSGI 프로세스와 손쉽게 통신이 가능하도록 만든다.
작업 디렉토리를 매핑하고 PATH 환경변수를 설정한다. 서비스를 시작할 명령을 특정한다. Systemd 은 uWSGI 실행파일 전체 경로를 필요로 하므로, 이를입력하고 여기로 .ini 설정 파일을 전달한다.
마지막으로 [Install] 섹션에서 멀티 유저 시스템이 구동중일 때 서비스가 시작되도록 설정한다.
birdbox.ini
1 2 3 4 5 6 7 8 9 10 11 12 13 | [Unit] Description=uWSGI Instance to server birdbox After=network.target [Service] User=founder Group=www-data WorkingDirectory=/home/founder/tfKeras/birdbox Environment="PATH=/home/founder/anaconda3/envs/tfKeras/bin" ExecStart=/home/founder/anaconda3/envs/tfKeras/bin/uwsgi --ini birdbox.ini [Install] WantedBy=multi-user.target | cs |
이것으로 systemd 서비스 파일이 완성되었다. 파일을 저장하고 종료한다.
uWSGI 서비스는 다음과 같이 실행할 수 있으며, 상태 확인이 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo systemctl start birdbox (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo systemctl status birdbox ● birdbox.service - uWSGI Instance to server birdbox Loaded: loaded (/etc/systemd/system/birdbox.service; disabled; vendor preset: enabled) Active: active (running) since Sat 2019-01-19 08:46:26 UTC; 6s ago Main PID: 14417 (uwsgi) Tasks: 6 (limit: 4915) CGroup: /system.slice/birdbox.service ├─14417 /home/founder/anaconda3/envs/tfKeras/bin/uwsgi --ini birdbox.ini ├─14428 /home/founder/anaconda3/envs/tfKeras/bin/uwsgi --ini birdbox.ini ├─14431 /home/founder/anaconda3/envs/tfKeras/bin/uwsgi --ini birdbox.ini ├─14432 /home/founder/anaconda3/envs/tfKeras/bin/uwsgi --ini birdbox.ini ├─14434 /home/founder/anaconda3/envs/tfKeras/bin/uwsgi --ini birdbox.ini └─14435 /home/founder/anaconda3/envs/tfKeras/bin/uwsgi --ini birdbox.ini Jan 19 08:46:26 hilbert uwsgi[14417]: mapped 437520 bytes (427 KB) for 5 cores Jan 19 08:46:26 hilbert uwsgi[14417]: *** Operational MODE: preforking *** Jan 19 08:46:26 hilbert uwsgi[14417]: WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x5562de081d Jan 19 08:46:26 hilbert uwsgi[14417]: *** uWSGI is running in multiple interpreter mode *** Jan 19 08:46:26 hilbert uwsgi[14417]: spawned uWSGI master process (pid: 14417) Jan 19 08:46:26 hilbert uwsgi[14417]: spawned uWSGI worker 1 (pid: 14428, cores: 1) Jan 19 08:46:26 hilbert uwsgi[14417]: spawned uWSGI worker 2 (pid: 14431, cores: 1) Jan 19 08:46:26 hilbert uwsgi[14417]: spawned uWSGI worker 3 (pid: 14432, cores: 1) Jan 19 08:46:26 hilbert uwsgi[14417]: spawned uWSGI worker 4 (pid: 14434, cores: 1) Jan 19 08:46:26 hilbert uwsgi[14417]: spawned uWSGI worker 5 (pid: 14435, cores: 1) | cs |
Configuring Nginx to Proxy Requests
이제 uwsgi 프로토콜을 사용하는 소켓으로 웹요청을 전달할 수 있도록 Nginx 를 설정해보자. Nginx's sites-available 디렉토리내에 새로운 서버 블록 설정 파일을 만드는 것에서 시작한다. 이를 birdbox 라고 부르기로 하자.
서버 블록을 열어 Nginx 가 5000번 포트를 리스닝하도록 설정한다. 서버 도메인 네임에 대한 요청에 이 블록을 사용하도록 설정하자.
다음으로 모든 요청에 부합하는 로케이션 블록을 추가한다. 이 블록안에 일반적인 uWSGI 파라메터를 특정하는 uwsgi_params 파일을 포함하도록 한다. 그러면 uwsgi_pass 지시자를 이용하여 요청을 정의한 소켓으로 보내게 된다.
1 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo nano /etc/nginx/sites-available/birdbox | cs |
1 2 3 4 5 6 7 8 9 10 11 12 | server { listen 5000; server_name teamgalois.com www.teamgalois.com; location / { include uwsgi_params; uwsgi_pass unix:/home/founder/tfKeras/birdbox/birdbox.sock; } } | cs |
파일을 저장하고 닫는다. Nginx 서버 블록 설정을 활성화하기 위해서, 그 파일을 sites-enabled 디렉토리로 연결한다.
1 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo ln -s /etc/nginx/sites-available/birdbox /etc/nginx/sites-enabled | cs |
구문상의 오류가 없는지 테스트해보자.
1 2 3 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful | cs |
특별한 이슈가 없다고 나오면 새로운 설정사항을 읽어들이기 위해 Nginx 를 재시작한다.
1 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo systemctl restart nginx | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo systemctl status nginx ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2019-01-19 08:56:25 UTC; 46s ago Docs: man:nginx(8) Process: 14507 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS) Process: 10645 ExecReload=/usr/sbin/nginx -g daemon on; master_process on; -s reload (code=exited, status=0/SUCCESS) Process: 14516 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Process: 14508 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 14521 (nginx) Tasks: 5 (limit: 4915) CGroup: /system.slice/nginx.service ├─14521 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; ├─14524 nginx: worker process ├─14525 nginx: worker process ├─14527 nginx: worker process └─14529 nginx: worker process Jan 19 08:56:25 hilbert systemd[1]: Starting A high performance web server and a reverse proxy server... Jan 19 08:56:25 hilbert systemd[1]: Started A high performance web server and a reverse proxy server. | cs |
정상적으로 출력됨을 알 수 있다.
Securing the Application
서버 도메인에 대한 트래픽을 보호하기 위해, SSL 인증서를 설치하도록 하자. 먼저 Certbot Ubuntu repository 를 추가한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo add-apt-repository ppa:certbot/certbot This is the PPA for packages prepared by Debian Let's Encrypt Team and backported for Ubuntu(s). More info: https://launchpad.net/~certbot/+archive/ubuntu/certbot Press [ENTER] to continue or Ctrl-c to cancel adding it. Hit:1 https://packages.microsoft.com/repos/vscode stable InRelease Hit:2 http://asia-east1.gce.archive.ubuntu.com/ubuntu bionic InRelease Get:3 http://asia-east1.gce.archive.ubuntu.com/ubuntu bionic-updates InRelease [88.7 kB] Get:4 http://asia-east1.gce.archive.ubuntu.com/ubuntu bionic-backports InRelease [74.6 kB] Hit:5 http://packages.cloud.google.com/apt google-cloud-logging-wheezy InRelease Get:6 http://asia-east1.gce.archive.ubuntu.com/ubuntu bionic-updates/main amd64 Packages [489 kB] Get:7 http://asia-east1.gce.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 Packages [711 kB] Get:8 http://security.ubuntu.com/ubuntu bionic-security InRelease [83.2 kB] Hit:9 http://packages.cloud.google.com/apt google-cloud-monitoring-bionic InRelease Get:10 http://ppa.launchpad.net/certbot/certbot/ubuntu bionic InRelease [21.3 kB] Hit:11 http://archive.canonical.com/ubuntu bionic InRelease Get:12 http://ppa.launchpad.net/certbot/certbot/ubuntu bionic/main amd64 Packages [8016 B] Get:13 http://ppa.launchpad.net/certbot/certbot/ubuntu bionic/main Translation-en [4200 B] Fetched 1480 kB in 2s (745 kB/s) Reading package lists... Done | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo apt install python-certbot-nginx Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: certbot python3-acme python3-certbot python3-certbot-nginx python3-configargparse python3-future python3-icu python3-josepy python3-mock python3-ndg-httpsclient python3-parsedatetime python3-pbr python3-pyparsing python3-requests-toolbelt python3-rfc3339 python3-tz python3-zope.component python3-zope.event python3-zope.hookable Suggested packages: python3-certbot-apache python-certbot-doc python-acme-doc python-certbot-nginx-doc python-future-doc python-mock-doc python-pyparsing-doc The following NEW packages will be installed: certbot python-certbot-nginx python3-acme python3-certbot python3-certbot-nginx python3-configargparse python3-future python3-icu python3-josepy python3-mock python3-ndg-httpsclient python3-parsedatetime python3-pbr python3-pyparsing python3-requests-toolbelt python3-rfc3339 python3-tz python3-zope.component python3-zope.event python3-zope.hookable 0 upgraded, 20 newly installed, 0 to remove and 97 not upgraded. Need to get 1213 kB of archives. After this operation, 6406 kB of additional disk space will be used. Do you want to continue? [Y/n] y | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ sudo certbot --nginx -d teamgalois.com -d www.teamgalois.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): alexjinchoi@gmail.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 teamgalois.com http-01 challenge for www.teamgalois.com Using default address 80 for authentication. Using default address 80 for authentication. Waiting for verification... Cleaning up challenges Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/birdbox Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/birdbox Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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): 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Congratulations! You have successfully enabled https://teamgalois.com and https://www.teamgalois.com You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=teamgalois.com https://www.ssllabs.com/ssltest/analyze.html?d=www.teamgalois.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/teamgalois.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/teamgalois.com/privkey.pem Your cert will expire on 2019-04-19. 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 / Lets 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. (tfKeras) founder@hilbert:~/tfKeras/birdbox$ | cs |
https://
: 를 이용하여 접속해보면 아래 이미지와 같이 암호화된 페이지가 로딩됨을 볼 수 있다.nginx 및 uwsgi 설치와 관련하여 추가적인 내용은 다음을 참고한다.
nginx 설치 여부 확인 (버전 확인)
1 2 3 4 5 6 7 8 9 10 11 | (tfKeras) founder@hilbert:~$ nginx -v nginx version: nginx/1.14.0 (Ubuntu) (tfKeras) founder@hilbert:~$ curl -I localhost HTTP/1.1 200 OK Server: nginx/1.14.0 (Ubuntu) Date: Sat, 19 Jan 2019 06:45:03 GMT Content-Type: text/html; charset=UTF-8 Connection: keep-alive Link: <http://www.teamgalois.com/wp-json/>; rel="https://api.w.org/" Link: <https://wp.me/asrQ3>; rel=shortlink | cs |
Anaconda uwsgi 설치
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | (tfKeras) founder@hilbert:~/tfKeras/birdbox$ conda install -c conda-forge uwsgi Solving environment: done ## Package Plan ## environment location: /home/founder/anaconda3/envs/tfKeras added / updated specs: - uwsgi The following packages will be downloaded: package | build ---------------------------|----------------- openssl-1.0.2p | h14c3975_1002 3.1 MB conda-forge uwsgi-2.0.17.1 |py36hf36b3d6_1002 2.0 MB conda-forge yaml-0.1.7 | h14c3975_1001 78 KB conda-forge python-3.6.6 | hd21baee_1003 29.0 MB conda-forge jansson-2.11 | h14c3975_1001 50 KB conda-forge ------------------------------------------------------------ Total: 34.2 MB The following NEW packages will be INSTALLED: jansson: 2.11-h14c3975_1001 conda-forge uwsgi: 2.0.17.1-py36hf36b3d6_1002 conda-forge yaml: 0.1.7-h14c3975_1001 conda-forge The following packages will be UPDATED: ca-certificates: 2018.03.07-0 anaconda --> 2018.11.29-ha4d7672_0 conda-forge certifi: 2018.10.15-py36_0 anaconda --> 2018.11.29-py36_1000 conda-forge The following packages will be DOWNGRADED: openssl: 1.1.1-h7b6447c_0 anaconda --> 1.0.2p-h14c3975_1002 conda-forge python: 3.6.7-h0371630_0 --> 3.6.6-hd21baee_1003 conda-forge Proceed ([y]/n)? y Downloading and Extracting Packages openssl-1.0.2p | 3.1 MB | #################################################################### | 100% uwsgi-2.0.17.1 | 2.0 MB | #################################################################### | 100% yaml-0.1.7 | 78 KB | #################################################################### | 100% python-3.6.6 | 29.0 MB | #################################################################### | 100% jansson-2.11 | 50 KB | #################################################################### | 100% Preparing transaction: done Verifying transaction: done Executing transaction: done | cs |
[원문출처] https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-uswgi-and-nginx-on-ubuntu-18-04