在軟體開發的快速世界中,快速且可靠地交付高質量應用程式至關重要。這就是CI/CD(持續整合和持續交付/部署)發揮作用的地方。

CI/CD是一組設計用於自動化並優化程式碼變更整合、測試和部署流程的實踐和工具。通過採用CI/CD,您的團隊可以減少手動錯誤,加快發布週期,並確保您的程式碼始終處於可部署狀態。

在本教程中,我們將專注於使用Bitbucket、Linux伺服器和具有Flask的Python來建立基本的CI/CD管道的初學者友好方法。具體來說,我們將創建一個自動化流程,每當有推送或合併到特定分支時,就會從Bitbucket存儲庫中拉取最新更改至您的Linux伺服器。

這個流程將由Bitbucket Webhooks和一個簡單的基於Flask的Python伺服器驅動,該伺服器會監聽傳入的Webhook事件並觸發部署。

值得注意的是,CI/CD是一個龐大且複雜的領域,本教程旨在提供基礎理解,而不是作為一個詳盡的指南。

我們將介紹使用對初學者來說易於接觸的工具建立CI/CD管道的基礎知識。請記住,現實世界中的CI/CD系統通常涉及更高級的工具和配置,例如容器化、編排和多階段測試環境。

通過本教程的最後,您將瞭解如何使用Bitbucket、Linux和Python自動化部署的工作示例,隨著您對CI/CD概念的熟悉程度不斷增加,您可以在此基礎上進一步擴展。

目錄:

  1. 為什麼CI/CD很重要?

  2. 步驟1:在Bitbucket中設置Webhook

  3. 步驟2:在您的Linux伺服器上設置Flask監聽器

  4. 步驟3:公開Flask應用程序(可選)

  5. 步驟4:測試設置

  6. 步驟5:安全考量

  7. 結語

CI/CD 為何重要?

CI/CD 已成為現代軟體開發的基石,原因有幾個。首先,它加速了開發過程。通過自動化重複性任務,如測試和部署,開發人員可以更多地專注於編寫代碼,而不是手動流程。這導致新功能和錯誤修復更快地交付,這在競爭激烈的市場中尤為重要,因為速度可以成為區隔因素。

CI/CD 的另一個關鍵好處是降低錯誤並提高可靠性。自動化測試確保每個代碼更改在集成到主代碼庫之前都經過嚴格檢查,這減少了引入可能擾亂應用程序或需要後續昂貴修復的錯誤的風險。自動化部署流程還減少了在發布過程中出現人為錯誤的可能性,確保部署是一致和可預測的。

CI/CD還促進團隊成員之間更好的協作。在傳統的開發工作流程中,從多個開發人員整合代碼更改可能是耗時且容易出錯的過程。有了CI/CD,代碼經常被集成和測試,通常一天多次。這意味著衝突被及早檢測並解決,代碼庫保持穩定。因此,團隊可以更高效地工作並更有信心,即使多個貢獻者同時在項目的不同部分工作。

最後,CI/CD支持持續改進和創新。通過自動化部署過程,團隊可以更頻繁地且更少風險地將更新發布到生產環境。這使他們可以更快地從用戶獲得反饋並更有效地對產品進行迭代。

本教程將涵蓋的內容

在本教程中,我們將介紹設置一個簡單的CI/CD流水線的過程,該流水線將自動將Bitbucket存儲庫中的代碼更改部署到Linux服務器。你將學到:

  1. 如何配置Bitbucket存儲庫,以在特定分支推送或合併時發送webhook通知。

  2. 如何在Linux服務器上設置基於Flask的Python服務器,以便監聽傳入的webhook事件。

  3. 如何編寫一個腳本,從存儲庫中提取最新更改並部署到伺服器。

  4. 如何測試和排除自動部署流程中的問題。

完成本教程後,您將擁有一個基本CI/CD流水線的工作範例,您可以根據需要進行自定義和擴展。讓我們開始吧!

第1步:在Bitbucket中設置Webhook

在開始設置之前,讓我們簡要解釋一下webhook是什麼,以及它如何融入我們的CI/CD流程。

Webhook是一種機制,允許一個系統即時通知另一個系統發生的事件。在Bitbucket的上下文中,可以配置一個Webhook,當存儲庫中發生特定事件時(例如對分支的推送或拉取請求合併),它會向指定的URL發送HTTP請求(通常是帶有有效載荷數據的POST請求)。

在我們的情況下,當特定分支推送或合併時,Webhook將通知我們基於Flask的Python伺服器(運行在您的Linux伺服器上)。此通知將觸發伺服器上的腳本自動提取存儲庫中的最新更改並部署它們。基本上,Webhook充當Bitbucket和您的伺服器之間的橋樑,實現部署流程的無縫自動化。

現在您了解了Webhook的作用,讓我們在Bitbucket中設置一個:

  1. 登入Bitbucket並導航至您的存儲庫。

  2. 在左側側邊欄中,點擊設置

  3. 工作流程部分下,找到並點擊Webhooks

  4. 點擊添加webhook按鈕。

  5. 為您的webhook輸入一個名稱(例如,“自動拉取”)。

  6. URL欄中,提供webhook將發送請求的伺服器URL。如果您在本地運行Flask應用程式,這將類似於http://your-server-ip/pull-repo。(對於生產環境,強烈建議使用HTTPS來保護Bitbucket和您的伺服器之間的通信。)

  7. 觸發器部分,選擇您想要監聽的事件。在這個例子中,我們將選擇推送(Push)(還可以選擇合併的拉取請求(Pull Request Merged)如果您也想在合併後部署)。

  8. 保存Webhook時使用一個自我說明的名稱,以便稍後易於識別。

設置完Webhook後,每當所選事件發生時,Bitbucket將向指定的URL發送一個POST請求。在接下來的步驟中,我們將設置一個Flask服務器來處理這些傳入的請求並觸發部署過程。

這是您在設置Bitbucket webhook時應該看到的內容

第2步:在您的Linux服務器上設置Flask監聽器

在下一步中,您將在Linux機器上設置一個簡單的網絡伺服器,以監聽來自Bitbucket的Webhook。當它收到通知時,將執行git pull或強制拉取(以防本地更改)來更新存儲庫。

安裝Flask:

要創建Flask應用程式,請首先運行以下命令安裝Flask:

pip install flask

創建Flask應用程式:

在伺服器上創建一個新的Python腳本(例如,app_repo_pull.py),並添加以下代碼:

from flask import Flask
import subprocess

app = Flask(__name__)

@app.route('/pull-repo', methods=['POST'])
def pull_repo():
    try:
        # 從遠程存儲庫獲取最新更改
        subprocess.run(["git", "-C", "/path/to/your/repository", "fetch"], check=True)
        # 強制重置本地分支以匹配遠程的 'test' 分支
        subprocess.run(["git", "-C", "/path/to/your/repository", "reset", "--hard", "origin/test"], check=True)  # 將 'test' 替換為您的分支名稱
        return "Force pull successful", 200
    except subprocess.CalledProcessError:
        return "Failed to force pull the repository", 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

這段代碼的功能如下:

  • subprocess.run(["git", "-C", "/path/to/your/repository", "fetch"]):此命令從遠程存儲庫提取最新更改,而不影響本地工作目錄。

  • subprocess.run(["git", "-C", "/path/to/your/repository", "reset", "--hard", "origin/test"]):此命令執行硬重置,強制本地存儲庫與遠端test分支匹配。將test替換為您的分支名稱。

請確保將/path/to/your/repository替換為實際的本地Git存儲庫路徑。

步驟 3:公開 Flask 應用程式(可選)

如果希望從伺服器外部訪問Flask應用程式,則需要將其公開。為此,您可以使用NGINX設置反向代理。以下是如何執行此操作:

首先,如果尚未安裝NGINX,請運行此命令進行安裝:

sudo apt-get install nginx

接下來,您需要配置NGINX以將請求代理到您的Flask應用程式。打開NGINX配置文件:

sudo nano /etc/nginx/sites-available/default

修改配置以包含此區塊:

server {
    listen 80;
    server_name your-server-ip;

    location /pull-repo {
        proxy_pass http://localhost: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;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

現在只需重新加載NGINX以應用更改:

sudo systemctl reload nginx

步驟 4:測試設置

現在一切都設置好了,請執行此Python腳本來啟動Flask應用程式:

python3 app_repo_pull.py

現在來測試一切是否運作正常:

  1. 進行提交:將提交推送到您Bitbucket存儲庫中的test分支。此操作將觸發 Webhook。
  1. Webhook 觸發:Webhook 將向您的伺服器發送 POST 請求。Flask 應用將接收此請求,從test分支執行強制拉取,並更新本地存儲庫。

  2. 驗證拉取:檢查您的 Flask 應用的日誌輸出或檢查本地存儲庫,以確認更改已成功拉取並應用。

第5步:安全考量

當將 Flask 應用公開到互聯網時,確保伺服器和應用程式的安全性至關重要,以保護免受未經授權訪問、數據泄露和攻擊。以下是需要關注的關鍵領域:

1. 使用帶有適當防火牆規則的安全伺服器

安全伺服器是配置為最小化受外部威脅影響的伺服器。這包括使用防火牆規則、最小化不必要的服務,並確保僅打開通訊所需的端口。

安全伺服器設置示例:
  • 最小化軟體:僅安裝您需要的軟體(例如Python、Flask、NGINX),並移除不必要的服務。

  • 作業系統更新:確保您的伺服器作業系統有最新的安全補丁。

  • 防火牆設定:使用防火牆控制進出流量,限制對伺服器的訪問。

例如,在Ubuntu上,基本的UFW(簡易防火牆)配置可能如下:

# 允許SSH(端口22)進行遠程訪問
sudo ufw allow ssh

# 允許HTTP(端口80)和HTTPS(端口443)進行網路流量
sudo ufw allow http
sudo ufw allow https

# 啟用防火牆
sudo ufw enable

# 檢查防火牆狀態
sudo ufw status

在這種情況下:

  • 防火牆允許通過端口22進入SSH連接,端口80上的HTTP和端口443上的HTTPS。

  • 任何不必要的端口或服務應該默認被阻擋,以限制攻擊的風險。

附加防火牆規則:
  • 限制對webhook端點的訪問:理想情況下,只允許來自Bitbucket IP地址的流量訪問webhook端點,以防止外部訪問。您可以在防火牆中設置此設定,或者使用您的web服務器(例如NGINX),只接受來自Bitbucket IP範圍的請求。

  • 拒絕所有其他傳入流量:對於不需要向互聯網公開的任何服務(例如數據庫端口),請確保這些端口被阻擋。

2. 為Flask應用添加身份驗證

由於您的Flask應用將通過webhook URL公開訪問,因此應考慮添加身份驗證,以確保僅授權使用者(例如Bitbucket的伺服器)可以觸發拉取操作。

基本身份驗證示例:

您可以使用簡單的基於令牌的身份驗證來保護您的 Webhook 端點。以下是如何修改您的 Flask 應用程序以要求身份驗證令牌的示例:

from flask import Flask, request, abort
import subprocess

app = Flask(__name__)

# 為 Webhook 驗證定義一個秘密令牌
SECRET_TOKEN = 'your-secret-token'

@app.route('/pull-repo', methods=['POST'])
def pull_repo():
    # 檢查請求是否包含正確的令牌
    token = request.headers.get('X-Hub-Signature')
    if token != SECRET_TOKEN:
        abort(403)  # 如果令牌不正確,則拒絕

    try:
        subprocess.run(["git", "-C", "/path/to/your/repository", "fetch"], check=True)
        subprocess.run(["git", "-C", "/path/to/your/repository", "reset", "--hard", "origin/test"], check=True)
        return "Force pull successful", 200
    except subprocess.CalledProcessError:
        return "Failed to force pull the repository", 500

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
工作原理:
  • X-Hub-Signature 是您在 Bitbucket 設置 Webhook 時添加到請求中的自定義標頭。

  • 只有包含正確令牌的請求才能觸發拉取。如果缺少或不正確,該請求將被拒絕並返回 403 Forbidden 響應。

您還可以使用更複雜的身份驗證形式,如 OAuth 或 HMAC(基於哈希的消息驗證碼),但這種簡單的令牌方法適用於許多情況。

3. 使用 HTTPS 進行安全通信

對於您的 Flask 應用程序和 Bitbucket Webhook 之間傳輸的數據以及任何敏感數據(如令牌或密碼)進行加密是至關重要的。這確保攻擊者無法截取或修改數據。

為什麼要使用HTTPS?
  • 資料加密:HTTPS加密通訊,確保敏感資料(如您的驗證令牌)不會暴露在中間人攻擊中。

  • 信任與完整性:HTTPS有助於確保您的伺服器接收的資料未被篡改。

使用Let’s Encrypt為您的Flask應用程式配置SSL:
  1. 安裝Certbot(用於獲取Let’s Encrypt憑證的工具):
sudo apt-get update
sudo apt-get install certbot python3-certbot-nginx

為您的域名獲取免費SSL憑證

sudo certbot --nginx -d your-domain.com
  • 此命令將自動配置Nginx以使用來自Let’s Encrypt的免費SSL憑證的HTTPS。

  • 確保使用HTTPS:確保您的Flask應用程式或Nginx配置強制所有流量使用HTTPS。您可以通過在Nginx中設置重定向規則來實現這一點:

server {
    listen 80;
    server_name your-domain.com;

    # 將HTTP重定向到HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    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;

    # 其他Nginx配置...
}

自動續期:Let’s Encrypt證書有效期為90天,因此設置自動續期非常重要:

sudo certbot renew --dry-run

此命令測試續期流程,確保一切運作正常。

4. 記錄和監控

為您的Flask應用實施記錄和監控,以跟踪任何未經授權的嘗試、錯誤或異常活動:

  • 記錄請求:記錄所有傳入請求,包括IP地址、請求標頭和響應狀態,以便監控任何可疑活動。

  • 使用監控工具:設置像PrometheusGrafanaNew Relic這樣的工具,來監控伺服器性能和應用程式健康狀況。

總結

在本教程中,我們探討了如何設置一個簡單、適合初學者的CI/CD流水線,使用Bitbucket、Linux伺服器和具有Flask的Python自動化部署。以下是您學到的內容:

  1. CI/CD基礎: 我們討論了持續整合(CI)和持續交付/部署(CD)的基本概念,這是自動化代碼整合、測試和部署的基本實踐。您了解了CI/CD如何幫助加速開發、減少錯誤並改善開發人員之間的協作。

  2. 設置Bitbucket Webhooks: 您了解了如何配置Bitbucket webhook,以在特定分支推送或合併時通知您的伺服器。這個webhook作為觸發器,可自動啟動部署過程。

  3. 創建基於Flask的Webhook監聽器: 我們向您展示了如何在Linux伺服器上設置一個Flask應用程式,以監聽來自Bitbucket的webhook請求。這個Flask應用程式接收通知並運行必要的Git命令以拉取和部署最新更改。

  4. 自動化部署流程:使用Python和Flask,我們自動化了從Bitbucket存儲庫中拉取更改並執行強制拉取的流程,以確保最新的程式碼被部署。您還學會了如何配置伺服器以公開Flask應用程式並安全接受請求。

  5. 安全考量:我們介紹了保護部署流程的關鍵安全步驟:

    • 防火牆規則:我們討論了配置防火牆規則以限制曝光,確保只有授權的流量(來自Bitbucket)可以訪問您的伺服器。

    • 身份驗證:我們添加了基於令牌的身份驗證,以確保只有授權的請求可以觸發部署。

    • HTTPS:我們解釋了如何使用Let’s Encrypt的SSL憑證來保護您的伺服器和Bitbucket之間的通信。

    • 記錄和監控:最後,我們建議設置記錄和監控來跟蹤任何異常活動或錯誤。

下一步驟

在本教程结束时,您现在已经拥有一个自动化部署流水线的工作示例。虽然这只是一个基本实现,但它可以作为您进一步构建的基础。随着您对CI/CD越来越熟悉,您可以探索高级主题,如:

  • 多阶段部署流水线

  • 与Docker等容器化工具的集成

  • 更复杂的测试和部署策略

  • 使用像Kubernetes这样的编排工具进行扩展

CI/CD实践不断发展,通过掌握基础知识,您已经为自己在这一领域扩展技能奠定了成功的基础。祝您自动化愉快,感谢阅读!

您可以从这里fork代码