自架Server

用 Docker 把開發要用到的服務都架在本機的紀錄,從版控、私有套件庫、CI,到一整套可觀測性堆疊的設定檔。

## ———-MSSQL———-

–不掛Volume

docker run --name sqlserver_novolume -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=<your-password>' -p 1433:1433  -d shilvain/linux_sqlserver:v1

–掛Volume(不設定root) is work (還原資料庫用)

docker run --name sqlserver -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=<your-password>' -p 1433:1433 -v C:\\Users\\User\\Docker\\MSSQL\\DATA:/var/opt/mssql/data -d shilvain/linux_sqlserver:v1

複製檔案

docker cp sqlserver:/var/opt/mssql/data/database.bak 'C:\\Users\\User\\Docker\\MSSQL\\database.bak'
docker cp sqlserver:/var/opt/mssql/data/database.bak C:\\Users\\User\\Docker\\MSSQL\\database.bak  docker cp 'C:\\Users\\User\\Docker\\MSSQL\\database.bak' sqlserver1:/var/opt/mssql/data/database.bak

———-Mongo DB———-

拉 mongodb image

docker pull mongo

建立mongodb container

docker run -d --name mongodb -p 27017:27017 -v C:\\Users\\User\\Docker\\MongoDB\\data:/data/db -e MONGO_INITDB_ROOT_USERNAME=sa -e MONGO_INITDB_ROOT_PASSWORD=1qaz@WSX3edc mongo

Git Server

docker run -d --name gitea -p 3000:3000 -p 222:22 -v C:\users\user01\data:/data -e GITEA__security__SECRET_KEY=ShilvainSecretKey123! gitea/gitea:latest

設定資料庫的時候順便設定管理員帳戶。

查看目前 repos:

docker exec -u git -it gitea gitea repo list --config /data/gitea/conf/app.ini

列出某 user:

docker exec -u git -it gitea gitea repo list --user admin --config /data/gitea/conf/app.ini

NuGet Server

docker run -d --name baget -p 5555:80 -e ApiKey=MySecretKey loicsharma/baget

docker-compose.yml(只啟 BaGet)

version: '3.8'

services:
  baget:
    image: loicsharma/baget:latest
    container_name: baget
    ports:
      - '5555:80'
    environment:
      # ===== API Key(NuGet push 用)=====
      ApiKey: MySecretKey

      # ===== 套件儲存 =====
      Storage__Type: FileSystem
      Storage__Path: /var/baget/packages

      # ===== 使用既有 MSSQL =====
      Database__Type: SqlServer
      Database__ConnectionString: >
        Server=192.168.1.10,1433;
        Database=BaGet;
        User Id=baget_user;
        Password=StrongPassword!;
        TrustServerCertificate=True;

    volumes:
      - ./baget-data:/var/baget
    restart: always

1️⃣ 註冊 NuGet Source(只做一次)

dotnet nuget add source http://localhost:5555/v3/index.json --name BaGetMSSQL --username any --password MySecretKey --store-password-in-clear-text

2️⃣ 建立 NuGet 套件

dotnet pack -c Release

產生:

bin/Release/Your.Package.1.0.0.nupkg

3️⃣ Push 套件(關鍵)

dotnet nuget push \
  bin/Release/*.nupkg \
  --source BaGetMSSQL \
  --api-key MySecretKey

成功訊息:

Your.Package.1.0.0.nupkg was pushed successfully.

🎉 套件已經存在你的 MSSQL + 檔案系統中

驗證下載

dotnet add package Your.Package --source BaGetMSSQL

或 NuGet.config:

<configuration>
  <packageSources>
    <add key='BaGetMSSQL'
         value='http://localhost:5555/v3/index.json' />
  </packageSources>
</configuration>

Jenkins

docker run -d --name jenkins -p 8080:8080 -p 50000:50000 -v jenkins_home:/var/jenkins_home jenkins/jenkins:lts
  • 8080 → Web UI
  • 50000 → Agent 通訊
  • jenkins_home → 所有設定、Job、Plugin 都在這
  • lts → 長期支援版(穩定)

OpenTelemetry

docker-compose.yml

version: '3.9'

services:
  # ======================
  # Grafana UI
  # ======================
  grafana:
    image: grafana/grafana:10.3.1
    container_name: grafana
    ports:
      - '3000:3000'
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana-data:/var/lib/grafana
    depends_on:
      - prometheus
      - tempo
      - loki

  # ======================
  # Prometheus (Metrics)
  # ======================
  prometheus:
    image: prom/prometheus:v2.49.1
    container_name: prometheus
    ports:
      - '9090:9090'
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'

  # ======================
  # Tempo (Traces)
  # ======================
  tempo:
    image: grafana/tempo:2.4.1
    user: '0:0'
    container_name: tempo
    ports:
      - '3200:3200'   # Tempo UI / Query
      #- '4317:4317'   # OTLP gRPC
      #- '4318:4318'   # OTLP HTTP
    volumes:
      - ./tempo.yml:/etc/tempo.yml
      - tempo-data:/tmp/tempo
    command: ['-config.file=/etc/tempo.yml']

  # ======================
  # Loki (Logs)
  # ======================
  loki:
    image: grafana/loki:2.9.4
    container_name: loki
    ports:
      - '3100:3100'
    volumes:
      - ./loki.yml:/etc/loki/loki.yml
    command: ['-config.file=/etc/loki/loki.yml']

  # ======================
  # OpenTelemetry Collector
  # ======================
  otel-collector:
    image: otel/opentelemetry-collector-contrib:0.95.0
    container_name: otel-collector
    ports:
      - '4317:4317' # OTLP gRPC
      - '4318:4318' # OTLP HTTP
      - '8889:8889'
    volumes:
      - ./otel-collector-config.yml:/etc/otelcol/config.yml
    command: ['--config=/etc/otelcol/config.yml']
    depends_on:
      - prometheus
      - tempo
      - loki

volumes:
  grafana-data:
  tempo-data:

otel-collector-config.yml

receivers:
  otlp:
    protocols:
      grpc:
      http:

processors:
  batch:
  memory_limiter:      # << 加在這裡
    limit_mib: 512     # 最大使用 512 MB
    spike_limit_mib: 256  # 突發量允許再增加 256 MB
    check_interval: 5s    # 每 5 秒檢查一次記憶體

exporters:
  # Metrics → Prometheus
  prometheus:
    endpoint: '0.0.0.0:8889'

  # Traces → Tempo
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true

  # Logs → Loki
  loki:
    endpoint: http://loki:3100/loki/api/v1/push

service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [prometheus]

    traces:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [otlp/tempo]

    logs:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [loki]

prometheus.yml

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'otel-collector'
    static_configs:
      - targets: ['otel-collector:8889']

tempo.yml

server:
  http_listen_port: 3200

distributor:
  receivers:
    otlp:
      protocols:
        grpc:
        http:

ingester:
  lifecycler:
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1

compactor:
  compaction:
    block_retention: 24h

storage:
  trace:
    backend: local
    local:
      path: /tmp/tempo
    wal:
      path: /tmp/tempo/wal

loki.yml

auth_enabled: false

server:
  http_listen_port: 3100

common:
  path_prefix: /tmp/loki
  replication_factor: 1
  storage:
    filesystem:
      chunks_directory: /tmp/loki/chunks
      rules_directory: /tmp/loki/rules
  ring:
    kvstore:
      store: inmemory

schema_config:
  configs:
    - from: 2024-01-01
      store: boltdb-shipper
      object_store: filesystem
      schema: v13
      index:
        prefix: index_
        period: 24h