← 返回導覽

自動化部署之道

Ansible & Python Automation

Python:自修復的智慧

此方法採用單一 Python 腳本 (vps_deploy.py),直接在 VPS 上運行。它內建了強大的「自修復 (Self-Healing)」邏輯,能在安裝失敗時自動切換備用方案。

  • 系統淨化: 自動更新 APT 快取並安裝基礎相依套件。
  • 意圖感知: 互動式詢問 SSL Email、網域及容器端口資訊。
  • 韌性安裝: 嘗試 APT 安裝 Docker,若失敗則自動切換至官方腳本。
  • 安全閉環: 自動申請 SSL 並配置防火牆 (僅開放 80/443/22)。

部署代碼

請複製以下代碼並存為 vps_deploy.py,使用 root 權限執行。

import os
import subprocess
import time
import sys

# --- 顏色定義 ---
class Color:
    RED = '\033[91m'
    GREEN = '\033[92m'
    YELLOW = '\033[93m'
    END = '\033[0m'

CONFIG = {}

def run_command_with_retry(command, error_keyword=None, fix_command=None, max_retries=3, description=""):
    print(f"\n{Color.YELLOW}--> 執行: {description} ...{Color.END}")
    for attempt in range(max_retries):
        result = subprocess.run(command, shell=True, capture_output=True, text=True)
        if result.returncode == 0:
            print(f"{Color.GREEN}   ✅ 成功{Color.END}")
            return True
        print(f"{Color.RED}   ❌ 失敗 (嘗試 {attempt + 1}/{max_retries}){Color.END}")
        if error_keyword and fix_command and (error_keyword in result.stderr or error_keyword in result.stdout):
            print(f"{Color.YELLOW}   🛠️ 嘗試自動修正...{Color.END}")
            subprocess.run(fix_command, shell=True)
            continue
    print(f"{Color.RED}🚨 致命錯誤:{description} 失敗{Color.END}")
    sys.exit(1)

def main():
    if os.geteuid() != 0:
        print("請使用 root 權限執行。")
        sys.exit(1)

    print("=== VPS 自動化部署啟動 ===")
    
    # 1. 系統更新
    run_command_with_retry("apt update", description="更新 APT")
    run_command_with_retry("apt install -y curl wget git nginx certbot python3-certbot-nginx", description="安裝基礎套件")

    # 2. 收集資訊
    try:
        CONFIG['email'] = input("SSL Email: ").strip()
        CONFIG['domain'] = input("Domain (e.g., app.com): ").strip()
    except KeyboardInterrupt: sys.exit(0)

    # 3. 安裝 Docker (帶 fallback)
    run_command_with_retry(
        "apt install -y docker-ce docker-ce-cli containerd.io", 
        error_keyword="E:", 
        fix_command="curl -fsSL https://get.docker.com | sh",
        description="安裝 Docker"
    )

    # 4. 配置 Nginx
    nginx_conf = f"""server {{
    listen 80;
    server_name {CONFIG['domain']};
    location / {{
        return 200 'Hello from {CONFIG['domain']}';
    }}
}}"""
    with open(f"/etc/nginx/sites-available/{CONFIG['domain']}", "w") as f:
        f.write(nginx_conf)
    
    if os.path.exists(f"/etc/nginx/sites-enabled/{CONFIG['domain']}"):
        os.remove(f"/etc/nginx/sites-enabled/{CONFIG['domain']}")
    os.symlink(f"/etc/nginx/sites-available/{CONFIG['domain']}", f"/etc/nginx/sites-enabled/{CONFIG['domain']}")
    
    run_command_with_retry("systemctl reload nginx", description="重載 Nginx")

    # 5. SSL
    run_command_with_retry(
        f"certbot --nginx -d {CONFIG['domain']} --non-interactive --agree-tos -m {CONFIG['email']} --redirect",
        description="申請 SSL 憑證"
    )

    print(f"\n{Color.GREEN}部署完成!訪問 https://{CONFIG['domain']}{Color.END}")

if __name__ == "__main__":
    main()

Ansible:編排者的藝術

Ansible 是一種「無代理 (Agentless)」的自動化工具。適合需要同時部署多台主機、追求基礎設施即代碼 (IaC) 的場景。

核心結構 (site.yml)

---
- name: VPS Full Deployment
  hosts: vps_servers
  become: yes
  vars:
    domain: "example.com"
    email: "admin@example.com"

  tasks:
    - name: 更新 APT 快取
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: 安裝 Docker 依賴
      apt:
        name: [apt-transport-https, ca-certificates, curl, gnupg]
        state: present

    - name: 添加 Docker GPG Key
      apt_key:
        url: https://download.docker.com/linux/debian/gpg
        state: present

    - name: 安裝 Docker
      apt:
        name: docker-ce
        state: present

    - name: 啟動 Docker
      service:
        name: docker
        state: started
        enabled: yes