AWS EC2 上使用 Nginx + Let’s Encrypt 部署 Flask 應用程式
啟動 AWS EC2 執行個體
可以參考 Django 部署 (ㄧ):啟動 AWS EC2 執行個體 文章中申請步驟進行 AWS EC2 的設置與啟用。
建立的 AWS EC2 IP 位址如下:(以下範例將會以此 EC2 執行個體為例)
Public IPv4 Address: 54.169.24.192
Private IPv4 Address: 172.31.42.195
部署 Flask 應用程式
首先,先建立一個 Flask App,並將服務運行於 ‘0.0.0.0’,指定阜為 5000。
@app.route('/hello')
def hello():
return 'Hello, World!'
if __name__ = "__main__":
app.run(host='0.0.0.0', port=5000)
啟動後終端機畫面如下:
小知識:
host
參數用於指定 Flask 應用程式綁定的 IP 位址。預設值為127.0.0.1
,表示只能從本機訪問該應用程式。如果將host
設置為0.0.0.0
,則表示該應用程式將會綁定到本機的所有網路介面,即可以從本機的任何 IP 位址訪問該應用程式。
新增 AWS EC2 安全規則
啟動 Flask 應用程式後,要將指定阜 5000 新增至 AWS EC2 安全規則中,才可以透過對外 IP 與指定 Port 訪問該應用程式。(設定方法可以參考 Django 部署 (二):AWS EC2 上部署 Django 專案)
設定完成後,打開網址 http://54.169.24.192/hello 即可訪問該應用程式。
使用 Nginx + Let’s Encrypt 配置 HTTPS
設置 Nginx 反向代理
首先,先安裝 Nginx 套件。
$ sudo apt-get install nginx
打開網址 http://54.169.24.192 看到預設畫面如下,表示 Nginx 服務已經成功安裝並且順利運行。
接著,新增一個 Nginx 配置文件 /etc/nginx/sites-available/flask
。其中 server_name
的 your_domain.com 要換成你要使用的對外 IP 位址或是域名。
server {
listen 80;
listen [::]:80;
server_name your_domain.com;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
將此配置文件鏈接到 /etc/nginx/sites-enabled
目錄中。
$ sudo ln -s /etc/nginx/sites-available/flask /etc/nginx/sites-enabled/
重新啟動 Nginx 服務。
$ sudo systemctl restart nginx
打開 http://your_domain/hello 可以訪問應用程式即代表成功配置。
使用 Let’s Encrypt 申請免費 SSL/TLS 憑證
使用 Let’s Encrypt 提供的 Certbot 工具來生成 SSL/TLS 證書。首先,先安裝 Certbot 與他的 Nginx 插件。
$ sudo apt-get install certbot python3-certbot-nginx
使用 Certbot 生成 SSL/TLS 證書。
$ sudo certbot --nginx -d your_domain.com -d www.your_domain.com
依照 Certbot 指示輸入 Email 並同意服務條款,申請成功會顯示訊息如下:
Certbot Nginx 插件會更新你的 Nginx 配置。打開 /etc/nginx/sites-available/flask
查看更新的配置文件,可以看到新增的 SSL/TLS 相關配置項:
server {
listen 443 ssl;
listen [::]:443 ssl ipv6only=on;
server_name your_domain.com;
ssl_certificate /etc/letsencrypt/live/your_domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your_domain.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
listen [::]:80;
server_name your_domain.com;
if ($host = your_domain.com) {
return 301 https://$host$request_uri;
}
return 404;
}
打開 https://your_domain.com/hello 可以訪問網站,即代表成功使用 Nginx 代理並擁有合法的 SSL 憑證。這樣就完成了!
如果想要檢視憑證內容,可以點擊網址列的鎖頭查看憑證的詳細內容。
自動更新 SSL/TLS 憑證
Let’s Encrypt 憑證的有效期限為90天(3個月),為了確保憑證處於最新狀態,可以使用 Certbot 工具自動更新憑證。
如果使用 Certbot 自動生成的 Nginx 配置文件,自動更新憑證的設定已經完成。自動更新的設定檔在 /etc/letsencrypt/renewal/your_domain.conf
。
# renew_before_expiry = 30 days
version = 1.21.0
archive_dir = /etc/letsencrypt/archive/your_domain.com
cert = /etc/letsencrypt/live/your_domain.com/cert.pem
privkey = /etc/letsencrypt/live/your_domain.com/privkey.pem
chain = /etc/letsencrypt/live/your_domain.com/chain.pem
fullchain = /etc/letsencrypt/live/your_domain.com/fullchain.pem
# Options used in the renewal process
[renewalparams]
account = deecea7de532e64c032ba93f998cd4fe
authenticator = nginx
installer = nginx
server = https://acme-v02.api.letsencrypt.org/directory
如果沒有使用自動生成的 Nginx 配置文件,請手動設定自動更新的指令。可以先使用以下命令進行更新測試:
$ sudo certbot renew --dry-run
如果測試成功,可以使用 cron 設置一個 crontab 任務來自動執行更新指令。
$ sudo crontab -e
打開文件中添加以下指令:
# m h dom mon dow command
0 0 * * 0 certbot renew --quiet --no-self-upgrade --post-hook "systemctl reload nginx"
這個設定表示每週日午夜12點,Certbot 會自動檢查憑證是否需要更新,如果需要更新就會自動更新憑證,並在更新後自動載入 Nginx 設定。(Certbot 只會在憑證到期前一個月才會進行更新)
這樣就完成 Let’s Encrypt 的自動更新憑證設定了。