Python: 進階用法
深入了解 Python 部署
👋 歡迎來到 Stackhero 文檔!
Stackhero 提供一個即用型的 Python 雲端 解決方案,帶來多項好處,包括:
- 只需一個簡單的
git push,即可在幾秒鐘內部署您的應用程式。- 使用您自己的域名,並享受 HTTPS 證書的自動配置以增強安全性。
- 享受自動備份、一鍵更新,以及簡單、透明且可預測的定價,讓您安心無憂。
- 得益於專用的私人 VM,獲得最佳的性能和強大的安全性。
節省時間並簡化您的生活:只需 5 分鐘即可嘗試 Stackhero 的 Python 雲端託管 解決方案!
部署非 main 的分支
到目前為止,我們使用 git push stackhero main 命令將 main 分支部署到生產環境。
如果您需要部署其他分支,可以使用以下命令,其中 <BRANCH> 是您想要部署的分支名稱:
git push stackhero <BRANCH>:main
例如,如果您想部署 production 分支,只需執行:
git push stackhero production:main
部署標籤而非分支
您可以選擇部署標籤而不是分支。要部署特定標籤,請在以下命令中將 <TAG> 替換為您想要的標籤:
git push stackhero '<TAG>^{}:main'
例如,要部署標籤 v1.0.0,您將執行:
git push stackhero 'v1.0.0^{}:main'
^{}語法確保您推送的是標籤的提交而不是標籤引用本身。
部署特定提交
除了部署分支或標籤,您還可以使用提交的哈希值來部署特定提交。將 <COMMIT_HASH> 替換為您想要部署的提交哈希:
git push -f stackhero <COMMIT_HASH>:main
例如,要部署哈希為 abcde 的提交,請執行:
git push -f stackhero abcde:main
回滾到先前版本
如果最近的部署引入了問題,您可以通過部署早期的提交來回滾。首先,通過執行以下命令識別提交哈希:
git log
此命令顯示每個提交的日期、哈希和描述。
例如,輸出可能如下所示:
git log
commit cccc8b3ebdccb9abc1926ef49ee589dae5c5fe06 (HEAD -> main, stackhero/main)
Author: Developer
Date: Fri Apr 28 09:36:18 +0000
Break the code
commit bbbb622301772072c3d82f3cc0d91e29e6e84901
Author: Developer
Date: Wed Apr 26 12:49:28 +0000
Update the code
commit aaaa1d8b06535b413e0df8298ccf52339dfef3ff
Author: Developer
Date: Wed Apr 26 12:44:50 +0000
Improve the code
如果當前生產部署是提交 "Break the code"(哈希以 cccc 開頭),而您希望回滾到先前的提交 "Update the code"(哈希以 bbbb 開頭),請執行:
git push -f stackhero bbbb622301772072c3d82f3cc0d91e29e6e84901:main
為了避免部署有缺陷的代碼並提高生產穩定性,強烈建議設置一個 "staging" 環境。
位於開發和生產之間,staging 環境提供了生產設置的近似副本。它幫助您在實時部署之前徹底測試代碼。
使用 staging 增加了對代碼功能和性能的信心,從而實現更穩定的生產部署。
這種類型的環境將在文檔中稍後討論。
設置 staging 環境
當與開發和生產環境一起使用時,staging 環境是一種最佳實踐。它複製生產環境,以便您可以在上線之前測試更新和更改,從而降低生產中的問題風險。
staging 環境必須緊密反映生產環境。
然而,它應使用生產數據庫或連接服務的克隆版本,而不是實時生產數據庫。
如果您的 Python 服務依賴於數據庫或其他服務,請在新的
<Project> - Staging堆疊中重新創建它們。
按照以下步驟使用 Stackhero 設置 staging 環境:
- 在 Stackhero 儀表板上,將現有堆疊從
<Project>重命名為<Project> - Production。例如,如果您的項目名為Chat Bot,則堆疊變為Chat Bot - Production。 - 創建一個名為
<Project> - Staging的新堆疊。對於Chat Bot項目,堆疊變為Chat Bot - Staging。 - 在 staging 堆疊中啟動 Python 服務。
- 獲取
git remote命令並按照 部署到 staging 環境 文檔中的說明進行操作。
此配置確保您擁有一個功能齊全的 staging 環境,以便在生產部署之前測試更新。
部署到 staging 環境
強烈建議維護單獨的 staging 和生產環境。要管理多個環境,首先重命名當前的遠程存儲庫。例如,將遠程 stackhero 重命名為 stackhero-production:
git remote rename stackhero stackhero-production
接下來,為您的 staging 環境創建一個新的 Python 服務。獲取 git remote add 命令並將 <XXXXXX> 替換為您的服務域:
-
原始命令:
git remote add stackhero ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git -
修改後的命令:
git remote add stackhero-staging ssh://stackhero@<XXXXXX>.stackhero-network.com:222/project.git
然後,您可以使用以下命令部署到任一環境:
-
部署到 staging:
git push stackhero-staging main -
部署到生產:
git push stackhero-production main
為了改善部署過程,我們建議使用 改進版 Makefile。
使用這個改進的
Makefile,部署到生產或 staging 變得像運行make deploy-production或make deploy-staging一樣簡單。
改進版 Makefile
以下是支持多個規則的改進版 Makefile:
make dev(或簡單地make):以開發模式啟動應用程序。make deploy:將應用程序部署到名為stackhero的遠程。這在您只有一個 Stackhero 實例時效果很好。make deploy-production:將應用程序部署到名為stackhero-production的遠程。make deploy-staging:將應用程序部署到名為stackhero-staging的遠程。
此
Makefile設計用於處理代碼未更改的情況,避免 "Everything up-to-date" 錯誤。
複製並粘貼以下內容作為您的新 Makefile:
# 默認執行的規則,當不帶參數調用 "make" 時執行
.DEFAULT_GOAL := dev
# Stackhero for Python 將在您的實例上執行 "run" 規則。
# 這是在您的生產和 staging 環境中運行的命令。
run:
ENV=production gunicorn app:app \
--error-logfile - \
-b 0.0.0.0:8080
# 在開發環境中使用的命令
dev:
python app.py
# "deploy" 規則用於部署到 "stackhero" 實例。
# 適合您只有一個實例的情況。
deploy:
@$(MAKE) -s deploy-script DEPLOY_REMOTE=stackhero DEPLOY_BRANCH=main
# "deploy-*" 規則部署到名為 "stackhero-*" 的實例。
# 例如,運行 "make deploy-production" 部署到 "stackhero-production",
# 或 "make deploy-staging" 部署到 "stackhero-staging"。
deploy-%:
@$(MAKE) -s deploy-script DEPLOY_REMOTE=stackhero-$* DEPLOY_BRANCH=main
# 內部部署規則。請勿修改。
deploy-script:
@echo "正在將分支 \"${DEPLOY_BRANCH}\" 部署到 \"${DEPLOY_REMOTE}\"..."
@echo
@if [ -n "$$(git status --porcelain)" ]; then \
echo "無法部署,因為有未提交的更改:"; \
echo "\e[0m"; \
git status -s; \
echo ""; \
echo "\e[0;31m"; \
echo "您可以使用此命令提交更改:"; \
echo "git add -A . && git commit -m \"您的信息\""; \
echo "\e[0m"; \
exit 1; \
fi
@git push --dry-run ${DEPLOY_REMOTE} ${DEPLOY_BRANCH} 2>&1 | grep -q -F "Everything up-to-date"; \
EXIT_CODE=$$?; \
if [ $$EXIT_CODE -eq 0 ]; then \
echo -n "沒有新內容可部署... 強制部署(這將創建一個新提交)? (y/N) "; \
read answer && \
case $$answer in \
y|Y|yes|YES) \
git commit --allow-empty -m "為部署目的強制更新到 \"${DEPLOY_REMOTE}\"" ; \
;; \
*) \
echo "沒有可部署的內容!"; \
exit 1; \
;; \
esac \
fi
git push ${DEPLOY_REMOTE} ${DEPLOY_BRANCH}
處理機密(環境變量)
在某些時候,您需要存儲如令牌和數據庫或第三方服務的密碼等機密。重要的是要安全地存儲這些信息。避免將它們直接嵌入到您的存儲庫或代碼中,因為這會造成重大安全風險。
使用環境變量提供了兩個主要優勢:
- 您的機密從未存儲在您的 Git 存儲庫中,從而降低未經授權訪問的風險。
- 您可以為不同的環境使用不同的憑證,例如在生產中使用生產數據庫,在開發中使用開發數據庫。
為開發設置環境變量
在開發環境中,在項目根目錄創建 .env 文件。此文件應從 Git 中排除,以確保它從未被提交。
要自動讀取 .env 文件,您可以使用 python-dotenv 模塊:
pip install python-dotenv
pip freeze > requirements.txt
然後,在項目根目錄創建 .env 文件並添加您的變量:
ENV="development"
DATABASE_PASSWORD="secretPassword"
THIRD_API_PRIVATE_KEY="secretKey"
# ...
最後,確保 .env 文件被排除在 Git 之外,將其添加到 .gitignore:
echo ".env" >> .gitignore
為 staging 和生產設置環境變量
.env 文件對於 staging 和生產環境來說不夠安全。相反,Stackhero 允許您將環境變量安全地存儲在您的 Python 服務配置中。
您可以在 Stackhero 儀表板中選擇您的 Python 服務,然後點擊 "Configure" 按鈕來設置這些變量。
Stackhero 上的 Python 環境變量
在 Python 中訪問環境變量
在 Python 中訪問環境變量很簡單。只需使用 os.environ.get(),如下所示:
import os
print(os.environ.get('ENV'))
例如,使用環境變量連接到 Redis 服務器可以這樣做:
import os
import redis
r = redis.from_url(os.environ.get("REDIS_URL"))
在開發環境中,在 .env 文件中設置 REDIS_URL 如下:
REDIS_URL="redis://localhost:6379"
對於生產和 staging,請在 Stackhero 儀表板的 Python 服務配置中定義 REDIS_URL:
REDIS_URL="rediss://default:<yourPassword>@<XXXXXX>.stackhero-network.com:6380"
管理 Python 套件
使用 requirements.txt 文件管理 Python 套件是一種最佳實踐。此文件列出了運行代碼所需的所有套件及其版本,以確保可靠運行。
保持此文件的更新可確保:
- 安裝了所有必需的套件。
- 僅使用兼容的套件版本。
在部署到您的 Stackhero 實例時,requirements.txt 中指定的套件會自動安裝。
在安裝新套件後,運行以下命令生成或更新 requirements.txt:
pip freeze > requirements.txt
開啟 UDP/TCP 端口
大多數 Python 應用程序使用 HTTP 端口 80(HTTP)和 443(HTTPS)。
如果您的應用程序需要開啟其他端口或使用其他協議(TCP 或 UDP),您可以在 Stackhero 儀表板的 Python 服務中調整 "Ports Redirections" 設置。
對於每個額外的端口,指定入口端口(公共面向)、目標端口(由您的 Python 應用程序使用)和協議(TCP 或 UDP)。
Stackhero 儀表板中的端口重定向
文件存儲
對於存儲用戶照片或文檔等文件,通常最好使用對象存儲解決方案。
對象存儲允許您在多個服務或實例之間共享文件,並將存儲與代碼分開,遵循最佳實踐。
我們推薦 MinIO,這是一個快速且強大的解決方案,兼容 Amazon S3 協議。
如果您更喜歡本地文件存儲,可以使用位於 /persistent/storage/ 的 Python 實例提供的持久存儲。然而,在大多數情況下不建議這種方法。
警告:切勿將數據存儲在
/persistent/storage/文件夾之外!將數據存儲在此文件夾之外可能會導致數據丟失,當您的實例重新啟動、更新或推送新代碼時。
Apple/macOS:保存您的 SSH 私鑰密碼
在 macOS 上,每次推送代碼時輸入 SSH 私鑰密碼可能會很麻煩。雖然安全性至關重要,但您可以使用 Apple 的鑰匙串安全地保存密碼,而不是從密鑰中刪除它。
要存儲名為 id_ed25519 的密鑰密碼,請執行:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
之後,您將不會被提示輸入密鑰密碼,節省時間和精力。
如果您使用的是 RSA 密鑰,請在命令中將
id_ed25519替換為id_rsa:ssh-add --apple-use-keychain ~/.ssh/id_rsa