Privat fjärrdistribution
Det här mönstret kör Libre WebUI, Ollama och Cloudflare Tunnel på en Docker-värd utan att publicera programmets eller Ollamas portar. Cloudflare Access är den yttre identitetsgränsen och Libre WebUI-autentisering den inre. Work och Watchtower är separata, frivilliga funktioner med root-likvärdig behörighet.
Mallen använder solo-topologin med en replik: SQLite, lokala krypterade blobbar,
inbäddade vektorer, lokal samordning och en inbäddad jobbworker delar programmets
datavolym. Gör inte om den till en teaminstallation genom att ändra backendväljare i
.env. Teaminstallationer måste använda arkivets docker-compose.team.yml (och
docker-compose.team.work.yml när Work är aktiverat), som etablerar PostgreSQL/PGVector,
versionshanterad S3-lagring, Redis, en extern worker och gatewayen som en samordnad topologi.
Använd deploy/private/docker-compose.yml
som utgångspunkt. Den använder avbildningen main som standard:
LIBRE_WEBUI_IMAGE=ghcr.io/libre-webui/libre-webui:main
Taggen dev passar en utvecklingsinstans som uttryckligen valts, inte klientens standard.
Säkerhetsmodell
- Cloudflare Access skyddar hela värdnamnet, inklusive
/api/*och WebSocket-uppgraderingar. Lägg inte till publika undantagssökvägar. - Libre WebUI kräver ett aktuellt konto för programmets API:er. Modelllivscykel och Work-åtgärder kräver att den aktuella databasrollen är administratör.
- Programmet, Ollama, SearXNG och cloudflared använder endast ett privat Compose-nätverk. Värden publicerar inga programportar.
- Den medföljande SearXNG-tjänsten driver valfri webbsökning. Den är
endast intern och inaktiv tills en administratör aktiverar sökning i Settings > Search.
Ange
SEARXNG_SECRETi.envinnan stacken startas. - Appen körs utan root med skrivskyddat rotfilsystem, utan Linux-funktioner, med no-new-privileges och gränser för CPU, minne och PID.
- Work är inaktiverat om ingen av dess åsidosättningar inkluderas. När det aktiveras får containrarna ett eget skrivskyddat rotfilsystem, borttagna funktioner, resursgränser, arbetsytevolym och en nätverkspolicy som nekar som standard.
Basstacken monterar ingen Docker-socket. Om Work aktiveras med
docker-compose.work-proxy.yml förblir det så: en socketproxy på ett internt nätverk
håller socketen och vidarebefordrar endast de API-delar som Work använder (containrar,
avbildningar, volymer, nätverk, exec och info). Swarm-, secrets-, build- och
systemslutpunkter nekas i proxyn, och programmet behöver varken socketmontering eller
medlemskap i socketgruppen. Proxyn minskar Docker API-ytan, inte verkansradien för det
som vidarebefordras — den som kan skapa containrar kan fortfarande bind-montera
värdsökvägar. Behandla den som ett verkligt härdningslager, inte fleranvändarisolering.
Alternativen med rå socket förblir den största tillitsgränsen: åsidosättningarna
docker-compose.work.yml och Watchtower ger en container en process som kan göra
godtyckliga Docker API-anrop och styra värden. En skrivskyddad socketmontering gör inte
Docker API-åtkomst skrivskyddad. Den integrerade säkerhetskopieringshjälpen vägrar att
ärva en rå Docker-socket. Migrera Work till den filtrerade proxyn innan schemalagda
integrerade säkerhetskopior används.
Grundkonfiguration
- Skapa en operatör utan root med sudo och verifiera nyckelbaserad SSH-inloggning innan root-SSH inaktiveras.
- Kopiera
deploy/private/.env.exampletill/opt/libre-webui/.env, ställ in läget0600, generera unika hemligheter och dimensioneraBLOB_QUOTA_BYTES_PER_USERför värden.BLOB_QUOTA_RESERVATION_TTL_MSlåter övergivna uppladdningsreservationer löpa ut; standardvärdet är en timme. - Om Work ska aktiveras ställer du
DOCKER_GIDtill den numeriska grupp som äger/var/run/docker.sock. - Lagra Cloudflare-tunneltoken i
/opt/libre-webui/secrets/tunnel-tokenmed läget0640eller striktare. - Skapa ett självhostat Cloudflare Access-program för hela värdnamnet, använd en
24-timmarssession och tillåt endast avsedda identiteter. Aktivera Protect with Access
på tunnelrutten. Om övervakning kräver en publik hälsokontroll skapar du ett separat,
sökvägsavgränsat program eller policy endast för
/health/live. Lägg aldrig till en generell Bypass-policy i huvudprogrammet: matchande Bypass-policyer upphäver Allow-policyn. - Låt
ENABLE_SIGNUP=false. När Access-tillåtelselistan skyddar värdnamnet skapar du den första lokala administratören. En tom databas tillåter automatiskt detta enda bootstrap-konto. Aktivera registrering endast under ett avsiktligt senare tidsfönster. - Konfigurera Turnstile-begränsningar för värdnamn och ställ
TURNSTILE_EXPECTED_HOSTNAMEtill exakt det publika värdnamnet.
Starta och verifiera:
cd /opt/libre-webui
docker compose config --quiet
docker compose up -d
docker compose ps
För att aktivera Work inkluderar du medvetet åsidosättningen för socketproxyn:
docker compose -f docker-compose.yml -f docker-compose.work-proxy.yml up -d
Varianten med rå socket (docker-compose.work.yml) finns kvar för installationer
som behöver den, med tillitskonsekvenserna ovan.
När Access är aktivt behöver kommandoradstester en Cloudflare Access-tjänstetoken om inte den exakta sökvägen har ett smalt undantag. Lagra uppgifterna utanför skalhistoriken och skicka båda rubrikerna:
curl --fail --silent --show-error \
-H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \
-H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET" \
https://your-hostname.example/api/auth/system-info
En oautentiserad förfrågan till ett skyddat program-API måste returnera 401:
curl --output /dev/null --write-out '%{http_code}\n' \
-H "CF-Access-Client-Id: $CF_ACCESS_CLIENT_ID" \
-H "CF-Access-Client-Secret: $CF_ACCESS_CLIENT_SECRET" \
https://your-hostname.example/api/work/tasks
Härda värden
Katalogen innehåller ett sshd-tillägg och ett fail2ban-fängelse. Innan sshd-tillägget
tillämpas ska du verifiera en separat sudo-session utan root i en annan terminal.
Testa konfigurationen med sshd -t innan SSH läses in igen.
Använd UFW (eller en motsvarande brandvägg) för att neka inkommande trafik som standard och endast tillåta hastighetsbegränsad SSH. Docker publicerar inga tjänsteportar i mallen:
ufw default deny incoming
ufw default allow outgoing
ufw limit OpenSSH
ufw enable
Behåll obevakade säkerhetsuppdateringar aktiverade. Inaktivera vidarebefordran av X11, agent och TCP om installationen inte har ett dokumenterat behov av dem.
Säkerhetskopiering och återställning
Kör den skrivskyddade återställningsinventeringen i den aktiva distributionscontainern före säkerhetskopiering. Då används exakt den distribuerade programversionen, miljön och monterade datavolymen. Ett kommando från en utcheckning på värden kan granska fel databas eller köra källkod som skiljer sig från den distribuerade avbildningen.
docker exec libre-webui \
libre-webui recovery-check --json --data-dir /app/backend/data
Slutstatus 0 betyder att inga hinder för återställningsberedskap hittades, 1 att
JSON-rapporten innehåller hinder och 2 att kommandot inte kunde köras. Rapporten
innehåller endast ett fingeravtryck för krypteringsnyckeln och flaggor om hemligheter.
Den skriver aldrig ut en nyckel eller annat hemligt värde. Behåll inventeringen med
motsvarande säkerhetskopia så att operatörer kan jämföra programversion, schemafingeravtryck,
förväntade Work-resurser och undantag före återställning.
Skapa särskilda krypterings- och signeringsnycklar för säkerhetskopiering med exakt den distribuerade avbildningen. Håll katalogen utanför programvolymen och kopiera krypteringsnyckeln och den privata signeringsnyckeln till en separat skyddad återställningsplats:
install -d -m 0700 /etc/libre-webui/backup-keys
image_ref=$(docker inspect libre-webui --format '{{.Image}}')
docker run --rm --user 0:0 --read-only --network none --cap-drop ALL \
--security-opt no-new-privileges \
--mount type=bind,src=/etc/libre-webui/backup-keys,dst=/backup-keys \
--entrypoint /usr/local/bin/libre-webui "$image_ref" \
backup keygen \
--directory /backup-keys
Nyckelgenereringen vägrar att skriva över befintliga utdatafiler. Generera aldrig nya nycklar över en befintlig säkerhetskopieuppsättning. Om arkivets krypteringsnyckel eller signeringsidentitet förloras blir motsvarande återställningsbevis oanvändbart.
Installera de medföljande skripten och systemd-enheterna för säkerhetskopiering och återställning och aktivera sedan timern:
install -d -m 0700 /var/backups/libre-webui
install -m 0750 deploy/private/libre-webui-backup \
/usr/local/sbin/libre-webui-backup
install -m 0750 deploy/private/libre-webui-restore \
/usr/local/sbin/libre-webui-restore
install -m 0644 deploy/private/libre-webui-backup.{service,timer} \
/etc/systemd/system/
systemctl daemon-reload
systemctl enable --now libre-webui-backup.timer
Enheten kan läsa underhållsspecifika åsidosättningar från /etc/libre-webui/backup.env.
Den läser inte programmets .env. Skapa endast filen som root när ett åsidosättande behövs:
install -d -m 0750 /etc/libre-webui
install -m 0600 /dev/null /etc/libre-webui/backup.env
LIBRE_WEBUI_STACK_DIR, LIBRE_WEBUI_BACKUP_RETENTION_DAYS,
LIBRE_WEBUI_CONTAINER_NAME och LIBRE_WEBUI_BACKUP_KEY_DIR kan anges direkt där.
Behåll root som ägare och läget 0600. En anpassad nyckelkatalog måste förbli läsbar
för root i systemd-sandlådan.
Om LIBRE_WEBUI_BACKUP_DIR ändras, ändras också systemd:s skrivgräns. Katalogen måste
finnas innan tjänsten startar och enheten behöver ett motsvarande tillägg. Efter att
LIBRE_WEBUI_BACKUP_DIR=/srv/backups/libre-webui har angetts i backup.env:
install -d -m 0700 /srv/backups/libre-webui
systemctl edit libre-webui-backup.service
Lägg till exakt denna sökväg i redigeraren och läs sedan in enheten igen:
[Service]
ReadWritePaths=/srv/backups/libre-webui
systemctl daemon-reload
systemctl start libre-webui-backup.service
Utan motsvarande ReadWritePaths=-post förhindrar ProtectSystem=strict korrekt att
timern skriver till en anpassad plats.
Säkerhetskopieringstjänsten tillåter upp till sex timmar för stora arkiv. Hjälpen tar
ett lås på värden, stoppar endast programmet om det redan kördes och skapar arkivet från den
vilande volymen med exakt den distribuerade avbildningen. Arkivet har ett signerat
manifest och en operatörskrypterad nyttolast. Det innehåller datakatalogen samt den
körtids- och hemlighetskonfiguration som krävs för att öppna tillståndet. Hjälpen
verifierar därefter hela arkivet oberoende innan metadatarapporten publiceras atomärt.
Dess skrivskyddade underhållscontainrar får en privat skrivbar /tmp tmpfs för
SQLite-granskning och autentiserad arkivverifiering. Ingen tillfällig klartext lagras
i containerlagret. Kopiera båda filerna och de separat skyddade återställningsnycklarna
utanför värden.
När Work använder docker-compose.work-proxy.yml måste återställning också bevisa att
varje Work-volym som databasen refererar till finns kvar. Hjälpen läser det distribuerade
programmets DOCKER_HOST, hittar socketproxytjänsten i samma aktiva Compose-projekt och
upptäcker deras enda gemensamma interna nätverk från Dockers faktiska nätverksanslutningar.
Compose lägger till projektnamnet före nätverksnamnet, så konfigurera eller hårdkoda inte
ett gissat namn. Endast containern som skapar arkivet ansluter till det interna nätverket
och kan nå den filtrerade proxyn; den får ingen rå socket. Oberoende arkivverifiering
fortsätter med --network none. En saknad proxy, oväntad slutpunkt, ett externt eller
tvetydigt gemensamt nätverk eller en rå socketmontering orsakar fel innan programmet
stoppas och innan ett arkiv publiceras.
Testa återställning till en ny volym utan att ersätta den aktiva volymen:
LIBRE_WEBUI_RESTORE_IMAGE="$image_ref" \
libre-webui-restore \
/var/backups/libre-webui/libre-webui-integrated-YYYYMMDDTHHMMSSZ.lwb \
libre-webui-restore-drill
Återställningshjälpen vägrar en befintlig volym eller ett konfigurationsmål, verifierar
arkivet och dess interna återställningsinventering i tillfällig lagring och kopierar
sedan data till den nya volymen samt skriver återställda runtime.json och secrets.json
med privata behörigheter. Den kopplar aldrig om eller startar den aktiva stacken.
Granska den återställda konfigurationen, uppdatera distributionsspecifika värden medvetet
och testa den återställda volymen med en isolerad stack.
Ollama-modeller kan hämtas igen. Docker Work-volymer, Kubernetes Work-PVC:er och värdbundna Work-mappar ligger utanför programmets datakatalog och kräver egna samordnade ögonblicksbilder och lagringspolicyer.
Uppdateringar
Libre WebUI är tillståndsbevarande även när avbildningstaggen är föränderlig. Basfilen för Compose märker permanent programmet som undantaget från Watchtower. Uppgradera endast som en samordnad operatörsåtgärd:
- Registrera ID:t för den aktiva avbildningen och lös den granskade ersättaren till en oföränderlig digest.
- Kör
libre-webui recovery-check, starta säkerhetskopieringstjänsten och kräv ett nyskapat arkiv och en verifieringsrapport innan du fortsätter. - Ställ
LIBRE_WEBUI_IMAGEtill den granskade digesten, hämta den och återskapa endastlibre-webuimed Docker Compose. Ta inte bort eller återskapa dess datavolym. - Kräv att
/health/ready, inloggning, session/historik, dokumenthämtning och Work-tester godkänns. Återgå till den registrerade avbildningsdigesten om de misslyckas och bevara både det misslyckade tillståndet och den verifierade säkerhetskopian för diagnos.
Sekvensen på värdsidan är avsiktligt manuell. Ersätt digesten först efter granskning
och kontrollera det senaste paret .lwb och .json före hämtning:
docker inspect libre-webui --format '{{.Config.Image}} {{.Image}}'
docker exec libre-webui \
libre-webui recovery-check --json --data-dir /app/backend/data
systemctl start libre-webui-backup.service
systemctl --no-pager --full status libre-webui-backup.service
ls -lt /var/backups/libre-webui/libre-webui-integrated-* | head
# Set LIBRE_WEBUI_IMAGE=ghcr.io/libre-webui/libre-webui@sha256:REVIEWED_DIGEST
# in the root-owned .env, then recreate only the application.
docker compose pull libre-webui
docker compose up -d --no-deps libre-webui
docker inspect libre-webui --format '{{.State.Health.Status}} {{.Image}}'
Den valfria socketbärande Watchtower-åsidosättningen finns kvar endast för de sidecars som uttryckligen märkts i basfilen:
docker compose \
-f docker-compose.yml \
-f docker-compose.watchtower.yml \
up -d
Watchtower kontrollerar Ollama och SearXNG var 30:e minut. Ollama-modelldata ligger kvar
i den namngivna volymen och SearXNG-konfigurationen i sin bind-montering. Den uppdaterar
inte Libre WebUI, cloudflared, Work-socketproxyn eller Work-sandlådor. En klientinstallation
följer main. En experimentell instans kan välja :dev, men programmet kräver fortfarande
samma säkerhetskopieringsspärrade manuella uppgradering. Anslut aldrig denna privata
solo-stack till teambeständighetstjänster. Distribuera hela teamtopologin i stället.