180 lines
5.4 KiB
YAML
180 lines
5.4 KiB
YAML
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 |