commit 1b10271ee6cb323d375bed4170d97d941a00487d Author: Jeffery Date: Wed Jan 21 12:02:55 2026 +0800 first commit diff --git a/.gitea/workflows/cd.yaml b/.gitea/workflows/cd.yaml new file mode 100644 index 0000000..53e8f46 --- /dev/null +++ b/.gitea/workflows/cd.yaml @@ -0,0 +1,22 @@ +on: + push: + branches: + - master +jobs: + up: + name: "CD > 啟動服務" + runs-on: ct-docker + steps: + - name: 取得專案 + uses: actions/checkout@v4 + - name: 啟動 Traefik + run: cd "${{ gitea.workspace }}/traefik" && docker compose up -d --build + - name: 重新啟動 Traefik + run: cd "${{ gitea.workspace }}/traefik" && docker compose restart + clear: + name: "CD > 清理資源" + runs-on: ct-docker + needs: up + steps: + - name: 清理資源 + run: docker system prune -af --volumes \ No newline at end of file diff --git a/traefik/Dockerfile b/traefik/Dockerfile new file mode 100644 index 0000000..a2ca35c --- /dev/null +++ b/traefik/Dockerfile @@ -0,0 +1,3 @@ +FROM traefik:v3 + +COPY ./config /etc/traefik/config \ No newline at end of file diff --git a/traefik/README.md b/traefik/README.md new file mode 100644 index 0000000..f9f5eb9 --- /dev/null +++ b/traefik/README.md @@ -0,0 +1,23 @@ +# 安裝公鑰 + +```console +./mkcert -install +``` + +# 產生憑證 + +```console +./mkcert -key-file ./config/jsc.idv.me+4-key.pem -cert-file ./config/jsc.idv.me+4.pem jsc.idv.me *.jsc.idv.me localhost 127.0.0.1 ::1 +``` + +# 取得公鑰 + +```console +cp ~/.local/share/mkcert/rootCA.pem ./config +``` + +# 產生憑證匯入檔 + +```console +openssl pkcs12 -export -out ./jsc.idv.me.pfx -inkey ./config/jsc.idv.me+4-key.pem -in ./config/jsc.idv.me+4.pem -certfile ./config/rootCA.pem +``` diff --git a/traefik/config/certificates.yaml b/traefik/config/certificates.yaml new file mode 100644 index 0000000..c50e47d --- /dev/null +++ b/traefik/config/certificates.yaml @@ -0,0 +1,4 @@ +tls: + certificates: + - certFile: "/etc/traefik/config/jsc.idv.me+4.pem" + keyFile: "/etc/traefik/config/jsc.idv.me+4-key.pem" diff --git a/traefik/config/jsc.idv.me+4-key.pem b/traefik/config/jsc.idv.me+4-key.pem new file mode 100644 index 0000000..df2a6e4 --- /dev/null +++ b/traefik/config/jsc.idv.me+4-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDWvkk6kWJWjI4b +48QRW7HhhrncVwnn9Prz05qwVS4lCo41Q5Iw2LyDpEiYqGS+aiKUWIctrzBawIv2 +ZboAWVtzzoz1jMmCTY3NrmQw3WEkUD7/8HlV3hhNXv7k+csT8rHqepS+m/qCYwh1 +RfdxwhVIG03kzb4ugwZIXToCb9d+PNnXRCE7Zgdz0DLFXRwmDgGL2EaTCnm1PkOI +X/Y8GxfEboLddvO34XLhLPNlw4odWvP/dBsLI4fGoO4h1jAdgU2Y14ZbmdjtGMtN +MuCXl0SJ1dmIc2FRFPUEcflJm4c4pKuXjK8cFNgGdo2kE7Yhm9ora9vS0llN7lHQ +U+CpRuWTAgMBAAECggEAZVMV5G+y8dmSODCpU/NrJFnYmtHq16rtOl1O8QLQKiQn +45QFh8zMbmT26CkUmBAmTs7SwciWzUtq/xESyZVgJG2Cb15FupjzXuh5V+EtM+A1 +Sbhi2BRabS90oAAJRVlPf67lPmcEtb8av5MK5X9JYWOYxmwZ34JtVXm/pGS3TlV0 +ukDuIoxBmYd0vo1hT/crGZCfZlwW+5SXA5vnTwL6JtBJJOLx1owha+WH2Y5pozJ9 +bIvCdIiJrkJ/MJvBKyU19hEP7GEzQPhQJUNcK6EKfRWo/tAvezpj+WWPOlEFrs+A +/Z6PTgABmUMgjFl2UJdMrpvm97gtyabuCM6BMmDfCQKBgQDmC7tGFQihPO9Liaw3 +TA775bmhPzBgJHU/6YuIQk55czvyrLT/zTS/8s+oP9URXn/FZkDsiYy2ax46+0Nd +y+OqTHMXiBOp2sE5wVS3sNsENmkY0BOcAKMcMzFN86y98qY+K1QPUSQyPVloSVmf +PlFMEE9EiSmhruOR0e+H6A2KJQKBgQDu+JTZO8lkizqf8APYz8KDVlUk8VcrqDee +telK28lyRLFzOvsitBPK/zH9ejSuXHSSUo6Pp0pBWje1UZ1UODa70UF9KUPPEj8N ++CgGwIcZ/Iwz4VoQePP+Wr1ZOJMd8td+pCnhbekXsGNK0+rrZlhYVCWG8Mlp5QYI +pA81klM3VwKBgHuLOVv919Cf5PNwUGiyFCn7yaFrShOYAM/+IM1grrxSwpMlZV8r +WXTsddEp1sepNH1S2PMvO76L8IREhH1PDklbHUQ59DV4IeVeipzMAhNVFUQaGy3g +ubhfVc9DWjX4pockxdQkA4hnoih7nAIFeaub5rYr44vNXLHnSPh4Cy1xAoGBAM7V +Amf+8jF+vA//+iRmtdFdILan2C3mG7XXdwMetf2b7QZyDzkbKWJyfD8KzZv4U8Dt +iYxWW9OylTLvX7+sI9tto0QEOjd4cHDTzzkA3C4mwuaIbp6BQZVtziLx74tlSxTG +W6VMrwmc1mPGhbaWz3Ir6osfzwRDgHRsIunYKwRjAoGBANM3ObtDegjLil9wV65d +ii82eI3LVGvRX2vLQtrX1dATyk9XzU48oqGrmy1N/w4BUXP3iCx+HvRlIXeYxaqH +mCwx45AEZvynPojCL267Oy9+3y3baVI8oc8yTHBdvdaFkKYM2fFy1zlRGmPm7uup +qFzrvSEmPn7IxtugxIC3qdhQ +-----END PRIVATE KEY----- diff --git a/traefik/config/jsc.idv.me+4.pem b/traefik/config/jsc.idv.me+4.pem new file mode 100644 index 0000000..d610577 --- /dev/null +++ b/traefik/config/jsc.idv.me+4.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEdzCCAt+gAwIBAgIQWiFE9btAuOMh5NCtqdOF8zANBgkqhkiG9w0BAQsFADCB +gzEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMSwwKgYDVQQLDCNzaHVv +Y2hlbkB2bS1kb2NrZXIgKFNIVU8tQ0hFTiBKSUFOKTEzMDEGA1UEAwwqbWtjZXJ0 +IHNodW9jaGVuQHZtLWRvY2tlciAoU0hVTy1DSEVOIEpJQU4pMB4XDTI1MDQyNTA5 +MTcyMFoXDTI3MDcyNTA5MTcyMFowVzEnMCUGA1UEChMebWtjZXJ0IGRldmVsb3Bt +ZW50IGNlcnRpZmljYXRlMSwwKgYDVQQLDCNzaHVvY2hlbkB2bS1kb2NrZXIgKFNI +VU8tQ0hFTiBKSUFOKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANa+ +STqRYlaMjhvjxBFbseGGudxXCef0+vPTmrBVLiUKjjVDkjDYvIOkSJioZL5qIpRY +hy2vMFrAi/ZlugBZW3POjPWMyYJNjc2uZDDdYSRQPv/weVXeGE1e/uT5yxPysep6 +lL6b+oJjCHVF93HCFUgbTeTNvi6DBkhdOgJv13482ddEITtmB3PQMsVdHCYOAYvY +RpMKebU+Q4hf9jwbF8Rugt1287fhcuEs82XDih1a8/90Gwsjh8ag7iHWMB2BTZjX +hluZ2O0Yy00y4JeXRInV2YhzYVEU9QRx+Umbhzikq5eMrxwU2AZ2jaQTtiGb2itr +29LSWU3uUdBT4KlG5ZMCAwEAAaOBkTCBjjAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0l +BAwwCgYIKwYBBQUHAwEwHwYDVR0jBBgwFoAUAij2DW/P4hUAsOzil/bOvAcSJfQw +RgYDVR0RBD8wPYIKanNjLmlkdi5tZYIMKi5qc2MuaWR2Lm1lgglsb2NhbGhvc3SH +BH8AAAGHEAAAAAAAAAAAAAAAAAAAAAEwDQYJKoZIhvcNAQELBQADggGBADylkrW0 +Tx5U8UMh2AvH6wZwX4w5Qm2IVu2CKyR9g7CJmgmCMziR2a/XmTEqOfDjVyBGMwR+ +A0inhzivKII11HM/jlDhteBl+sho93f0lPfWRBgCaO8UXBkH/gudpSjZ6NEI5W1j +J4cnhV5aPWboSWlwrRYxDYETCeLluu6njDlcsERbF5OcLXopOEeCVeQwaHN3nu3O +0DLSr78Ztio+PZGlpznmrOtWRm9lgoKe9ugYdJOY+NtNcSpsaoXqZVgqf4UCCyu6 ++p8x8Kc8yj24lwSdEbiUYiI8fKk5kGrmBT0IShwR5Jds2B32dspeS92YfmIQHr+h +qRHXeCts7bmX4z4GqeT6dbBFwFKIBhWXl1M53GQvZpYWAiOjXkMt+FkbQL8zofnp +gLkpVqUZ6uBb/NZc7x7vtipzIswrJGjxqzpiqlfHTcn+3rwbD43NpNpNsI/Kqd81 +M3AuIAj00Nv7+EBH66SjN/YQSauYSdZJrFndMMPxAvPKfkhyee0ewLkWFw== +-----END CERTIFICATE----- diff --git a/traefik/config/rootCA.pem b/traefik/config/rootCA.pem new file mode 100644 index 0000000..ab5e41e --- /dev/null +++ b/traefik/config/rootCA.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIE1zCCAz+gAwIBAgIQa4BGxgsUBBsGn5Lx+ryQmDANBgkqhkiG9w0BAQsFADCB +gzEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMSwwKgYDVQQLDCNzaHVv +Y2hlbkB2bS1kb2NrZXIgKFNIVU8tQ0hFTiBKSUFOKTEzMDEGA1UEAwwqbWtjZXJ0 +IHNodW9jaGVuQHZtLWRvY2tlciAoU0hVTy1DSEVOIEpJQU4pMB4XDTI1MDQyNTA5 +MTY0OFoXDTM1MDQyNTA5MTY0OFowgYMxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9w +bWVudCBDQTEsMCoGA1UECwwjc2h1b2NoZW5Adm0tZG9ja2VyIChTSFVPLUNIRU4g +SklBTikxMzAxBgNVBAMMKm1rY2VydCBzaHVvY2hlbkB2bS1kb2NrZXIgKFNIVU8t +Q0hFTiBKSUFOKTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAL0gzICC +R2s7us7tpzFRSyG7HGrqu25fjd49/aESzYMk9ztCj5Zm5uIT3O7xqfj2y2UsQcuw +xL0FzsECQUeQx7PQwWOMnZfyYFrlkBFbDZa9nVHltsC8t/C1IP0oOH1d+iKKkxRy +7ynFp5HlhLueECd8wPTjHRo8idTNyKnNpzsL6rkPjx90cuBlLMna1fBzIN8BPpVK +4x3dNktRiDUU/uIZLtvb6w41+mD6gIFalds1P4kG/nYC8GWSe6ZCp2vqJVIGr7/q +wx38q6owzwPect7+ENEES2QcnHK/PcR/5uCOqrX1ZhVEtduV8n7EPMD6Onp8c9H/ +JxMoV9TT4UERbbXYxKMp0vGxR5q0a29yajKN0ub0Qq/LI+uISFgnYfbqxMWr0i7t +tWswUMmvxQ4gOXtgnffzHOrLucr+k0jkx6dU6Yn/TAokF1YsMoyi9LgEfkz3XRwk +26Eaf7+3mFJdBneHetld4D0pO8bwUuqi4zhYTqei7FeKiMPeYNLwaR9FHwIDAQAB +o0UwQzAOBgNVHQ8BAf8EBAMCAgQwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E +FgQUAij2DW/P4hUAsOzil/bOvAcSJfQwDQYJKoZIhvcNAQELBQADggGBAJb9jRZi +uiYmeeMZK/4P2AM+nvBEAuQMtPPizkt+l9i4A4HB/xFAwbPyF5rtK39SRyvRaEyp +IuJ3y6wGEhB3jauhU2NtY8Q9YiYlwOHTFPkTIGW4XdcRLB/7CVGEZrhEDAthIPxn +KSIircf5rTz2+SjtlIfFamSyyPmf+qpydOZ4PEKTPQyiwdKf8gy1Dyr3Ci7cU5Ze +Pgt0dlK2h7UrLcr60PHM5PbewEl2Llg0WCtApikd0rwL+CseEiyNkIgdGW/4HADo +S7fnmu4D7Tm7aSgmCF+8dGQIYhGlYXcDhDvJyoP1eZulVUYvLIGXoSiBUkqvLm8S +INlsFNxl4RZyChDSLunVhl7oDfFEJ2YNGGwK9qnkxCHSnz7SIi/VE7zAc4UunSn6 +bwSF9tA77Nh96zAE06UNGx78369hrOn16oAKBBeFKoWnmLhFIBoKgSY2l6fDjyGm +yHdDhcU60u7sD4vme3KBgraGk6wQMYVK9rOCfx8fqM7Z2mbp1MQa/ps1og== +-----END CERTIFICATE----- diff --git a/traefik/docker-compose.yaml b/traefik/docker-compose.yaml new file mode 100644 index 0000000..ec37e9e --- /dev/null +++ b/traefik/docker-compose.yaml @@ -0,0 +1,127 @@ +# =============================================================== +# Traefik Reverse Proxy Docker Compose Configuration +# =============================================================== +# 服務描述: Traefik 反向代理與負載平衡器 +# 建立日期: 2025-10-23 +# 更新日期: 2025-10-23 +# 版本: latest +# 網路連接埠: 80 (HTTP), 443 (HTTPS) +# 管理介面: traefik.jsc.idv.me +# =============================================================== + +services: + # --- Traefik 反向代理主服務 --- + server: + # === 容器基本設定 === + build: . + image: traefik:latest + container_name: traefik_server + + # === 網路連接埠對應 === + ports: + - "80:80" # HTTP 連接埠 + - "443:443" # HTTPS 連接埠 + + # === Traefik 標籤設定 === + labels: + # --- 基本設定 --- + - "traefik.enable=true" # 啟用 Traefik 路由 + - "traefik.docker.network=traefik_vlan" # 指定網路 + + # --- HTTP 壓縮中介軟體 --- + - "traefik.http.middlewares.gzip.compress=true" + + # --- Basic Auth 中介軟體 (共用) --- + - "traefik.http.middlewares.auth.basicauth.users=jiantw83:$$apr1$$u.VU3c6O$$AfAxvklBJ4lelZw07o2g20" + + # --- HTTP 重導向中介軟體 --- + - "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.https-redirect.redirectscheme.permanent=true" + + # --- Traefik 儀表板 HTTP 路由 --- + - "traefik.http.routers.traefik-dashboard.entrypoints=http" + - "traefik.http.routers.traefik-dashboard.rule=Host(`traefik.jsc.idv.me`)" + - "traefik.http.routers.traefik-dashboard.middlewares=https-redirect@docker" + + # --- Traefik 儀表板 HTTPS 路由 --- + - "traefik.http.routers.traefik-dashboard-tls.entrypoints=https" + - "traefik.http.routers.traefik-dashboard-tls.rule=Host(`traefik.jsc.idv.me`)" + - "traefik.http.routers.traefik-dashboard-tls.middlewares=gzip@docker" + - "traefik.http.routers.traefik-dashboard-tls.service=dashboard@internal" + - "traefik.http.routers.traefik-dashboard-tls.tls=true" + + # --- Traefik API HTTP 路由 --- + - "traefik.http.routers.traefik-dashboard-api.entrypoints=http" + - "traefik.http.routers.traefik-dashboard-api.rule=Host(`traefik.jsc.idv.me`)" + - "traefik.http.routers.traefik-dashboard-api.middlewares=https-redirect@docker" + + # --- Traefik API HTTPS 路由 --- + - "traefik.http.routers.traefik-dashboard-api-tls.entrypoints=https" + - "traefik.http.routers.traefik-dashboard-api-tls.rule=Host(`traefik.jsc.idv.me`) && PathPrefix(`/api`)" + - "traefik.http.routers.traefik-dashboard-api-tls.middlewares=gzip@docker" + - "traefik.http.routers.traefik-dashboard-api-tls.service=api@internal" + - "traefik.http.routers.traefik-dashboard-api-tls.tls=true" + + # === 環境變數設定 === + environment: + TZ: "Asia/Taipei" # 時區設定 (台北時間 UTC+8) + + # === 資料持久化 === + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro # Docker Socket (唯讀) + + # === 健康檢查 === + healthcheck: + test: [ "CMD-SHELL", "wget -q --spider --proxy off traefik_server:8080/ping || exit 1" ] + interval: 3s # 檢查間隔 + retries: 10 # 重試次數 + + # === 日誌管理 === + logging: + driver: "json-file" # 使用 JSON 檔案記錄日誌 + options: + max-size: "1m" # 單一日誌檔案最大 1MB + + # === 網路設定 === + networks: + - vlan # 使用 traefik_vlan 網路 + + # === Traefik 啟動參數 === + command: + # --- API 與儀表板設定 --- + - "--api=true" # 啟用 API + - "--api.dashboard=true" # 啟用儀表板 + - "--ping=true" # 啟用 ping 端點 + - "--accesslog=true" # 啟用存取日誌 + - "--tracing=true" # 啟用追蹤 + + # --- 入口點設定 --- + - "--entrypoints.http.address=:80" # HTTP 入口點 + - "--entrypoints.https.address=:443" # HTTPS 入口點 + + # --- Docker 提供者設定 --- + - "--providers.docker=true" # 啟用 Docker 提供者 + - "--providers.docker.endpoint=unix:///var/run/docker.sock" + - "--providers.file.directory=/etc/traefik/config" + - "--providers.docker.exposedbydefault=false" # 只路由有 traefik.enable=true 的服務 + + # --- 全域設定 --- + - "--global.sendanonymoususage=false" # 停用匿名使用資料收集 + - "--global.checknewversion=false" # 停用版本檢查 + + # --- Let's Encrypt 憑證設定 --- + - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true" + - "--certificatesresolvers.letsencrypt.acme.email=jiantw83@yahoo.com" + - "--certificatesresolvers.letsencrypt.acme.storage=/etc/traefik/config/acme.json" + + # --- SSL 設定 --- + - "--serverstransport.insecureskipverify=true" # 跳過 SSL 驗證 + + # === 重新啟動策略 === + restart: always # 容器異常退出時自動重啟 + +# =============================================================== +# Docker Networks 定義 +# =============================================================== +networks: + vlan: # Traefik 專用網路 \ No newline at end of file diff --git a/traefik/jsc.idv.me.pfx b/traefik/jsc.idv.me.pfx new file mode 100644 index 0000000..51b2073 Binary files /dev/null and b/traefik/jsc.idv.me.pfx differ diff --git a/traefik/mkcert b/traefik/mkcert new file mode 100644 index 0000000..a8a7e8b Binary files /dev/null and b/traefik/mkcert differ diff --git a/traefik/mkcert.exe b/traefik/mkcert.exe new file mode 100644 index 0000000..c9cde49 Binary files /dev/null and b/traefik/mkcert.exe differ