<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Flask on IT 空間</title><link>https://blog.jiatool.com/tags/Flask/</link><description>Recent content in Flask on IT 空間</description><generator>Hugo -- gohugo.io</generator><language>zh</language><managingEditor>jia@jiatool.com (Jia)</managingEditor><webMaster>jia@jiatool.com (Jia)</webMaster><copyright>&amp;copy;{year}, Jia All Rights Reserved</copyright><lastBuildDate>Sat, 03 Sep 2022 20:50:00 +0800</lastBuildDate><atom:link href="https://blog.jiatool.com/tags/Flask/index.xml" rel="self" type="application/rss+xml"/><item><title>Heroku 的替代方案？ Fly.io 平台 — Python Flask 實際範例</title><link>https://blog.jiatool.com/posts/flyio_python/</link><pubDate>Sat, 03 Sep 2022 20:50:00 +0800</pubDate><author>jia@jiatool.com (Jia)</author><atom:modified>Sat, 03 Sep 2022 20:50:00 +0800</atom:modified><guid>https://blog.jiatool.com/posts/flyio_python/</guid><description>前言 上禮拜著名的佈署平台神器 Heroku 公告說將在 11 月 28 日停止免費方案，之後不付錢不給用了 QAQ，包括旗下的 Heroku Dynos、Heroku Postgres</description><content:encoded>&lt;h2 id="前言">前言&lt;/h2>
&lt;p>上禮拜著名的佈署平台神器 Heroku 公告說將在 11 月 28 日停止免費方案，之後不付錢不給用了 QAQ，包括旗下的 Heroku Dynos、Heroku Postgres、Heroku Data for Redis 等服務的免費版本。&lt;br />
(&lt;a href="https://www.ithome.com.tw/news/152729" target="_blank" rel="noopener">
平臺即服務Heroku將在今年終止免費服務 | iThome
&lt;/a>)&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/heroku_announcement.png" alt="Heroku 公告" data-caption="Heroku 公告" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='950px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:950px;height:;"/>
&lt;figcaption style="text-align: center;">
Heroku 公告
&lt;/figcaption>
&lt;/figure>
&lt;p>所以看到有網友推薦 &lt;a href="https://fly.io/" target="_blank" rel="noopener">
Fly.io
&lt;/a>，那我就來試用看看並記錄過程吧，也順便給需要的網友參考~&lt;/p>
&lt;p>* 以下流程及範例程式參考&lt;a href="https://fly.io/docs/getting-started/python/" target="_blank" rel="noopener">
官方文檔
&lt;/a>。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/flyio.jpg" alt="Fly.io 官網" data-caption="Fly.io 官網" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='750px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:750px;height:;"/>
&lt;figcaption style="text-align: center;">
Fly.io 官網
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;!--adsense-->
&lt;h2 id="費用">費用&lt;/h2>
&lt;p>既然要使用，那當然要先了解一下此平台的&lt;a href="https://fly.io/docs/about/pricing/" target="_blank" rel="noopener">
收費機制
&lt;/a>，免費版提供：&lt;/p>
&lt;ul>
&lt;li>最多 3 個 shared-cpu-1x 256MB VM (虛擬機)&lt;/li>
&lt;li>3GB 持久卷(volume)存儲&lt;/li>
&lt;li>160GB 出站數據傳輸量&lt;/li>
&lt;/ul>
&lt;p>* 迷之音：奇怪？我記得上禮拜看的時候，他應該還有限制每月的小時數，不知道是我記錯了，還是他們想透過更多免費額度來吸引 Heroku 那邊來的使用者。&lt;/p>
&lt;br/>
&lt;h2 id="部署步驟">部署步驟&lt;/h2>
&lt;h3 id="準備專案">準備專案&lt;/h3>
&lt;p>我們直接下載官方在GitHub提供的範例&lt;a href="https://github.com/fly-apps/python-hellofly-flask" target="_blank" rel="noopener">
範例專案
&lt;/a>下來，我將資料夾改名(fly_flask)方便我自己區分。&lt;/p>
&lt;p>主要會需要以下四個檔案(剩下的非必要)：&lt;/p>
&lt;pre>&lt;code>fly_flask
├─ templates
│ └─ hello.html
├─ hellofly.py
├─ Procfile
└─ requirements.txt
&lt;/code>&lt;/pre>&lt;br/>
&lt;p>首先 hellofly.py 是我們 flask 主要的入口 (這個簡單的範例也只有這支XD)。&lt;/p>
&lt;p>而當你網址輸入根目錄(&lt;code>/&lt;/code>)或後面隨便帶字串(&lt;code>/&amp;lt;name&amp;gt;&lt;/code>)，它會進到 &lt;code>hello&lt;/code> 這個函式，並渲染 hello.html 這個網頁(檔案位於 templates &amp;gt; hello.html)。&lt;/p>
&lt;br/>
&lt;p>我們先在本機實際運行這個應用程式看看。&lt;br />
(非必要的步驟，但可以先確保整個專案是可以運作的)&lt;/p>
&lt;p>首先要安裝相關套件，在此資料夾打開命令提示字元 CMD，&lt;br />
我還有搭配 pipenv 虛擬環境&amp;amp;套件管理工具，所以指令有些不同：&lt;/p>
&lt;p>創建一個虛擬環境&lt;br />
&lt;code>pipenv --python 3&lt;/code>&lt;/p>
&lt;p>安裝 requirements.txt 裡面列出來的套件&lt;br />
&lt;code>pipenv install&lt;/code>&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/cmd_install_package.jpg" alt="Python虛擬環境建置&amp;amp;安裝套件" data-caption="Python虛擬環境建置&amp;amp;安裝套件" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='900px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:900px;height:;"/>
&lt;figcaption style="text-align: center;">
Python虛擬環境建置&amp;amp;安裝套件
&lt;/figcaption>
&lt;/figure>
&lt;p>其實主要就是 Flask 與 gunicorn 兩個套件。&lt;br />
gunicorn 是用來在正式環境運行 Flask 之用，它是個 WSGI(Web Server Gateway Interface) HTTP Server，因為 Flask 內建的只適合開發測試用，看看再下一張執行它跳出的紅字就在提醒你了。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/cmd_package.png" alt="查看已安裝套件" data-caption="查看已安裝套件" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='650px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:650px;height:;"/>
&lt;figcaption style="text-align: center;">
查看已安裝套件
&lt;/figcaption>
&lt;/figure>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/cmd_run_flask.png" alt="執行 Flask" data-caption="執行 Flask" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='900px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:900px;height:;"/>
&lt;figcaption style="text-align: center;">
執行 Flask
&lt;/figcaption>
&lt;/figure>
&lt;p>試著在瀏覽器的網址列輸入&lt;br />
&lt;code>http://127.0.0.1:5000&lt;/code>&lt;br />
和&lt;br />
&lt;code>http://127.0.0.1:5000/&amp;lt;隨便你打&amp;gt;&lt;/code>&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/confirm_run_result.png" alt="在瀏覽器確認執行結果" data-caption="在瀏覽器確認執行結果" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='800px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:800px;height:;"/>
&lt;figcaption style="text-align: center;">
在瀏覽器確認執行結果
&lt;/figcaption>
&lt;/figure>
&lt;p>OK，看來很正常，沒問題。&lt;/p>
&lt;figure >
&lt;img data-src="https://memeprod.ap-south-1.linodeobjects.com/user-template/276a87d67dc92c2663cb337a160fd60d.png" alt="來源：Meme 梗圖倉庫" data-caption="來源：Meme 梗圖倉庫" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='450px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:450px;height:;"/>
&lt;figcaption style="text-align: center;">
來源：Meme 梗圖倉庫
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h3 id="專案設定">專案設定&lt;/h3>
&lt;p>來到重要的一步，要先設置一些文件，告訴 Fly 我們的應用程式開如何運行及相關設定。&lt;/p>
&lt;br/>
&lt;p>當然，第一步還要要到 &lt;a href="https://fly.io/app/sign-in" target="_blank" rel="noopener">
Fly.io
&lt;/a> 網站註冊一組帳號，完成後會看到這個畫面。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/fly_background.jpg" alt="Fly.io 登入後頁面" data-caption="Fly.io 登入後頁面" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='900px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:900px;height:;"/>
&lt;figcaption style="text-align: center;">
Fly.io 登入後頁面
&lt;/figcaption>
&lt;/figure>
&lt;p>接下來，依照你的作業系統&lt;a href="https://fly.io/docs/getting-started/installing-flyctl/" target="_blank" rel="noopener">
安裝 flyctl
&lt;/a>，這個工具就跟 Heroku 裡的 Heroku CLI 是同樣的概念。&lt;/p>
&lt;p>以 Windows 為例，在 Powershell 內輸入 &lt;code>iwr https://fly.io/install.ps1 -useb | iex&lt;/code> 來安裝 flyctl。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/powershell_install_flyctl.png" alt="Windows 安裝 flyctl" data-caption="Windows 安裝 flyctl" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='700px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:700px;height:;"/>
&lt;figcaption style="text-align: center;">
Windows 安裝 flyctl
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;p>每個應用程式(APP)都需要一個 fly.toml 檔案來告訴 Fly 系統如何部署它。&lt;/p>
&lt;p>可以使用 &lt;code>flyctl launch&lt;/code> 指令來自動生成。&lt;br />
(如果你剛剛才安裝 flyctl，那命令提示字元 CMD 可能要重開它才會生效)&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/cmd_flyctl_login.png" alt="flyctl 登入" data-caption="flyctl 登入" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='700px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:700px;height:;"/>
&lt;figcaption style="text-align: center;">
flyctl 登入
&lt;/figcaption>
&lt;/figure>
&lt;p>啊，第一次要先登入，輸入 &lt;code>flyctl auth login&lt;/code> 來自動打開網頁登入。&lt;br />
登入完成後再次輸入 &lt;code>flyctl launch&lt;/code>。&lt;/p>
&lt;br/>
&lt;p>喔喔喔~它會自動辨識我們使用 Python 創建應用程式，但我們已經有範例的 Procfile 檔案，這邊輸入 &lt;code>N&lt;/code> 跳過即可。&lt;/p>
&lt;p>輸入名稱後(名稱只能包含數字、小寫字母和破折號)，接下來它會讓你選擇看要架在哪個地區的伺服器上。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/cmd_flyctl_launch1.png" alt="flyctl launch" data-caption="flyctl launch" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='550px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:550px;height:;"/>
&lt;figcaption style="text-align: center;">
flyctl launch
&lt;/figcaption>
&lt;/figure>
&lt;p>這是官網展示的伺服器分布，看來離我們最近的就是東京或香港了。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/server_city.png" alt="Fly 伺服器分布城市" data-caption="Fly 伺服器分布城市" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='900px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:900px;height:;"/>
&lt;figcaption style="text-align: center;">
Fly 伺服器分布城市
&lt;/figcaption>
&lt;/figure>
&lt;p>然後我們這個專案不需要資料庫。&lt;br />
完成~&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/cmd_flyctl_launch2.png" alt="flyctl launch" data-caption="flyctl launch" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='900px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:900px;height:;"/>
&lt;figcaption style="text-align: center;">
flyctl launch
&lt;/figcaption>
&lt;/figure>
&lt;p>它就會自動產生 &lt;code>fly.toml&lt;/code> 檔案，內容我們沒有特別需求就不用去改它。&lt;/p>
&lt;br/>
&lt;p>另外，說明一下 &lt;code>Procfile&lt;/code> 檔案用途，它是說明如何啟動我們的應用程式：&lt;/p>
&lt;pre>&lt;code>web: gunicorn hellofly:app
&lt;/code>&lt;/pre>&lt;p>前面說過，我們使用 gunicorn 這個 WSGI HTTP Server 來運行，後面的 hellofly 就是我們 Flask 的進入點 hellofly.py 的檔名。&lt;/p>
&lt;br/>
&lt;h3 id="專案佈署">專案佈署&lt;/h3>
&lt;p>接下來就是重頭戲 — 要將我們的應用程式佈署到 Fly.io 平台了。&lt;/p>
&lt;br/>
&lt;p>在命令提示字元 CMD 輸入指令：&lt;br />
&lt;code>flyctl deploy&lt;/code>&lt;/p>
&lt;p>等它跑一連串的東西&amp;hellip;&amp;hellip;&lt;br />
有興趣也可以觀察它做了哪些步驟。&lt;/p>
&lt;p>結束後，輸入指令來看看應用程式部屬的狀態：&lt;br />
&lt;code>flyctl status&lt;/code>&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/cmd_flyctl_status.png" alt="flyctl deploy 完成後執行 flyctl status" data-caption="flyctl deploy 完成後執行 flyctl status" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='900px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:900px;height:;"/>
&lt;figcaption style="text-align: center;">
flyctl deploy 完成後執行 flyctl status
&lt;/figcaption>
&lt;/figure>
&lt;p>在 Hostname 那行顯示了我這個應用程式的網址(&lt;code>fly-flask.fly.dev&lt;/code>)，或者輸入 &lt;code>flyctl open&lt;/code> 也可自動從瀏覽器中打開。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/flyctl_open.png" alt="來看看部屬是否有成功吧" data-caption="來看看部屬是否有成功吧" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='450px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:450px;height:;"/>
&lt;figcaption style="text-align: center;">
來看看部屬是否有成功吧
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;p>如果要查看 IP 可以使用：&lt;code>flyctl ips list&lt;/code>&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/cmd_flyctl_ips_list.png" alt="查看 IP (flyctl ips list)" data-caption="查看 IP (flyctl ips list)" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='500px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:500px;height:;"/>
&lt;figcaption style="text-align: center;">
查看 IP (flyctl ips list)
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h2 id="dashboard-頁面">Dashboard 頁面&lt;/h2>
&lt;p>在 Fly.io 平台後台有 Dashboard 頁面，可以依據每個 App 去看更詳細的資訊、統計、設定等等。&lt;/p>
&lt;figure >
&lt;img data-src="https://res.cloudinary.com/jiablog/flyio_python/fly_dashboard.jpg" alt="Dashboard 頁面" data-caption="Dashboard 頁面" src="data:image/svg+xml,%0A%3Csvg xmlns='http://www.w3.org/2000/svg' width='900px' height='' viewBox='0 0 24 24'%3E%3Cpath fill='none' d='M0 0h24v24H0V0z'/%3E%3Cpath fill='%23aaa' d='M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 16H6c-.55 0-1-.45-1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1zm-4.44-6.19l-2.35 3.02-1.56-1.88c-.2-.25-.58-.24-.78.01l-1.74 2.23c-.26.33-.02.81.39.81h8.98c.41 0 .65-.47.4-.8l-2.55-3.39c-.19-.26-.59-.26-.79 0z'/%3E%3C/svg%3E" class="lazyload" style="width:900px;height:;"/>
&lt;figcaption style="text-align: center;">
Dashboard 頁面
&lt;/figcaption>
&lt;/figure>
&lt;br/>
&lt;h2 id="其他程式語言">其他程式語言&lt;/h2>
&lt;p>除了上述 Python 範例外，&lt;a href="https://fly.io/docs/getting-started/" target="_blank" rel="noopener">
官方文件
&lt;/a> 還提供更多不同程式語言的文章，目前看到的有 Crystal、Deno、Elixir、Go、Node、Laravel、Rails、Redwood、Remix、NuxtJS、NextJS、Ruby、靜態網站。&lt;/p>
&lt;p>甚至也可以使用 Dockerfile 部署在 Docker，所以照理來講它應該可以運行大部分的程式。&lt;/p>
&lt;br/>
&lt;!--adsense-->
&lt;h2 id="結語">結語&lt;/h2>
&lt;p>實際操作過一遍後，也會發現其實也蠻容易的。&lt;/p>
&lt;p>如果你想像 Heroku 一樣，程式碼推送到 GitHub 後自動佈署到 Fly.io，則可以參考這篇官方文章：&lt;a href="https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/" target="_blank" rel="noopener">
Continuous Deployment with Fly and GitHub Actions
&lt;/a>&lt;/p>
&lt;p>之後如果有資料要儲存，可以起個 &lt;a href="https://fly.io/docs/reference/postgres/" target="_blank" rel="noopener">
Postgres
&lt;/a>、&lt;a href="https://fly.io/docs/app-guides/mysql-on-fly/" target="_blank" rel="noopener">
MySQL
&lt;/a>、&lt;a href="https://fly.io/docs/getting-started/edgedb/" target="_blank" rel="noopener">
EdgeDB
&lt;/a> 資料庫(DB)，這幾個官方都有寫詳細的文件說明。&lt;/p>
&lt;br/>
&lt;p>題外話&lt;br />
Fly.io 並不是使用 Docker 去運行 container 容器，而是使用 Firecracker micro-VMs 開源的虛擬化技術，說是 Docker 的隔離性還不太夠，這方面我就不太了解，有興趣的網友可以閱讀官方說明：&lt;a href="https://fly.io/blog/docker-without-docker/" target="_blank" rel="noopener">
Docker Without Docker
&lt;/a>&lt;/p>
&lt;br/>
&lt;br/>
&lt;hr />
&lt;p>參考：&lt;br />
&lt;a href="https://fly.io/" target="_blank" rel="noopener">
Fly.io 官方網站
&lt;/a>&lt;br />
&lt;a href="https://fly.io/docs/" target="_blank" rel="noopener">
Fly.io 官方文件
&lt;/a>&lt;br />
&lt;a href="https://www.youtube.com/watch?v=CedAzHw1k5I" target="_blank" rel="noopener">
Fly.io 官方教學影片—Tutorial: Deploy a non-web Python application to Fly.io
&lt;/a>&lt;/p>
&lt;br/>
&lt;blockquote>
&lt;p>珍惜今天，珍惜現在，誰知道明天和意外，哪一個先來。&lt;/p>
&lt;p align="right">—— 《螢火蟲之墓》&lt;/p>
&lt;/blockquote></content:encoded><dc:creator>Jia</dc:creator><media:content url="https://blog.jiatool.comimages/cover/flyio_python.jpg" medium="image"><media:title type="html">featured image</media:title></media:content><media:content url="https://blog.jiatool.comimages/posts/flyio_python_meta.jpg" medium="image"><media:title type="html">meta image</media:title></media:content><category>Python</category><category>Flask</category><category>分享</category></item></channel></rss>