Add LLM compose stack for phy-srv-gpu01 (not deployed yet)
Follows the homelab pattern: ironicbadger.docker_compose_generator v2 renders services/<host>/NN-<stack>/compose.yml templates into ~/docker/compose.yaml on the host. - 01-vllm: chat model, fixed --gpu-memory-utilization - 02-embeddings: second vLLM instance (--task embed) rather than a separate toolchain, so SM120 support only has to be solved once - 03-openwebui: Open WebUI + pgvector (not chroma — corpus size) - 99-network: shared bridge; leading comment keeps networks: top-level - pin docker_compose_generator to 2.0.1 — galaxy tags mix v1/v2 formats - group_vars: stack config incl. LDAP placeholders still to be filled The role only writes the compose file; starting the stack stays manual. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,2 +1,41 @@
|
|||||||
---
|
---
|
||||||
|
# overrides of group_vars/all.yml
|
||||||
|
|
||||||
|
hostname: phy-srv-gpu01
|
||||||
|
|
||||||
|
# geerlingguy.docker
|
||||||
|
docker_users:
|
||||||
|
- "{{ main_username }}"
|
||||||
|
|
||||||
|
# ironicbadger.docker_compose_generator
|
||||||
|
# services/<docker_compose_hostname>/NN-<stack>/compose.yml next to run.yml
|
||||||
|
appdata_path: "/home/{{ main_username }}/appdata"
|
||||||
|
docker_compose_generator_output_path: "/home/{{ main_username }}/docker/"
|
||||||
|
docker_compose_hostname: phy-srv-gpu01
|
||||||
|
docker_compose_generator_uid: "{{ main_uid }}"
|
||||||
|
docker_compose_generator_gid: "{{ main_gid }}"
|
||||||
|
|
||||||
|
# --- LLM stack -------------------------------------------------------------
|
||||||
|
llm_dns_name: chat.phytron.local
|
||||||
|
|
||||||
|
# ⚠️ TODO: pin to a build verified on SM120 (Blackwell) before the first deploy
|
||||||
|
vllm_image: vllm/vllm-openai:latest
|
||||||
|
vllm_model: Qwen/Qwen3-32B-FP8
|
||||||
|
vllm_served_model_name: qwen3-32b
|
||||||
|
vllm_gpu_memory_utilization: "0.80"
|
||||||
|
vllm_max_model_len: "32768"
|
||||||
|
|
||||||
|
embedding_model: BAAI/bge-m3
|
||||||
|
embedding_model_name: bge-m3
|
||||||
|
embeddings_gpu_memory_utilization: "0.10"
|
||||||
|
|
||||||
|
openwebui_image: ghcr.io/open-webui/open-webui:main
|
||||||
|
pgvector_image: pgvector/pgvector:pg16
|
||||||
|
|
||||||
|
# --- AD/LDAP ---------------------------------------------------------------
|
||||||
|
# ⚠️ TODO: real bind DN / base DN from the customer; group llm_users is agreed
|
||||||
|
ldap_server_host: dc.phytron.local
|
||||||
|
ldap_server_port: "389"
|
||||||
|
ldap_bind_dn: "CN=svc-llm,OU=Service,DC=phytron,DC=local"
|
||||||
|
ldap_search_base: "DC=phytron,DC=local"
|
||||||
|
ldap_search_filter: "(&(objectClass=user)(memberOf=CN=llm_users,OU=Groups,DC=phytron,DC=local))"
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
---
|
---
|
||||||
|
# docker_compose_generator MUST stay pinned — its galaxy tags mix formats
|
||||||
|
# (1.0.x uses a `containers:` data structure, 2.x uses native compose files)
|
||||||
|
# and an unpinned install can silently change the expected layout.
|
||||||
roles:
|
roles:
|
||||||
#- name: geerlingguy.pip
|
#- name: geerlingguy.pip
|
||||||
- name: geerlingguy.docker
|
- name: geerlingguy.docker
|
||||||
@@ -6,3 +9,4 @@ roles:
|
|||||||
- name: geerlingguy.security
|
- name: geerlingguy.security
|
||||||
- name: geerlingguy.ntp
|
- name: geerlingguy.ntp
|
||||||
- name: ironicbadger.docker_compose_generator
|
- name: ironicbadger.docker_compose_generator
|
||||||
|
version: 2.0.1
|
||||||
|
|||||||
@@ -88,3 +88,8 @@
|
|||||||
tags: docker
|
tags: docker
|
||||||
- role: nvidia_gpu
|
- role: nvidia_gpu
|
||||||
tags: gpu
|
tags: gpu
|
||||||
|
# renders services/phy-srv-gpu01/*/compose.yml into ~/docker/compose.yaml.
|
||||||
|
# It only WRITES the file — starting the stack stays a deliberate manual
|
||||||
|
# step (see ansible/services/phy-srv-gpu01/README.md).
|
||||||
|
- role: ironicbadger.docker_compose_generator
|
||||||
|
tags: compose
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
services:
|
||||||
|
vllm:
|
||||||
|
image: "{{ vllm_image }}"
|
||||||
|
container_name: vllm
|
||||||
|
networks:
|
||||||
|
- llmnet
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
volumes:
|
||||||
|
# model cache on local disk — tens of GB per model
|
||||||
|
- "{{ appdata_path }}/models/huggingface:/root/.cache/huggingface"
|
||||||
|
environment:
|
||||||
|
- NVIDIA_VISIBLE_DEVICES=all
|
||||||
|
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
||||||
|
- "HUGGING_FACE_HUB_TOKEN={{ hf_token | default('') }}"
|
||||||
|
command:
|
||||||
|
- --model
|
||||||
|
- "{{ vllm_model }}"
|
||||||
|
- --served-model-name
|
||||||
|
- "{{ vllm_served_model_name }}"
|
||||||
|
# fixed VRAM share so the embedding server keeps its slice (§0: "it just works")
|
||||||
|
- --gpu-memory-utilization
|
||||||
|
- "{{ vllm_gpu_memory_utilization }}"
|
||||||
|
- --max-model-len
|
||||||
|
- "{{ vllm_max_model_len }}"
|
||||||
|
# vLLM needs a large shared-memory segment; without this it dies on startup
|
||||||
|
ipc: host
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
reservations:
|
||||||
|
devices:
|
||||||
|
- driver: nvidia
|
||||||
|
count: 1
|
||||||
|
capabilities: [gpu]
|
||||||
|
runtime: nvidia
|
||||||
|
restart: unless-stopped
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
services:
|
||||||
|
# Embeddings run on a second vLLM instance rather than a separate toolchain
|
||||||
|
# (e.g. text-embeddings-inference): whatever vLLM build works on SM120 then
|
||||||
|
# covers embeddings too, instead of having to solve Blackwell support twice.
|
||||||
|
embeddings:
|
||||||
|
image: "{{ vllm_image }}"
|
||||||
|
container_name: embeddings
|
||||||
|
networks:
|
||||||
|
- llmnet
|
||||||
|
ports:
|
||||||
|
- "8001:8000"
|
||||||
|
volumes:
|
||||||
|
- "{{ appdata_path }}/models/huggingface:/root/.cache/huggingface"
|
||||||
|
environment:
|
||||||
|
- NVIDIA_VISIBLE_DEVICES=all
|
||||||
|
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
||||||
|
- "HUGGING_FACE_HUB_TOKEN={{ hf_token | default('') }}"
|
||||||
|
command:
|
||||||
|
- --model
|
||||||
|
- "{{ embedding_model }}"
|
||||||
|
- --served-model-name
|
||||||
|
- "{{ embedding_model_name }}"
|
||||||
|
- --task
|
||||||
|
- embed
|
||||||
|
# small fixed slice — the chat model gets the rest
|
||||||
|
- --gpu-memory-utilization
|
||||||
|
- "{{ embeddings_gpu_memory_utilization }}"
|
||||||
|
ipc: host
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
reservations:
|
||||||
|
devices:
|
||||||
|
- driver: nvidia
|
||||||
|
count: 1
|
||||||
|
capabilities: [gpu]
|
||||||
|
runtime: nvidia
|
||||||
|
restart: unless-stopped
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
services:
|
||||||
|
openwebui:
|
||||||
|
image: "{{ openwebui_image }}"
|
||||||
|
container_name: openwebui
|
||||||
|
networks:
|
||||||
|
- llmnet
|
||||||
|
ports:
|
||||||
|
# plain HTTP for now — no TLS yet (projektplan §2.2). Put a reverse proxy
|
||||||
|
# in front (new stack 04-proxy) once an internal CA certificate exists.
|
||||||
|
- "80:8080"
|
||||||
|
depends_on:
|
||||||
|
- vllm
|
||||||
|
- owui-db
|
||||||
|
volumes:
|
||||||
|
- "{{ appdata_path }}/apps/open-webui:/app/backend/data"
|
||||||
|
environment:
|
||||||
|
- "WEBUI_URL=http://{{ llm_dns_name }}"
|
||||||
|
- "WEBUI_SECRET_KEY={{ vault_owui_secret_key }}"
|
||||||
|
|
||||||
|
# --- inference: vLLM speaks the OpenAI API, Ollama stays off ---
|
||||||
|
- OPENAI_API_BASE_URL=http://vllm:8000/v1
|
||||||
|
- OPENAI_API_KEY=dummy
|
||||||
|
- ENABLE_OLLAMA_API=false
|
||||||
|
|
||||||
|
# --- vector store: pgvector rather than the default chroma, which does
|
||||||
|
# not scale to the corpus sizes discussed in §2.6 ---
|
||||||
|
- VECTOR_DB=pgvector
|
||||||
|
- "PGVECTOR_DB_URL=postgresql://openwebui:{{ vault_owui_db_password }}@owui-db:5432/openwebui"
|
||||||
|
|
||||||
|
# --- RAG embeddings from the second vLLM instance ---
|
||||||
|
- RAG_EMBEDDING_ENGINE=openai
|
||||||
|
- RAG_OPENAI_API_BASE_URL=http://embeddings:8000/v1
|
||||||
|
- RAG_OPENAI_API_KEY=dummy
|
||||||
|
- "RAG_EMBEDDING_MODEL={{ embedding_model_name }}"
|
||||||
|
|
||||||
|
# --- AD/LDAP login (group llm_users) ---
|
||||||
|
# NOTE: verify these variable names against the Open WebUI docs for the
|
||||||
|
# tag actually deployed — they have changed between releases.
|
||||||
|
- ENABLE_LDAP=true
|
||||||
|
- LDAP_SERVER_LABEL=Phytron AD
|
||||||
|
- "LDAP_SERVER_HOST={{ ldap_server_host }}"
|
||||||
|
- "LDAP_SERVER_PORT={{ ldap_server_port }}"
|
||||||
|
- "LDAP_APP_DN={{ ldap_bind_dn }}"
|
||||||
|
- "LDAP_APP_PASSWORD={{ vault_ldap_bind_password }}"
|
||||||
|
- "LDAP_SEARCH_BASE={{ ldap_search_base }}"
|
||||||
|
- "LDAP_SEARCH_FILTER={{ ldap_search_filter }}"
|
||||||
|
- LDAP_ATTRIBUTE_FOR_USERNAME=sAMAccountName
|
||||||
|
- LDAP_USE_TLS=false
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
owui-db:
|
||||||
|
image: "{{ pgvector_image }}"
|
||||||
|
container_name: owui-db
|
||||||
|
networks:
|
||||||
|
- llmnet
|
||||||
|
volumes:
|
||||||
|
- "{{ appdata_path }}/databases/openwebui-pgdata:/var/lib/postgresql/data"
|
||||||
|
environment:
|
||||||
|
- POSTGRES_DB=openwebui
|
||||||
|
- POSTGRES_USER=openwebui
|
||||||
|
- "POSTGRES_PASSWORD={{ vault_owui_db_password }}"
|
||||||
|
restart: unless-stopped
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
# network definition (leading comment required: the compose generator
|
||||||
|
# indents the first line of each fragment; networks: must stay top-level)
|
||||||
|
networks:
|
||||||
|
llmnet:
|
||||||
|
driver: bridge
|
||||||
|
driver_opts:
|
||||||
|
com.docker.network.bridge.name: br-llm
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
# Compose stacks for phy-srv-gpu01
|
||||||
|
|
||||||
|
Rendered by `ironicbadger.docker_compose_generator` (pinned to 2.0.1) into
|
||||||
|
`{{ docker_compose_generator_output_path }}/compose.yaml` on the host.
|
||||||
|
The fragments here are **Jinja2 templates**, not plain compose files — Ansible
|
||||||
|
variables are substituted at render time.
|
||||||
|
|
||||||
|
| Stack | Contains |
|
||||||
|
| --- | --- |
|
||||||
|
| `01-vllm` | vLLM, serves the chat model on port 8000 (OpenAI API) |
|
||||||
|
| `02-embeddings` | second vLLM instance, embedding model on port 8001 |
|
||||||
|
| `03-openwebui` | Open WebUI (port 80) + pgvector Postgres |
|
||||||
|
| `99-network` | the shared `llmnet` bridge — must sort last |
|
||||||
|
|
||||||
|
Ordering comes from the `NN-` prefix; `99-network` keeps `networks:` at the
|
||||||
|
bottom of the generated file. The leading comment in `99-network/compose.yml`
|
||||||
|
is load-bearing: the role indents only the first line of each fragment, and the
|
||||||
|
comment absorbs that indentation so `networks:` stays top-level.
|
||||||
|
|
||||||
|
## Deploy
|
||||||
|
|
||||||
|
```sh
|
||||||
|
just compose phy_srv_gpu01 # renders ~/docker/compose.yaml on the host
|
||||||
|
```
|
||||||
|
|
||||||
|
The role only **writes** the file. Bringing the stack up is deliberate:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
ssh sbxadmin@192.168.66.69 'cd ~/docker && docker compose up -d'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Before the first run
|
||||||
|
|
||||||
|
- Secrets must exist in `group_vars/secrets.yml` (`just vault edit`):
|
||||||
|
`vault_owui_secret_key`, `vault_owui_db_password`, `vault_ldap_bind_password`
|
||||||
|
- LDAP parameters in `group_vars/phy_srv_gpu01.yml` need the real bind DN and
|
||||||
|
base DN from the customer
|
||||||
|
- `vllm_image` must point at a build that works on SM120 (Blackwell) — verify
|
||||||
|
before deploying, the official image is not guaranteed to work
|
||||||
@@ -93,24 +93,33 @@ GPU-Server nötig). Zu erheben:
|
|||||||
Ergebnis bestimmt: Korpus-Umfang (→ §1-Trigger), OCR-Pipeline ja/nein,
|
Ergebnis bestimmt: Korpus-Umfang (→ §1-Trigger), OCR-Pipeline ja/nein,
|
||||||
Index-Größe (→ Storage-Check §2.3), Erst-Indexierungsdauer.
|
Index-Größe (→ Storage-Check §2.3), Erst-Indexierungsdauer.
|
||||||
|
|
||||||
**Ergebnis (Lauf 2026-07-14, Skript `scripts/share-analysis.ps1` auf `D:` des
|
**Ergebnis (Lauf 2026-09-03, Skript `scripts/share-analysis.ps1` auf `D:` des
|
||||||
Fileservers Z-FILESERVER):**
|
Fileservers Z-FILESERVER; Zahlen ggü. dem Erstlauf 2026-07-14 leicht gewachsen):**
|
||||||
|
|
||||||
| Kennzahl | Wert | Konsequenz |
|
| Kennzahl | Wert | Konsequenz |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| Gesamt | **3.322.175 Dateien, 2.224 GB** | Scan lief über `D:` gesamt, nicht je Share → Obergrenze, enthält evtl. nicht freigegebene Daten |
|
| Gesamt | **3.338.643 Dateien, 2.231 GB** | Scan lief über `D:` gesamt, nicht je Share → Obergrenze, enthält evtl. nicht freigegebene Daten |
|
||||||
| `office` (extrahierbar) | **1.258.642 Dateien, 587 GB** | **12× über der §1-Schwelle** → Eingrenzung zwingend (§2.6) |
|
| `office` (extrahierbar) | **1.271.467 Dateien, 591 GB** | **12× über der §1-Schwelle** → Eingrenzung zwingend (§2.6) |
|
||||||
| `other` (unklassifiziert) | 1.575.752 Dateien, 934 GB | größter Block, **noch unidentifiziert** → `D-file-types.csv` auswerten |
|
| `other` (unklassifiziert) | 1.576.747 Dateien, 919 GB | größter Block, **noch unidentifiziert** → `D-file-types.csv` auswerten |
|
||||||
| Bilder / CAD / Archive / Medien | 403k / 60k / 12,6k / 6,2k Dateien | nicht extrahierbar → Erwartungsmanagement |
|
| Bilder / CAD / Archive / Medien | 403k / 60k / 12,6k / 6,2k Dateien | nicht extrahierbar → Erwartungsmanagement |
|
||||||
| PDFs | **924.076**, davon ~**18 % ohne Textlayer** (Stichprobe 200) | ≈ **166.000 Scan-PDFs → OCR**; eigener Zeit-/GPU-Aufwand, konkurriert mit vLLM |
|
| PDFs | **935.186**, davon ~**22 % ohne Textlayer** (Stichprobe 200) | ≈ **200.000 Scan-PDFs → OCR**; eigener Zeit-/GPU-Aufwand, konkurriert mit vLLM |
|
||||||
| Änderungsrate | 94 % älter als 1 Jahr; nur ~158k in den letzten 365 Tagen | Sync-Frequenz unkritisch; **Alter ≠ Irrelevanz** (Datenblätter, Normen) → Filter primär ordner-/inhaltsbasiert, Aktualität nur sekundär |
|
| Änderungsrate | 94 % älter als 1 Jahr; nur ~158k in den letzten 365 Tagen | Sync-Frequenz unkritisch; **Alter ≠ Irrelevanz** (Datenblätter, Normen) → Filter primär ordner-/inhaltsbasiert, Aktualität nur sekundär |
|
||||||
| Duplikat-/Altversions-Muster | 33.179 Dateien | Filterregeln |
|
| Duplikat-/Altversions-Muster | 33.378 Dateien | Filterregeln |
|
||||||
| Pfade > 240 Zeichen | 25.169 | Extraktions-Toolchain gezielt testen |
|
| Pfade > 240 Zeichen | 25.866 | Extraktions-Toolchain gezielt testen |
|
||||||
| Nicht-ASCII-Dateinamen | 126.111 | UTF-8 durchgängig (CIFS-Mount-Optionen → Extraktion → Index) |
|
| Nicht-ASCII-Dateinamen | 126.899 | UTF-8 durchgängig (CIFS-Mount-Optionen → Extraktion → Index) |
|
||||||
|
|
||||||
**Noch auszuwerten** (CSVs liegen auf dem Fileserver, noch nicht gesichtet):
|
**Bug im Erstlauf:** Beim Lauf über `D:` wurden **keine CSVs geschrieben**
|
||||||
`D-toplevel-folders.csv` (Größe/Anzahl je Top-Level-Ordner — die Grundlage für
|
(`Export-Csv` scheiterte an `D:` im Dateinamen). Behoben am 2026-09-03; für die
|
||||||
die Include-/Exclude-Liste) und `D-file-types.csv` (Auflösung der `other`-Kategorie).
|
Ordner-Aufschlüsselung neu laufen lassen mit:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\share-analysis.ps1 -Paths "D:" -OutDir .\file-analysis -FolderDepth 2
|
||||||
|
```
|
||||||
|
|
||||||
|
`-FolderDepth 2` liefert Größe/Anzahl je `Abteilungen\<Share>` — genau die
|
||||||
|
Granularität der Freigaben (s. §2.7) und die Grundlage für die Include-/
|
||||||
|
Exclude-Liste. Ebenfalls auszuwerten: `D-file-types.csv` zur Auflösung der
|
||||||
|
`other`-Kategorie (1,58 Mio. Dateien, größter unidentifizierter Block).
|
||||||
|
|
||||||
### 2.2 Mit dem Kunden zu klären (Checkliste) — Stand 2026-09-03
|
### 2.2 Mit dem Kunden zu klären (Checkliste) — Stand 2026-09-03
|
||||||
|
|
||||||
@@ -206,6 +215,36 @@ lautete sinngemäß „unsere Dokumente auslesen". Realistisch ist „ein kurati
|
|||||||
Teil unserer Dokumente, dafür mit guten Antworten". Das früh sagen — nicht erst,
|
Teil unserer Dokumente, dafür mit guten Antworten". Das früh sagen — nicht erst,
|
||||||
wenn der Vollindex schlechte Treffer liefert.
|
wenn der Vollindex schlechte Treffer liefert.
|
||||||
|
|
||||||
|
### 2.7 Freigaben-Inventar (Stand 2026-09-03)
|
||||||
|
|
||||||
|
`scripts/list-shares.ps1` auf Z-FILESERVER: **30 Freigaben, alle unterhalb `D:`**,
|
||||||
|
kein DFS. Vorschlag als *Gesprächsgrundlage* — die Zuordnung der Kürzel muss der
|
||||||
|
Kunde bestätigen, ebenso die endgültige Auswahl:
|
||||||
|
|
||||||
|
| Freigabe | Pfad | Vorschlag | Begründung |
|
||||||
|
|---|---|---|---|
|
||||||
|
| QM | `D:\Abteilungen\QM` | **rein** | Qualitätsmanagement — Normen, Prüfvorschriften: Kern der Wissensbasis |
|
||||||
|
| Arbeitssicherheit | `D:\Arbeitssicherheit` | **rein** | Vorschriften, Betriebsanweisungen |
|
||||||
|
| Competence Center | `D:\Abteilungen\Competence Center` | **rein** | Name deutet auf kuratiertes Wissen |
|
||||||
|
| EDV | `D:\Abteilungen\EDV` | **rein** | IT-Doku |
|
||||||
|
| Produktion | `D:\Produktion` | **prüfen** | vermutlich groß; ggf. nur Unterordner mit Doku |
|
||||||
|
| Projekte | `D:\Projekte` | **prüfen** | vermutlich der größte Block; nur mit Unterordner-Filter sinnvoll |
|
||||||
|
| Lagerlogistik, Marketing, Kalkulationen, Controlling, Immobilie | div. | **prüfen** | fachlich abhängig, eher zweite Welle |
|
||||||
|
| AA, AZ, BU, EE, EF, EK, ME, MF, MM, PL, SG, VT | `D:\Abteilungen\*` | **klären** | Abteilungskürzel — Bedeutung und Inhalt vom Kunden bestätigen lassen |
|
||||||
|
| Zeichnungen | `D:\Abteilungen\Zeichnungen` | **raus** | CAD/Zeichnungen — nicht extrahierbar (s. `cad`/`image` in §2.1) |
|
||||||
|
| Datenbank | `D:\Datenbank` | **raus** | Datenbank-Dateien, kein Fließtext |
|
||||||
|
| Tempwork | `D:\Tempwork` | **raus** | temporär, per Definition kein Wissensbestand |
|
||||||
|
| Benutzer | `D:\Benutzer` | **raus** | persönliche Ablagen — Datenschutz, kein geteiltes Wissen |
|
||||||
|
| **Personal** | `D:\Abteilungen\Personal` | **raus** | **HR — explizit ausgeschlossen** (§0: „alle sehen alles" gilt nur ohne Personaldaten) |
|
||||||
|
| **GF** | `D:\Abteilungen\GF` | **raus** | Geschäftsführung — vertraulich |
|
||||||
|
| **BR** | `D:\Abteilungen\BR` | **raus (klären)** | falls Betriebsrat: besonders schutzwürdig, auf keinen Fall indizieren |
|
||||||
|
|
||||||
|
⚠️ **Wichtig:** Weil alle Nutzer alles sehen (§0), ist jede indizierte Freigabe für
|
||||||
|
alle 25 Nutzer lesbar — unabhängig von den NTFS-Rechten auf dem Fileserver. Die
|
||||||
|
Ausschlüsse oben sind deshalb keine Kosmetik, sondern die einzige Zugriffskontrolle.
|
||||||
|
`list-shares.ps1` gibt die NTFS-Gruppen je Freigabe mit aus: Alles, was heute nur
|
||||||
|
einem eingeschränkten Personenkreis offensteht, gehört **nicht** in den Index.
|
||||||
|
|
||||||
## 3. Phasen ab Server-Lieferung
|
## 3. Phasen ab Server-Lieferung
|
||||||
|
|
||||||
| Phase | Inhalt | Ergebnis/Abnahme |
|
| Phase | Inhalt | Ergebnis/Abnahme |
|
||||||
|
|||||||
Reference in New Issue
Block a user