Add FRP
This commit is contained in:
@@ -1,33 +0,0 @@
|
||||
---
|
||||
# 頁面設定
|
||||
pageInfo:
|
||||
title: My Dashboard
|
||||
description: Welcome to your new dashboard!
|
||||
navLinks:
|
||||
- title: GitHub
|
||||
path: https://github.com/Lissy93/dashy
|
||||
- title: Documentation
|
||||
path: https://dashy.to/docs
|
||||
|
||||
# 應用程式區塊
|
||||
sections:
|
||||
- name: Getting Started
|
||||
icon: fas fa-rocket
|
||||
items:
|
||||
- title: Dashy Documentation
|
||||
description: Everything you need to know
|
||||
icon: fas fa-book
|
||||
url: https://dashy.to/docs
|
||||
- title: Source Code
|
||||
description: View on GitHub
|
||||
icon: fab fa-github
|
||||
url: https://github.com/Lissy93/dashy
|
||||
|
||||
# 主題與樣式設定
|
||||
appConfig:
|
||||
theme: colorful
|
||||
layout: auto
|
||||
iconSize: medium
|
||||
language: en
|
||||
editingPassword: "your_secure_password"
|
||||
|
||||
153
karylab-entrance/bitnami-harbor.yml
Normal file
153
karylab-entrance/bitnami-harbor.yml
Normal file
@@ -0,0 +1,153 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
# 1. Harbor Core Service
|
||||
harbor-core:
|
||||
image: docker.io/bitnami/harbor-core:latest
|
||||
container_name: harbor-core
|
||||
restart: always
|
||||
environment:
|
||||
- BITNAMI_DEBUG=false
|
||||
- HARBOR_ADMIN_PASSWORD=${HARBOR_ADMIN_PASSWORD} # <--- 請修改管理員密碼
|
||||
# Harbor 核心服務的資料庫連線設定
|
||||
- HARBOR_DATABASE_HOST=harbor-db
|
||||
- HARBOR_DATABASE_PORT_NUMBER=5432
|
||||
- HARBOR_DATABASE_USER=bn_harbor
|
||||
- HARBOR_DATABASE_PASSWORD=${HARBOR_GENERAL_PASSWORD}
|
||||
- HARBOR_DATABASE_NAME=bitnami_harbor
|
||||
# Redis 連線設定
|
||||
- HARBOR_REDIS_HOST=harbor-redis
|
||||
- HARBOR_REDIS_PORT_NUMBER=6379
|
||||
- HARBOR_REDIS_PASSWORD=${HARBOR_GENERAL_PASSWORD}
|
||||
# 重要:如果有域名,請改成 https://你的域名 (NPM有處理,不加埠號);只是內網用,改成 http://你的IP:port
|
||||
- HARBOR_EXTERNAL_URL=http://192.168.10.100:7700
|
||||
- HARBOR_REGISTRY_URL=http://harbor-registry:5000
|
||||
# Notary 服務設定(如果不使用 Notary,可以忽略這些設定)
|
||||
- HARBOR_NOTARY_SERVER_HOSTNAME=harbor-notary-server
|
||||
- HARBOR_NOTARY_SIGNER_HOSTNAME=harbor-notary-signer
|
||||
depends_on:
|
||||
- harbor-db
|
||||
- harbor-redis
|
||||
- harbor-registry
|
||||
volumes:
|
||||
- /mnt/data/External/harbor/core:/data
|
||||
networks:
|
||||
- harbor-network
|
||||
|
||||
# 2. Harbor Portal Service
|
||||
harbor-portal:
|
||||
image: docker.io/bitnami/harbor-portal:latest
|
||||
container_name: harbor-portal
|
||||
restart: always
|
||||
ports:
|
||||
- "7700:8080" # HTTP 入口 (NPM 反代請指到這裡)
|
||||
- "7750:8443" # HTTPS 入口
|
||||
environment:
|
||||
- BITNAMI_DEBUG=false
|
||||
- HARBOR_PORTAL_API_URL=http://harbor-core:8080/api
|
||||
- NGINX_HTTP_PORT_NUMBER=8080
|
||||
- NGINX_HTTPS_PORT_NUMBER=8443
|
||||
networks:
|
||||
- harbor-network
|
||||
depends_on:
|
||||
- harbor-core
|
||||
|
||||
# 3. Harbor Job Service
|
||||
harbor-jobservice:
|
||||
image: docker.io/bitnami/harbor-jobservice:latest
|
||||
container_name: harbor-jobservice
|
||||
restart: always
|
||||
environment:
|
||||
- BITNAMI_DEBUG=false
|
||||
- HARBOR_JOBSERVICE_DATABASE_HOST=harbor-db
|
||||
- HARBOR_JOBSERVICE_DATABASE_USER=bn_harbor
|
||||
- HARBOR_JOBSERVICE_DATABASE_PASSWORD=${HARBOR_GENERAL_PASSWORD}
|
||||
- HARBOR_JOBSERVICE_DATABASE_NAME=bitnami_harbor
|
||||
- HARBOR_JOBSERVICE_REDIS_HOST=harbor-redis
|
||||
- HARBOR_JOBSERVICE_REDIS_PORT_NUMBER=6379
|
||||
- HARBOR_JOBSERVICE_REDIS_PASSWORD=${HARBOR_GENERAL_PASSWORD}
|
||||
- HARBOR_JOBSERVICE_CORE_URL=http://harbor-core:8080
|
||||
depends_on:
|
||||
- harbor-core
|
||||
- harbor-redis
|
||||
volumes:
|
||||
- harbor-jobservice:/var/log/jobs
|
||||
networks:
|
||||
- harbor-network
|
||||
|
||||
# 4. Harbor Registry Service (映像檔儲存)
|
||||
harbor-registry:
|
||||
image: docker.io/bitnami/harbor-registry:latest
|
||||
container_name: harbor-registry
|
||||
restart: always
|
||||
environment:
|
||||
- BITNAMI_DEBUG=false
|
||||
- REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY=/storage
|
||||
- REGISTRY_HTTP_ADDR=:5000
|
||||
- REGISTRY_REDIS_HOST=harbor-redis
|
||||
- REGISTRY_REDIS_PORT=6379
|
||||
- REGISTRY_REDIS_PASSWORD=${HARBOR_GENERAL_PASSWORD}
|
||||
- REGISTRY_AUTH_TOKEN_REALM=http://harbor-core:8080/service/token
|
||||
# 為了方便,這裡關閉了部分複雜的安全驗證,依賴 Harbor Core 控制
|
||||
volumes:
|
||||
- /mnt/data/External/harbor/registry:/storage
|
||||
networks:
|
||||
- harbor-network
|
||||
depends_on:
|
||||
- harbor-redis
|
||||
|
||||
# 5. Harbor Registry Controller
|
||||
harbor-registryctl:
|
||||
image: docker.io/bitnami/harbor-registryctl:latest
|
||||
container_name: harbor-registryctl
|
||||
restart: always
|
||||
environment:
|
||||
- BITNAMI_DEBUG=false
|
||||
- REGISTRYCTL_REGISTRY_HOST=harbor-registry
|
||||
- REGISTRYCTL_REGISTRY_PORT=5000
|
||||
- REGISTRYCTL_REDIS_HOST=harbor-redis
|
||||
- REGISTRYCTL_REDIS_PORT=6379
|
||||
- REGISTRYCTL_REDIS_PASSWORD=${HARBOR_GENERAL_PASSWORD}
|
||||
- REGISTRYCTL_CHECK_INTERVAL=30m
|
||||
depends_on:
|
||||
- harbor-registry
|
||||
- harbor-redis
|
||||
volumes:
|
||||
- /mnt/data/External/harbor/registry:/storage
|
||||
networks:
|
||||
- harbor-network
|
||||
|
||||
# 6. Harbor Database (PostgreSQL資料庫)
|
||||
harbor-db:
|
||||
image: docker.io/bitnami/postgresql:latest
|
||||
container_name: harbor-db
|
||||
restart: always
|
||||
environment:
|
||||
- POSTGRESQL_USERNAME=bn_harbor
|
||||
- POSTGRESQL_PASSWORD=${HARBOR_GENERAL_PASSWORD}
|
||||
- POSTGRESQL_DATABASE=bitnami_harbor
|
||||
volumes:
|
||||
- harbor-db:/bitnami/postgresql
|
||||
networks:
|
||||
- harbor-network
|
||||
|
||||
# 7. Redis Cache (快取)
|
||||
harbor-redis:
|
||||
image: docker.io/bitnami/redis:latest
|
||||
container_name: harbor-redis
|
||||
restart: always
|
||||
environment:
|
||||
- REDIS_PASSWORD=${HARBOR_GENERAL_PASSWORD}
|
||||
volumes:
|
||||
- harbor-redis:/bitnami/redis/data
|
||||
networks:
|
||||
- harbor-network
|
||||
|
||||
volumes:
|
||||
harbor-db:
|
||||
harbor-redis:
|
||||
harbor-jobservice:
|
||||
|
||||
networks:
|
||||
harbor-network:
|
||||
driver: bridge
|
||||
42
karylab-entrance/config/frpc.toml
Normal file
42
karylab-entrance/config/frpc.toml
Normal file
@@ -0,0 +1,42 @@
|
||||
# =====================================================
|
||||
# FRP Client (frpc) 設定
|
||||
# 部署位置:UCG 內網機器(與 npm container 同網段)
|
||||
# 對接目標:PVE VM 上的 frps(具備固定 IP)
|
||||
# =====================================================
|
||||
|
||||
serverAddr = "45.64.97.4" # PVE VM 固定 IP
|
||||
serverPort = 7000 # 與 frps 的 bindPort 對應
|
||||
|
||||
# TLS 加密控制通道(與 frps 的 transport.tls.force = true 對應)
|
||||
[transport]
|
||||
tls.enable = true
|
||||
|
||||
# 連線驗證(需與 frps 的 auth token 相同)
|
||||
[auth]
|
||||
method = "token"
|
||||
token = "your_strong_secret_token" # TODO: 改為強密碼,frps 端要一致
|
||||
|
||||
# -------------------------------------------------------
|
||||
# HTTP (Port 80) → NPM
|
||||
# -------------------------------------------------------
|
||||
[[proxies]]
|
||||
name = "npm-http"
|
||||
type = "tcp"
|
||||
localIP = "npm" # 同 frp_network 內直接用 container name
|
||||
localPort = 80
|
||||
remotePort = 80
|
||||
|
||||
# -------------------------------------------------------
|
||||
# HTTPS (Port 443) → NPM
|
||||
# -------------------------------------------------------
|
||||
[[proxies]]
|
||||
name = "npm-https"
|
||||
type = "tcp"
|
||||
localIP = "npm"
|
||||
localPort = 443
|
||||
remotePort = 443
|
||||
|
||||
# -------------------------------------------------------
|
||||
# NPM 管理後台 (Port 81) 僅供內網存取,不對外 tunnel
|
||||
# 請直接在內網透過 http://內網機器IP:81 登入
|
||||
# -------------------------------------------------------
|
||||
@@ -36,9 +36,10 @@ container:
|
||||
docker_host: "tcp://docker:2375"
|
||||
|
||||
privileged: true # DinD 需要 privileged 模式
|
||||
# 讓 job 容器能解析 "docker" hostname,指向 DinD daemon 所在的宿主機
|
||||
# host-gateway 會自動解析為容器的宿主機 IP(對 job 容器來說就是 DinD)
|
||||
options: "--add-host=docker:host-gateway"
|
||||
# 让 job 容器能解析 hostname
|
||||
# docker: DinD daemon (使用 gitea-net 中的固定 IP 172.24.0.11)
|
||||
# server: Gitea 服务器 (使用固定 IP 172.24.0.10)
|
||||
options: "--add-host=docker:172.24.0.11 --add-host=server:172.24.0.10"
|
||||
workdir_parent: /workspace
|
||||
# 允許掛載的路徑,設為無限制以免綁手綁腳
|
||||
valid_volumes:
|
||||
|
||||
122
karylab-entrance/exchange.md
Normal file
122
karylab-entrance/exchange.md
Normal file
@@ -0,0 +1,122 @@
|
||||
# 工程師交接
|
||||
|
||||
## 1. cloudflared -> vps tunnel(已完成)
|
||||
|
||||
### 實作結果:採用方案一(FRP)
|
||||
|
||||
#### 檔案清單
|
||||
|
||||
| 檔案 | 位置 | 說明 |
|
||||
|---|---|---|
|
||||
| `vpstunnel+npm.yml` | `karylab-entrance/` | 內網 compose stack(frpc + npm + filebrowser) |
|
||||
| `frpc.toml` | `karylab-entrance/config/` | frpc 設定,掛載至 frpc container |
|
||||
| `vps-tunnel.yml` | `karylab-vps/` | VPS compose stack(frps) |
|
||||
| `frps.toml` | `karylab-vps/config/` | frps 設定,掛載至 frps container |
|
||||
|
||||
#### 架構說明
|
||||
|
||||
```
|
||||
[外部訪客]
|
||||
│ TCP 80/443
|
||||
▼
|
||||
[PVE VM(固定 IP)]
|
||||
└─ frps container
|
||||
│ TLS 加密隧道(Port 7000)
|
||||
▼
|
||||
[UCG 內網]
|
||||
└─ frpc container ─→ npm container(Port 80/443)
|
||||
│
|
||||
▼
|
||||
NAS / 其他內網服務
|
||||
```
|
||||
|
||||
#### 安全設計
|
||||
|
||||
- **控制通道 TLS**:frps 強制 `transport.tls.force = true`,frpc 開啟 `tls.enable = true`,控制通道全程加密
|
||||
- **Token 驗證**:frpc 與 frps 使用 HMAC-SHA256 簽名的 token 驗證身份
|
||||
- **NPM 管理後台(Port 81)不對外 tunnel**:只能從內網直接存取 `http://內網機器IP:81`
|
||||
- **建議**:在 VPS 防火牆(UFW / iptables)限制 Port 7000 只允許內網出口 IP 連入
|
||||
|
||||
#### 部署注意事項
|
||||
|
||||
1. **VPS 防火牆**必須開放 inbound TCP Port **80、443、7000**,否則 frpc 會出現 `i/o timeout`
|
||||
2. `frpc.toml` 的 `serverAddr` 填入 VPS 固定 IP 或可解析的網域皆可
|
||||
3. `frpc.toml` 與 `frps.toml` 的 `token` 必須設定為**同一組強密碼**
|
||||
4. 設定檔路徑:
|
||||
- VPS:`/opt/frp/frps.toml`
|
||||
- 內網:`/opt/cloudflare/frp/frpc.toml`
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
### 目標:
|
||||
|
||||
原來是cloudflare tunnel對接npm 再讓npm去找相關的設備
|
||||
直接把tunnel換成其他容器 然後對接vps(pve上的vm)
|
||||
|
||||
### 方案說明:
|
||||
|
||||
部署在 PVE 上的那台「固定 IP VM」當作私有的 Cloudflare 節點(也就是您的自建 VPS),然後用特定的「隧道容器」來取代 cloudflared+npm.yml 中的 cloudflared,打通兩個隔離的網段。新的版本更新到 vpstunnel+npm.yml。
|
||||
|
||||
要達成這個目的,有兩種主流的開源工具/容器可以完美取代 Cloudflare Tunnel,以下為您分析兩種作法:
|
||||
|
||||
**方案一:使用 FRP (Fast Reverse Proxy) —— 最直接的 1:1 替換**
|
||||
FRP 的運作邏輯與 Cloudflare Tunnel 幾乎一模一樣,只是伺服器從 Cloudflare 變成了您的 PVE VM。
|
||||
|
||||
架構配置:
|
||||
```
|
||||
前端 (您的 PVE VM - 具備固定 IP):安裝並運行 frps (FRP Server) 容器。它負責監聽來自網際網路的請求(如 Port 80, 443, 25565)。
|
||||
|
||||
後端 (您的 UCG 網段內):部署一個 frpc (FRP Client) 容器。這個容器會主動向 frps 發起連線,建立一條加密隧道。
|
||||
|
||||
路由分發:frpc 收到流量後,將 HTTP/HTTPS 流量轉交給同在 UCG 網段內的 NPM (Nginx Proxy Manager),再由 NPM 去找 UCG 底下的 NAS 或其他設備。
|
||||
```
|
||||
優點:架構與 Cloudflare Tunnel 概念完全一致,完全不用開 Port,因為是 frpc 由內向外主動連線的。
|
||||
|
||||
缺點:設定檔是基於 ini/yaml,需要稍微學習一下語法。
|
||||
|
||||
參考資源:FRP 官方 GitHub 專案庫與文件
|
||||
|
||||
**方案二:使用 WireGuard 或 Tailscale —— 網路層的虛擬區網 (推薦)**
|
||||
與其只代理特定 Port,不如在 PVE VM 和 UCG 網段之間建立一個專屬的「虛擬私有區域網路 (VPN)」。
|
||||
|
||||
架構配置:
|
||||
```
|
||||
前端 (您的 PVE VM):安裝 NPM 以及 Tailscale (或 WireGuard) 容器。將 Zyxel 的 80/443 Port Forwarding 到這個 VM。
|
||||
|
||||
後端 (您的 UCG 網段內):只需要在負責提供服務的機器(或 NPM)上安裝 Tailscale,讓它們加入同一個虛擬網路。
|
||||
|
||||
路由分發:當外部訪客連線到您的固定 IP (PVE VM) 時,VM 上的 NPM 會解析網域,並透過 Tailscale 給的虛擬 IP(例如 100.x.x.x)將流量安全地轉發到 UCG 底下的設備。
|
||||
```
|
||||
優點:
|
||||
|
||||
極致的隔離:Tailscale / WireGuard 使用點對點加密,流量穿梭在 Zyxel 網段與 UCG 網段之間時是完全加密的。
|
||||
|
||||
管理方便:所有伺服器都在同一個虛擬網段內,互相溝通就像在同一個 Switch 下一樣簡單。
|
||||
|
||||
參考資源:Tailscale 官方網站、WireGuard 官方網站
|
||||
|
||||
**流量動線解析 (以方案二為例)**
|
||||
假設訪客要訪問您在 UCG 網段下的 Nextcloud:
|
||||
|
||||
外部訪客輸入 cloud.example.com。
|
||||
|
||||
DNS (Cloudflare 灰雲) 將網域解析到您的 中華電信固定 IP。
|
||||
|
||||
流量抵達 vps 側路由器,透過 Port Forwarding 送入 PVE VM (自建 VPS) 的 Port 443。
|
||||
|
||||
PVE VM 上的 NPM 接收到請求,查看設定規則,發現要把流量送給 Nextcloud。
|
||||
|
||||
流量進入 隧道容器 (WireGuard/Tailscale),被加密打包。
|
||||
|
||||
加密封包穿越實體網路,抵達 UCG 網段下的目標機器。
|
||||
|
||||
目標機器解密封包,交由 Nextcloud 容器 處理。
|
||||
|
||||
這樣做的好處?
|
||||
擺脫限制:完全沒有 Cloudflare 的 100MB 檔案大小限制,也沒有任何協議的限制(您可以傳輸 TCP, UDP, 甚至跑自訂協議)。
|
||||
|
||||
完美隔離:您的 UCG 路由器不需要開放任何對外 Port (Inbound 規則維持全擋),所有的外部威脅第一時間都是由 Zyxel 底下的 PVE VM 承受。就算 VM 被攻破,攻擊者也無法直接看見 UCG 底下的設備(除非他們破解了加密隧道)。
|
||||
|
||||
掌控權:資料不再經過第三方的邊緣節點解密(Cloudflare 橘雲會解密 HTTPS 流量),真正的端到端都在您自己的掌控之下。
|
||||
@@ -11,7 +11,8 @@ services:
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
- POSTGRES_DB=gitea
|
||||
networks:
|
||||
- gitea-net
|
||||
gitea-net:
|
||||
ipv4_address: 172.24.0.3
|
||||
volumes:
|
||||
- postgres_db:/var/lib/postgresql/data
|
||||
|
||||
@@ -31,11 +32,14 @@ services:
|
||||
- GITEA__database__PASSWD=${POSTGRES_PASSWORD}
|
||||
# 啟用 Actions (關鍵設定)
|
||||
- GITEA__actions__ENABLED=true
|
||||
# 開啟內建 Registry 功能
|
||||
- GITEA__packages__ENABLED=true
|
||||
# 允許發送 webhook 到內部 IP
|
||||
- GITEA__webhook__ALLOWED_HOST_LIST=*
|
||||
networks:
|
||||
- gitea-net
|
||||
- webproxy
|
||||
gitea-net:
|
||||
ipv4_address: 172.24.0.10
|
||||
webproxy: {}
|
||||
depends_on:
|
||||
- db
|
||||
ports:
|
||||
@@ -54,8 +58,19 @@ services:
|
||||
privileged: true # DinD 必須開啟此權限才能運作
|
||||
environment:
|
||||
- DOCKER_TLS_CERTDIR= # 設為空字串以關閉 TLS,簡化內部連線
|
||||
# 允許連回 Gitea 的 Registry (因為是 HTTP)
|
||||
# 設置 DNS 讓內部容器能解析 gitea-net 的 service name
|
||||
command:
|
||||
- "dockerd"
|
||||
- "--host=unix:///var/run/docker.sock"
|
||||
- "--host=tcp://0.0.0.0:2375"
|
||||
- "--insecure-registry=172.24.0.10:3000"
|
||||
- "--insecure-registry=server:3000"
|
||||
- "--dns=172.24.0.1"
|
||||
- "--dns=8.8.8.8"
|
||||
networks:
|
||||
- gitea-net
|
||||
gitea-net:
|
||||
ipv4_address: 172.24.0.11
|
||||
volumes:
|
||||
- gitea_docker_certs:/certs/client
|
||||
- gitea_docker_data:/var/lib/docker # 持久化,避免重啟後又要重新 pull image
|
||||
@@ -65,22 +80,21 @@ services:
|
||||
image: gitea/act_runner:latest
|
||||
container_name: gitea_runner
|
||||
restart: always
|
||||
networks:
|
||||
gitea-net:
|
||||
ipv4_address: 172.24.0.5
|
||||
volumes:
|
||||
- /mnt/data/External/gitea/runner_data:/data
|
||||
environment:
|
||||
- CONFIG_FILE=/data/config.yaml
|
||||
# 注意:Runner 需要註冊 Token,我們在啟動後手動輸入一次即可
|
||||
- GITEA_INSTANCE_URL=http://server:3000
|
||||
# 關鍵修改:告訴 Runner 不要找 Socket,而是用 TCP 連線到 docker 容器
|
||||
- DOCKER_HOST=tcp://docker:2375
|
||||
- GITEA_RUNNER_REGISTRATION_TOKEN=${REGISTRATION_TOKEN}
|
||||
depends_on:
|
||||
- server
|
||||
- docker
|
||||
networks:
|
||||
- gitea-net
|
||||
volumes:
|
||||
- /mnt/data/External/gitea/runner_data:/data
|
||||
|
||||
environment:
|
||||
- CONFIG_FILE=/data/config.yaml
|
||||
|
||||
# 注意:Runner 需要註冊 Token,我們在啟動後手動輸入一次即可
|
||||
- GITEA_INSTANCE_URL=http://server:3000
|
||||
|
||||
# 關鍵修改:告訴 Runner 不要找 Socket,而是用 TCP 連線到 docker 容器
|
||||
- DOCKER_HOST=tcp://docker:2375
|
||||
|
||||
volumes:
|
||||
postgres_db:
|
||||
@@ -90,6 +104,9 @@ volumes:
|
||||
networks:
|
||||
gitea-net:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 172.24.0.0/16
|
||||
# npm bridge
|
||||
webproxy:
|
||||
external: true
|
||||
103
karylab-entrance/others/docker-harbor.yml
Normal file
103
karylab-entrance/others/docker-harbor.yml
Normal file
@@ -0,0 +1,103 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# 1. Harbor 映像服務器 - 提供容器映像管理功能
|
||||
harbor:
|
||||
image: goharbor/harbor-core:v2.9.3
|
||||
container_name: harbor-core
|
||||
restart: always
|
||||
ports:
|
||||
- "5700:8080"
|
||||
environment:
|
||||
CORE_URL: http://harbor:8080
|
||||
DATABASE_TYPE: postgresql
|
||||
POSTGRES_HOST: harbor-db
|
||||
POSTGRES_PORT: 5432
|
||||
POSTGRES_USERNAME: ${POSTGRES_USERNAME}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: registry
|
||||
REGISTRY_URL: http://harbor-registry:5000
|
||||
REGISTRY_CONTROLLER_URL: http://harbor-registry:5000
|
||||
LOG_LEVEL: info
|
||||
PERMITTED_REGISTRY_TYPES: docker-registry
|
||||
QUOTA_PER_PROJECT_ENABLED: "true"
|
||||
READ_ONLY: "false"
|
||||
volumes:
|
||||
- harbor_core_data:/data
|
||||
networks:
|
||||
- harbor-network
|
||||
- webproxy
|
||||
depends_on:
|
||||
- harbor-db
|
||||
- harbor-registry
|
||||
|
||||
# 2. Harbor 資料庫 - 儲存 Harbor 的元數據
|
||||
harbor-db:
|
||||
image: postgres:14
|
||||
container_name: harbor-db
|
||||
restart: always
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
|
||||
POSTGRES_DB: registry
|
||||
volumes:
|
||||
- harbor_db_data:/var/lib/postgresql/data
|
||||
networks:
|
||||
- harbor-network
|
||||
|
||||
# 3. Harbor Registry - 儲存容器映像的註冊表
|
||||
harbor-registry:
|
||||
image: registry:2
|
||||
container_name: harbor-registry
|
||||
restart: always
|
||||
ports:
|
||||
- "5600:5000"
|
||||
environment:
|
||||
REGISTRY_HTTP_ADDR: 0.0.0.0:5000
|
||||
REGISTRY_HTTP_RELATIVEURLS: 'true'
|
||||
REGISTRY_STORAGE_DELETE_ENABLED: 'true'
|
||||
volumes:
|
||||
- /mnt/data/External/harbor/registry:/var/lib/registry
|
||||
networks:
|
||||
- harbor-network
|
||||
|
||||
# 4. BuildKit 編譯服務 - 用於高效構建容器映像
|
||||
buildkitd:
|
||||
image: moby/buildkit:latest
|
||||
container_name: buildkitd
|
||||
restart: always
|
||||
privileged: true
|
||||
ports:
|
||||
- "5500:1234"
|
||||
environment:
|
||||
BUILDKIT_HOST: tcp://0.0.0.0:1234
|
||||
volumes:
|
||||
- buildkit_data:/var/lib/buildkit
|
||||
networks:
|
||||
- harbor-network
|
||||
|
||||
# 5. BuildKit Web UI - 提供 BuildKit 的 Web 界面
|
||||
buildkit-ui:
|
||||
image: tonistiiii/buildkit-ui:latest
|
||||
container_name: buildkit-ui
|
||||
restart: always
|
||||
ports:
|
||||
- "5400:8080"
|
||||
environment:
|
||||
BUILDKIT_HOST: tcp://buildkitd:1234
|
||||
networks:
|
||||
- harbor-network
|
||||
- webproxy
|
||||
depends_on:
|
||||
- buildkitd
|
||||
|
||||
volumes:
|
||||
harbor_core_data:
|
||||
harbor_db_data:
|
||||
buildkit_data:
|
||||
buildkit_cache:
|
||||
|
||||
networks:
|
||||
harbor-network:
|
||||
driver: bridge
|
||||
webproxy:
|
||||
external: true
|
||||
@@ -112,10 +112,8 @@ services:
|
||||
DRONE_SERVER_HOST: dronedocker.karylab.com
|
||||
DRONE_SERVER_PROTO: https
|
||||
DRONE_RPC_SECRET: ${DRONE_RANDOM_SECRET}
|
||||
# Webhook 密鑰設定(必須和 Gitea Webhook 設定一致)
|
||||
DRONE_WEBHOOK_SECRET: a1212416fb0515155c2c88f00a7879ad
|
||||
# Gitea 配置 - 連接到本機 Gitea 服務
|
||||
DRONE_GITEA_SERVER: http://git.karylab.com
|
||||
DRONE_GITEA_SERVER: https://git.karylab.com
|
||||
DRONE_GITEA_CLIENT_ID: ${GITEA_DRONE_CLIENT_ID:-drone_client}
|
||||
DRONE_GITEA_CLIENT_SECRET: ${GITEA_DRONE_SECRET:-drone_secret}
|
||||
volumes:
|
||||
180
karylab-entrance/others/rundeck-registry.yml
Normal file
180
karylab-entrance/others/rundeck-registry.yml
Normal file
@@ -0,0 +1,180 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# 1. Docker 編譯伺服器 - Docker-in-Docker,隔離編譯環境
|
||||
build-server:
|
||||
image: docker:dind
|
||||
container_name: docker-build-server
|
||||
restart: always
|
||||
privileged: true # DinD 必要權限
|
||||
command:
|
||||
- dockerd
|
||||
- --host=unix:///var/run/docker.sock
|
||||
- --host=tcp://0.0.0.0:2375
|
||||
- --storage-driver=overlay2
|
||||
# 允許來自內部的 HTTP 推送 (關鍵)
|
||||
- --insecure-registry=registry:5000
|
||||
environment:
|
||||
DOCKER_TLS_CERTDIR: "" # 關閉 TLS 方便內部通訊
|
||||
volumes:
|
||||
- build-cache:/var/lib/docker
|
||||
networks:
|
||||
- rundeck-network
|
||||
healthcheck:
|
||||
test: ["CMD", "test", "-f", "/shared-bin/docker"]
|
||||
interval: 5s
|
||||
timeout: 2s
|
||||
retries: 3
|
||||
start_period: 15s
|
||||
|
||||
# 2. Docker Registry - 儲存編譯好的 Image
|
||||
registry:
|
||||
image: registry:2
|
||||
container_name: local-registry
|
||||
restart: always
|
||||
ports:
|
||||
- "5700:5000" # 外部 Portainer 拉取用 192.168.1.XX:5700
|
||||
environment:
|
||||
REGISTRY_HTTP_ADDR: 0.0.0.0:5000
|
||||
REGISTRY_STORAGE_DELETE_ENABLED: 'true'
|
||||
volumes:
|
||||
- /mnt/data/External/rundeck/registry_data:/var/lib/registry
|
||||
networks:
|
||||
- rundeck-network
|
||||
depends_on:
|
||||
build-server:
|
||||
condition: service_healthy
|
||||
|
||||
# 3. Registry Web UI - 可視化管理鏡像
|
||||
registry-ui:
|
||||
image: joxit/docker-registry-ui:latest
|
||||
container_name: docker-registry-ui
|
||||
restart: always
|
||||
ports:
|
||||
- "5600:80"
|
||||
environment:
|
||||
REGISTRY_TITLE: "Docker Registry"
|
||||
SINGLE_REGISTRY: 'true'
|
||||
REGISTRY_SECURED: 'false'
|
||||
DELETE_IMAGES: 'true'
|
||||
SHOW_CATALOG_NB_TAGS: 'true'
|
||||
NGINX_PROXY_PASS_URL: 'http://registry:5000'
|
||||
networks:
|
||||
- rundeck-network
|
||||
depends_on:
|
||||
- registry
|
||||
|
||||
# 4. Rundeck - 編譯任務編排(通過網路連接到 DinD,不掛載宿主 socket)
|
||||
rundeck:
|
||||
image: rundeck/rundeck:5.18.0
|
||||
container_name: rundeck-builder
|
||||
restart: always
|
||||
ports:
|
||||
- "5500:4440"
|
||||
volumes:
|
||||
- rundeck-data:/home/rundeck/server/data
|
||||
- docker-bin:/usr/local/bin/docker-share
|
||||
environment:
|
||||
# 請修改為你的外部 IP (讓瀏覽器能正確轉址)
|
||||
- RUNDECK_GRAILS_URL=http://192.168.10.100:5500
|
||||
- RUNDECK_SERVER_FORWARDED=true
|
||||
# DinD 連接參數 告訴 Rundeck 裡的 docker 指令去連線 build-server
|
||||
- DOCKER_HOST=tcp://build-server:2375
|
||||
- DOCKER_TLS_VERIFY=
|
||||
# 將掛載進來的 docker 資料夾加入 PATH,這樣就能直接打 docker 指令了
|
||||
- PATH=/usr/local/bin/docker-share:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
# 資料庫設定
|
||||
- RUNDECK_DATABASE_URL=jdbc:mysql://rundeck-db/rundeck?autoReconnect=true&useSSL=false
|
||||
- RUNDECK_DATABASE_USERNAME=rundeck
|
||||
- RUNDECK_DATABASE_PASSWORD=${ROOT_PASSWORD}
|
||||
- RUNDECK_DATABASE_DRIVER=org.mariadb.jdbc.Driver
|
||||
networks:
|
||||
- rundeck-network
|
||||
- webproxy
|
||||
depends_on:
|
||||
- build-server
|
||||
- rundeck-db
|
||||
|
||||
# 5. Rundeck 資料庫 - 儲存 Rundeck 的任務和設定
|
||||
rundeck-db:
|
||||
image: mariadb:10
|
||||
container_name: rundeck-db
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${ROOT_PASSWORD}
|
||||
MYSQL_DATABASE: rundeck
|
||||
MYSQL_USER: rundeck
|
||||
MYSQL_PASSWORD: ${ROOT_PASSWORD}
|
||||
volumes:
|
||||
- rundeck-db-data:/var/lib/mysql
|
||||
networks:
|
||||
- rundeck-network
|
||||
|
||||
# 6. 編譯伺服器垃圾回收 - 通過 TCP 清理編譯緩存和未使用的層
|
||||
build-server-gc:
|
||||
image: docker:cli
|
||||
container_name: docker-build-gc
|
||||
restart: always
|
||||
environment:
|
||||
DOCKER_HOST: tcp://build-server:2375
|
||||
networks:
|
||||
- rundeck-network
|
||||
entrypoint: |
|
||||
sh -c 'while true; do
|
||||
echo "[$(date)] 清理構建緩存..." >> /proc/1/fd/1
|
||||
docker builder prune -af || true
|
||||
echo "[$(date)] 清理懸空鏡像..." >> /proc/1/fd/1
|
||||
docker image prune -af || true
|
||||
echo "[$(date)] 清理完成,24小時後再執行..." >> /proc/1/fd/1
|
||||
sleep 86400
|
||||
done'
|
||||
depends_on:
|
||||
build-server:
|
||||
condition: service_healthy
|
||||
|
||||
# 7. Registry 垃圾回收 - 定期清理未被引用的 blobs
|
||||
registry-gc:
|
||||
image: registry:2
|
||||
container_name: docker-registry-gc
|
||||
restart: always
|
||||
environment:
|
||||
REGISTRY_HTTP_ADDR: 0.0.0.0:5000
|
||||
REGISTRY_STORAGE_DELETE_ENABLED: 'true'
|
||||
volumes:
|
||||
- /mnt/data/External/rundeck/registry_data:/var/lib/registry
|
||||
- registry_gc_logs:/tmp
|
||||
networks:
|
||||
- rundeck-network
|
||||
entrypoint: |
|
||||
sh -c 'while true; do
|
||||
echo "[$(date)] 執行 Registry 垃圾回收..." >> /tmp/gc.log
|
||||
registry garbage-collect /etc/docker/registry/config.yml >> /tmp/gc.log 2>&1
|
||||
echo "[$(date)] Registry 垃圾回收完成,24小時後再執行..." >> /tmp/gc.log
|
||||
sleep 86400
|
||||
done'
|
||||
depends_on:
|
||||
- registry
|
||||
|
||||
# 7. Docker CLI Loader (Portainer 專用技巧)
|
||||
# 因為不能用 Dockerfile,開一個容器把 docker 執行檔複製出來
|
||||
docker-cli-loader:
|
||||
image: docker:cli
|
||||
container_name: tool-docker-loader
|
||||
# 執行完複製就自動退出,不需要 restart
|
||||
restart: "no"
|
||||
command: sh -c "cp /usr/local/bin/docker /shared-bin/docker && chmod +x /shared-bin/docker"
|
||||
volumes:
|
||||
- docker-bin:/shared-bin
|
||||
|
||||
volumes:
|
||||
build-cache:
|
||||
docker-bin:
|
||||
rundeck-data:
|
||||
rundeck-db-data:
|
||||
registry_gc_logs:
|
||||
|
||||
networks:
|
||||
rundeck-network:
|
||||
driver: bridge
|
||||
webproxy:
|
||||
external: true
|
||||
43
karylab-entrance/vpstunnel+npm.yml
Normal file
43
karylab-entrance/vpstunnel+npm.yml
Normal file
@@ -0,0 +1,43 @@
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
frpc:
|
||||
image: snowdreamtech/frpc:latest
|
||||
container_name: frpc
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- frp_network
|
||||
volumes:
|
||||
- /opt/cloudflare/frp/frpc.toml:/etc/frp/frpc.toml:ro
|
||||
|
||||
npm:
|
||||
image: jc21/nginx-proxy-manager:latest
|
||||
container_name: npm
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "81:81"
|
||||
- "443:443"
|
||||
networks:
|
||||
- frp_network
|
||||
- webproxy
|
||||
volumes:
|
||||
- /opt/cloudflare/npm/data:/data
|
||||
- /opt/cloudflare/npm/letsencrypt:/etc/letsencrypt
|
||||
|
||||
filebrowser:
|
||||
image: filebrowser/filebrowser:latest
|
||||
container_name: filebrowser
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "18080:80"
|
||||
networks:
|
||||
- frp_network
|
||||
volumes:
|
||||
- /opt/cloudflare/files:/srv
|
||||
|
||||
networks:
|
||||
frp_network:
|
||||
driver: bridge
|
||||
webproxy:
|
||||
external: true
|
||||
23
karylab-vps/config/frps.toml
Normal file
23
karylab-vps/config/frps.toml
Normal file
@@ -0,0 +1,23 @@
|
||||
# =====================================================
|
||||
# FRP Server (frps) 設定
|
||||
# 部署位置:PVE VM(具備固定 IP)
|
||||
# =====================================================
|
||||
|
||||
bindPort = 7000 # 與 frpc 的 serverPort 對應
|
||||
|
||||
# TLS 加密控制通道(強制要求 frpc 必須使用 TLS 連線)
|
||||
[transport.tls]
|
||||
force = true # 拒絕所有非 TLS 的 frpc 連線
|
||||
|
||||
# 連線驗證(需與 frpc 的 token 相同)
|
||||
[auth]
|
||||
method = "token"
|
||||
token = "your_strong_secret_token" # TODO: 改為強密碼,需與 frpc.toml 一致
|
||||
|
||||
# Dashboard(可選)
|
||||
# 若要啟用 frps web 管理介面,取消下方註解
|
||||
# [webServer]
|
||||
# addr = "0.0.0.0"
|
||||
# port = 7500
|
||||
# user = "admin"
|
||||
# password = "your_dashboard_password"
|
||||
17
karylab-vps/vps-tunnel.yml
Normal file
17
karylab-vps/vps-tunnel.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
version: "3.9"
|
||||
|
||||
services:
|
||||
frps:
|
||||
image: snowdreamtech/frps:latest
|
||||
container_name: frps
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80" # HTTP → 轉給內網 NPM
|
||||
- "443:443" # HTTPS → 轉給內網 NPM
|
||||
- "7000:7000" # frpc 控制通道(建議用防火牆限制來源 IP)
|
||||
volumes:
|
||||
- /opt/frp/frps.toml:/etc/frp/frps.toml:ro
|
||||
|
||||
networks:
|
||||
default:
|
||||
driver: bridge
|
||||
Reference in New Issue
Block a user