갈루아의 반서재

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 201803: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 2002 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 -/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 ---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

ENTEE 를 치고, apt 를 이용하여 Certbot's Nginx 패키지를 설치한다. 

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

Certbot 은 플러그인을 통해 SSL 인증서를 취득하는 여러 가지 방법을 제공하고 있다. 다음과 같이 Nginx 플러그인을 설치한다. 

명령문을 보면 --nginx 플러그인을 가지는 certbot 을 구동한다는 의미이며, -d 는 인증서가 유효한 도메인을 지정하는 옵션이다. 이번이 certbot 을 처음으로 구동하는 상황이라면 메일 주소 등을 입력해야 한다. 그리고나며 certbot 은 Let's Encrypt 서버와 통신을 하게 되고, 도메인에 대한 소유권이 있는지 확인하게 된다. 

이 과정이 성공적으로 끝나면 certbot 은 HTTPS 설정을 어떻게 할 것인지 물어온다. 옵션을 선택하면 모든 과정이 성공적으로 끝났다는 메시지를 보게 된다. 

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-2then [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://를 이용하여 접속해보면 아래 이미지와 같이 암호화된 페이지가 로딩됨을 볼 수 있다.
 
https://www.ssllabs.com/ssltest/analyze.html?d=teamgalois.com
https://www.ssllabs.com/ssltest/analyze.html?d=www.teamgalois.com


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