
Outline cu Docker Compose: wiki si baza de cunostinte pe VPS
Orice echipa ajunge, mai devreme sau mai tarziu, la aceeasi dezordine: parola de la server sta intr-un thread de chat de primavara trecuta, checklist-ul de onboarding exista doar in capul unui coleg, iar versiunea “finala” a ghidului de deploy e un document pe care nu-l mai gaseste nimeni. Un wiki de echipa rezolva problema, dar variantele hostate populare taxeaza per utilizator, iti tin cunostintele pe serverele altcuiva si devin lente dupa cateva mii de pagini. Outline e alternativa pe care o tot recomandam: arata si se simte ca Notion, e chiar rapid, iar cu Docker Compose il poti rula pe propriul VPS in mai putin de o ora.
In acest tutorial construim de la zero un stack complet outline wiki docker compose: Outline in sine, PostgreSQL pentru date, Redis pentru functiile in timp real, stocare locala pe disc pentru fisierele urcate, Caddy pentru HTTPS automat si autentificare fie prin single sign-on-ul firmei (OIDC), fie prin linkuri simple pe email. Fiecare pas e explicat, asa ca nu trebuie sa fii sysadmin cu experienta ca sa-l urmezi.
Ce este Outline si de ce le place echipelor
Outline (getoutline.com , codul sursa pe github.com/outline/outline ) este o aplicatie de baza de cunostinte pentru echipe. Organizezi documentele in colectii (de exemplu “Tehnic”, “Vanzari”, “HR”), pui pagini in pagini, iar toata lumea editeaza intr-un editor curat, prietenos cu Markdown, in care modificarile mai multor oameni apar live, ca in Google Docs.
Ce primesti din cutie:
- Editare colaborativa in timp real, cu scurtaturi Markdown si un meniu “/” pentru tabele, blocuri de cod, checklist-uri si embed-uri.
- Cautare full-text rapida in toate documentele la care ai acces.
- Permisiuni pe colectie, ca folderul de HR sa ramana privat in timp ce ghidul de onboarding e deschis tuturor.
- Istoric de revizii, comentarii si template-uri, plus linkuri publice de partajare cand vrei sa arati o pagina unui client.
- API si integrari (Slack, embed-uri pentru multe unelte uzuale) si o interfata tradusa in multe limbi.
Doua lucruri ii surprind pe cei care il instaleaza prima data, asa ca le spunem de la inceput:
- Outline nu are login clasic cu utilizator si parola. Oamenii se autentifica printr-un furnizor de identitate (OIDC, Google, Microsoft, Slack si altele) sau printr-un “magic link” primit pe email. Daca pornesti aplicatia fara sa configurezi una dintre aceste metode, te uiti la o pagina de login fara nicio cale de intrare. Pasul 6 e dedicat integral acestui subiect.
- Licenta este BSL 1.1 (Business Source License). Self-hosting-ul pentru echipa ta e permis si gratuit; ce nu ai voie sa faci e sa revinzi Outline ca serviciu hostat concurent. Fiecare versiune devine open source dupa cativa ani.
Cativa termeni pe care ii folosim
- Container: o aplicatie impachetata cu tot ce ii trebuie ca sa ruleze, izolata de restul serverului. Outline, PostgreSQL, Redis si Caddy ruleaza fiecare in containerul lui.
- Docker Compose: unealta care porneste mai multe containere impreuna dintr-un singur fisier text (
docker-compose.yml), deci tot stack-ul e descris intr-un singur loc. - Volum: un spatiu de stocare administrat de Docker care supravietuieste restarturilor si actualizarilor. Documentele si fisierele tale stau in volume, nu in containere.
- Port: o “usa” numerotata a serverului. Traficul web foloseste 80 (HTTP) si 443 (HTTPS); Outline asculta intern pe 3000.
- Reverse proxy: un server web pus in fata (aici Caddy) care primeste cererile HTTPS din internet, se ocupa de certificatul TLS si le trimite containerului potrivit.
- OIDC (OpenID Connect): un standard prin care spui “lasa alt sistem sa confirme cine este utilizatorul”. Keycloak, Authentik, Google Workspace si Microsoft Entra ID il suporta toate.
- SMTP: protocolul folosit pentru trimiterea emailurilor. Outline are nevoie de el pentru magic links, invitatii si notificari.
Cum se leaga piesele stack-ului Outline
Browserul vorbeste doar cu Caddy. Caddy termina HTTPS-ul si trimite cererea catre Outline, pe reteaua privata Docker. Outline tine documentele, utilizatorii si indexul de cautare in PostgreSQL, foloseste Redis pentru joburi in fundal si pentru sincronizarea editarilor live intre utilizatori, iar imaginile si atasamentele urcate le scrie intr-un volum Docker pe discul local. Cand cineva se logheaza, Outline face conexiuni de iesire catre furnizorul OIDC sau catre serverul SMTP.
De ce ai nevoie
- Un VPS cu minim 2 vCPU si 2 GB RAM (4 GB e confortabil pentru o echipa de 20+ oameni sau daca importi spatii mari), cel putin 20 GB disc, cu Debian 13 sau Ubuntu 24.04. Un VPS KVM e cea mai simpla alegere; vezi mai jos nota despre LXC.
- Un domeniu sau subdomeniu pe care il controlezi, de exemplu
wiki.exemplu.ro, unde poti crea o inregistrare DNS. - Acces SSH cu un utilizator obisnuit cu drepturi sudo. Toate comenzile de mai jos se ruleaza cu acest utilizator, nu ca root.
- O metoda de autentificare: fie un furnizor OIDC (Keycloak, Authentik, Google Workspace, Microsoft Entra ID etc.) in care poti inregistra o aplicatie, fie date SMTP pentru o casuta care poate trimite email. Ideal, amandoua.
- Cam 45 de minute, inclusiv asteptarea propagarii DNS.
O nota despre containerele LXC: Docker intr-un container LXC neprivilegiat functioneaza doar daca host-ul activeaza nesting (si de obicei keyctl) pentru containerul respectiv. Daca ai un plan LXC la DreamServer, cere suportului sa confirme ca aceste functii sunt active sau alege direct un VPS KVM, unde Docker merge fara setari speciale.
Cata memorie consuma de fapt? Pentru o echipa mica, tot stack-ul sta mult sub 1 GB in repaus. Outline, o aplicatie Node.js, e de departe cea mai mare piesa:
Instalarea pe scurt
Aceasta e toata procedura. Fiecare caseta corespunde unui titlu “Pasul” de mai jos, in aceeasi ordine.
Pasul 1: Pregatirea VPS-ului si a DNS-ului
Incepem cu un sistem la zi. Conecteaza-te prin SSH si ruleaza:
sudo apt update && sudo apt full-upgrade -y
Comanda reimprospateaza lista de pachete si instaleaza toate actualizarile. Trebuie restart dupa? Pe Ubuntu, verifica daca exista fisierul /var/run/reboot-required (ls /var/run/reboot-required); daca exista, ruleaza sudo reboot. Debian nu creeaza mereu acest fisier, asa ca pe Debian da reboot daca actualizarea a instalat un pachet linux-image nou.
Apoi indreapta domeniul catre server. In panoul DNS, creeaza o inregistrare A pentru wiki.exemplu.ro cu adresa IPv4 a VPS-ului (si o inregistrare AAAA cu adresa IPv6, daca VPS-ul are una). Inlocuieste wiki.exemplu.ro cu domeniul tau real peste tot in acest ghid. Dupa cateva minute, verifica de pe server:
getent hosts wiki.exemplu.ro
Ar trebui sa vezi IP-ul VPS-ului. Daca nu apare nimic, mai asteapta putin; Caddy nu poate obtine certificat pana cand DNS-ul nu se rezolva corect.
Acum un firewall de baza. Un firewall decide pe ce porturi se accepta conexiuni. Folosim ufw, care vine preinstalat pe Ubuntu 24.04, dar trebuie instalat pe Debian 13:
sudo apt install -y ufw
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443
sudo ufw enable
sudo ufw status verbose
In rezultat ar trebui sa vezi 22, 80 si 443 cu ALLOW IN. Daca SSH-ul tau asculta pe alt port, permite acel port in loc de 22 inainte de ufw enable, altfel te blochezi singur afara. Un detaliu important: porturile publicate de Docker ocolesc complet ufw, pentru ca Docker isi scrie propriile reguli de firewall. Regulile pentru 80/443 de mai sus documenteaza doar intentia; protectia reala pentru Outline vine din faptul ca nu publicam niciodata portul lui, 3000.
Pasul 2: Instalarea Docker Engine si a pluginului Compose
Instalam Docker din repository-ul oficial Docker, care are versiuni mai noi decat pachetele distributiei si include pluginul docker compose. Repository-ul e descris in formatul deb822 actual folosit de Docker, in fisierul /etc/apt/sources.list.d/docker.sources:
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
. /etc/os-release
sudo curl -fsSL "https://download.docker.com/linux/${ID}/gpg" -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/${ID}
Suites: ${VERSION_CODENAME}
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Linia . /etc/os-release incarca doua variabile utile: ID (care e debian sau ubuntu) si VERSION_CODENAME (trixie pe Debian 13, noble pe Ubuntu 24.04). Asa, acelasi bloc merge pe ambele sisteme. Poti verifica rezultatul cu cat /etc/apt/sources.list.d/docker.sources.
Permite utilizatorului tau sa ruleze Docker fara sudo de fiecare data, apoi delogheaza-te si conecteaza-te din nou ca schimbarea de grup sa intre in vigoare:
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER"
exit
Dupa reconectare, verifica:
docker run --rm hello-world
docker compose version
Ar trebui sa vezi mesajul “Hello from Docker!” si o versiune Compose care incepe cu v2. Retine ca apartenenta la grupul docker inseamna practic acces root, deci adauga doar conturi de incredere.
Pasul 3: Folderul proiectului si generarea secretelor
Tot ce tine de acest stack sta intr-un singur folder, ~/outline. Outline are nevoie de doua secrete aleatoare, iar PostgreSQL de o parola. Le generam pe toate cu openssl, ca sa nu fie nevoie sa inventezi tu una:
mkdir -p ~/outline && cd ~/outline
WIKI_DOMAIN=wiki.exemplu.ro
echo "POSTGRES_PASSWORD=$(openssl rand -hex 24)" > .env
cat > outline.env <<EOF
NODE_ENV=production
URL=https://${WIKI_DOMAIN}
PORT=3000
SECRET_KEY=$(openssl rand -hex 32)
UTILS_SECRET=$(openssl rand -hex 32)
PGSSLMODE=disable
REDIS_URL=redis://redis:6379
FILE_STORAGE=local
FILE_STORAGE_LOCAL_ROOT_DIR=/var/lib/outline/data
FILE_STORAGE_UPLOAD_MAX_SIZE=262144000
FORCE_HTTPS=true
DEFAULT_LANGUAGE=en_US
EOF
chmod 600 .env outline.env
cat outline.env
Schimba wiki.exemplu.ro de pe a doua linie cu domeniul tau inainte sa rulezi blocul. Ce contin aceste fisiere:
.enve citit automat de Docker Compose. Contine doarPOSTGRES_PASSWORD, pe care fisierul compose il foloseste si pentru containerul bazei de date, si pentru a construi sirul de conectare al lui Outline. Caracterele hex sunt sigure intr-un URL, ceea ce conteaza pentru ca parola ajunge intr-un URL.outline.enve transmis containerului Outline.URLtrebuie sa fie exact adresa publica pe care o tasteaza utilizatorii, cuhttps://si fara slash la final.SECRET_KEYcripteaza datele sensibile din baza de date,UTILS_SECRETprotejeaza endpoint-urile interne de mentenanta.PGSSLMODE=disablee corect pentru ca PostgreSQL e accesat prin reteaua privata Docker.FILE_STORAGE=localii spune lui Outline sa tina fisierele pe disc in loc de S3, iarFILE_STORAGE_UPLOAD_MAX_SIZEe marimea maxima a unui upload in bytes (aici 250 MB).
cat outline.env de la final ar trebui sa arate doua siruri hex lungi pentru secrete si domeniul tau real in URL. Fa backup acestor doua fisiere intr-un loc sigur. Daca pierzi SECRET_KEY, datele criptate din baza de date nu mai pot fi recuperate.
Pasul 4: Fisierul docker-compose.yml pentru Outline
Acum inima configuratiei outline wiki docker compose. Creeaza fisierul cu nano docker-compose.yml si lipeste:
name: outline
services:
outline:
image: docker.getoutline.com/outlinewiki/outline:latest
restart: unless-stopped
env_file: ./outline.env
environment:
DATABASE_URL: postgres://outline:${POSTGRES_PASSWORD}@postgres:5432/outline
volumes:
- files:/var/lib/outline/data
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
postgres:
image: postgres:17
restart: unless-stopped
environment:
POSTGRES_USER: outline
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: outline
volumes:
- db:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U outline -d outline"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:8-alpine
restart: unless-stopped
volumes:
- redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- outline
volumes:
files:
db:
redis:
caddy_data:
caddy_config:
Salveaza cu Ctrl+O, Enter, apoi Ctrl+X. Iata ce face fiecare parte:
name: outlinefixeaza numele proiectului, deci volumele primesc nume previzibile, precumoutline_filessioutline_db. Ne bazam pe asta la Pasul 8.outlinefoloseste imaginea oficiala din registry-ul Outline (aceeasi imagine exista si pe Docker Hub, caoutlinewiki/outline). Observa ca nu are sectiuneports:: e accesibila doar de Caddy, in reteaua Docker.depends_oncuservice_healthyasteapta pana cand PostgreSQL si Redis raspund efectiv, ca Outline sa nu intre intr-o bucla de restart la prima pornire.- Despre
:latest: Outline nu publica un tag de versiune majora, asa calateste comod, dar inseamna ca oricedocker compose pullpoate sari la o versiune noua. Dupa ce totul merge, iti recomandam sa inlocuiestilatestcu numarul exact de versiune de pe pagina de release-uri (de exempluoutlinewiki/outline:X.Y.Z) si sa actualizezi constient. postgres:17urmareste versiunea majora curenta si primeste automat patch-urile de securitate din acea majora. Nu schimba ulterior numarul major fara dump si restore, pentru ca versiunile majore PostgreSQL au formate de date incompatibile. Verifica pe pagina oficiala a imaginii care e cea mai noua majora cand instalezi.redis:8-alpinee o imagine Redis mica; Outline foloseste Redis pentru cozi de joburi si pentru a transmite editarile live intre utilizatori. Merge si tag-ul7-alpine, daca il preferi.caddy:2e singurul serviciu cu porturi publicate: 80 pentru validarea certificatului si redirect, 443 pentru HTTPS (TCP si UDP, al doilea pentru HTTP/3).- Blocul
volumes:declara volume cu nume. Datele din ele supravietuiesc ladocker compose down, actualizari si restarturi.
Valideaza fisierul fara sa-ti afisezi secretele:
docker compose config --quiet
Daca nu apare nimic, sintaxa e corecta. Un mesaj de eroare iti arata linia cu problema, cel mai des o greseala de indentare (YAML cere spatii, niciodata tab-uri).
Pasul 5: Caddy ca reverse proxy
Caddy are nevoie de un fisier de configurare minuscul, Caddyfile. Obtine si reinnoieste singur un certificat Let’s Encrypt gratuit, redirectioneaza HTTP catre HTTPS si trimite totul, inclusiv conexiunile WebSocket folosite de Outline pentru colaborare live, catre containerul Outline:
cd ~/outline
cat > Caddyfile <<EOF
${WIKI_DOMAIN} {
encode zstd gzip
reverse_proxy outline:3000
}
EOF
cat Caddyfile
Rezultatul trebuie sa inceapa cu domeniul tau real urmat de {. Daca ai deschis o sesiune SSH noua de la Pasul 3, variabila WIKI_DOMAIN nu mai exista si fisierul ar incepe doar cu {; in acest caz seteaz-o din nou (WIKI_DOMAIN=wiki.exemplu.ro) si ruleaza blocul inca o data.
encode zstd gzip comprima raspunsurile ca paginile sa se incarce mai repede, iar reverse_proxy outline:3000 foloseste numele serviciului din fisierul compose ca hostname, pe care Docker il rezolva in reteaua interna. Daca preferi nginx in locul lui Caddy, nu uita sa transmiti header-ele Upgrade si Connection pentru WebSocket, sa setezi X-Forwarded-Proto si sa maresti client_max_body_size, altfel editarea live si upload-urile mari nu vor merge.
Pasul 6: Configurarea autentificarii prin OIDC sau email
Cum spuneam la inceput, Outline nu are parole locale, deci inainte de prima pornire trebuie sa configurezi cel putin o cale de intrare. Acoperim cele doua variante cele mai universale. Le poti activa pe amandoua simultan si iti recomandam sa configurezi SMTP chiar daca folosesti OIDC, pentru ca Outline trimite si invitatii si notificari pe email.
Varianta A: single sign-on prin OIDC
In furnizorul de identitate (Keycloak, Authentik, Google Workspace, Microsoft Entra ID etc.), creeaza o aplicatie OIDC noua (uneori numita “client”) cu setarile:
- Tip client: confidential, cu client secret.
- Redirect URI (sau callback URL):
https://wiki.exemplu.ro/auth/oidc.callback, exact asa, cu domeniul tau. - Scopes:
openid profile email. Outline are nevoie de adresa de email a utilizatorului, asa ca asigura-te ca utilizatorii au una completata in furnizor.
Furnizorul iti afiseaza apoi un client ID si un client secret. Mai ai nevoie si de URL-urile endpoint-urilor. Orice furnizor OIDC le publica intr-un “document de discovery” la <issuer>/.well-known/openid-configuration; le poti extrage asa (exemplu cu URL in stil Keycloak):
curl -s https://sso.exemplu.ro/realms/echipa/.well-known/openid-configuration \
| grep -o '"[a-z_]*endpoint" *: *"[^"]*"'
Cauta authorization_endpoint, token_endpoint, userinfo_endpoint si end_session_endpoint. La Authentik, caile arata ca /application/o/authorize/, /application/o/token/ si /application/o/userinfo/. Acum adauga setarile in outline.env:
cd ~/outline
cat >> outline.env <<'EOF'
OIDC_CLIENT_ID=outline
OIDC_CLIENT_SECRET=lipeste-aici-client-secret
OIDC_AUTH_URI=https://sso.exemplu.ro/realms/echipa/protocol/openid-connect/auth
OIDC_TOKEN_URI=https://sso.exemplu.ro/realms/echipa/protocol/openid-connect/token
OIDC_USERINFO_URI=https://sso.exemplu.ro/realms/echipa/protocol/openid-connect/userinfo
OIDC_LOGOUT_URI=https://sso.exemplu.ro/realms/echipa/protocol/openid-connect/logout
OIDC_USERNAME_CLAIM=preferred_username
OIDC_DISPLAY_NAME=SSO Firma
OIDC_SCOPES=openid profile email
EOF
nano outline.env
Ghilimelele din jurul lui 'EOF' opresc shell-ul sa interpreteze ceva din interior, deci valorile se scriu literal. Apoi, in nano, inlocuieste secretul de exemplu si URL-urile cu valorile tale reale. OIDC_DISPLAY_NAME e textul de pe butonul de login (“Continue with SSO Firma”). OIDC_LOGOUT_URI e optional; daca e setat, delogarea din Outline il delogheaza pe utilizator si din furnizor.
Un sfat practic: restrictioneaza cine poate folosi Outline chiar in furnizorul de identitate (de exemplu, doar membrii grupului “wiki” primesc acces la aplicatie). E cea mai curata metoda de control al accesului cu OIDC.
Varianta B: magic links pe email prin SMTP
Cu SMTP configurat, utilizatorii isi scriu adresa de email pe pagina de login si primesc un link de autentificare de unica folosinta. Foloseste datele unei casute de email sau ale unui serviciu de email tranzactional care are voie sa trimita de pe domeniul tau:
cd ~/outline
cat >> outline.env <<'EOF'
SMTP_HOST=smtp.exemplu.ro
SMTP_PORT=587
SMTP_USERNAME=wiki@exemplu.ro
SMTP_PASSWORD=lipeste-aici-parola-smtp
SMTP_FROM_EMAIL=wiki@exemplu.ro
SMTP_SECURE=false
EOF
nano outline.env
Foloseste portul 587 cu SMTP_SECURE=false (conexiunea se securizeaza cu STARTTLS) sau portul 465 cu SMTP_SECURE=true (TLS de la primul byte). Inversarea lor e cel mai frecvent motiv pentru care emailurile nu pleaca, fara nicio eroare evidenta. Evita portul 25: multe retele restrictioneaza traficul de iesire pe el si oricum e gandit pentru livrare intre servere.
Cum intra primii utilizatori doar cu email? In versiunile recente de Outline, o instalare noua cu SMTP configurat si fara furnizor SSO afiseaza un camp de email care ii permite primei persoane sa creeze workspace-ul. Toti ceilalti intra apoi prin invitatie sau pentru ca domeniul lor de email e pe lista permisa a workspace-ului. Daca versiunea ta nu afiseaza campul de email pe o instalare goala, configureaza OIDC (Varianta A) pentru primul login, apoi activeaza autentificarea pe email pentru restul din setarile de securitate.
Pasul 7: Pornirea stack-ului si crearea workspace-ului
E momentul sa pornim totul:
cd ~/outline
docker compose up -d
docker compose ps
Prima rulare descarca imaginile, ceea ce dureaza un minut sau doua. docker compose ps ar trebui sa arate patru servicii cu statusul Up, iar postgres si redis ar trebui sa aiba si (healthy). Acum urmareste log-ul lui Outline cat timp se initializeaza:
docker compose logs -f outline
La prima pornire, Outline isi creeaza tabelele in PostgreSQL (migrarile bazei de date, pe care le ruleaza automat), apoi raporteaza ca asculta pe portul 3000. Formularea exacta difera de la o versiune la alta. Apasa Ctrl+C ca sa nu mai urmaresti log-ul; containerele raman pornite. Verifica daca Caddy a obtinut certificatul:
curl -I https://wiki.exemplu.ro
Un raspuns care incepe cu HTTP/2 200 (sau un redirect 30x) inseamna ca HTTPS-ul merge cap-coada. Daca vezi o eroare de certificat, uita-te in docker compose logs caddy.
Deschide https://wiki.exemplu.ro in browser. Ar trebui sa vezi un buton de login pentru SSO si/sau un camp de email. Prima persoana care se logheaza creeaza workspace-ul si devine administrator, asa ca fa asta tu, imediat. Apoi, in Settings:
- Details: seteaza numele workspace-ului, logo-ul si, daca vrei, un nume personalizat.
- Security: decide cine se poate alatura. Cu login pe email, seteaza domeniile de email permise (de exemplu doar
exemplu.ro) sau pastreaza inscrierea doar pe baza de invitatie si alege rolul implicit pentru membrii noi. - Members: invita colegii pe email; primesc un link de alaturare.
Creeaza prima colectie, scrie o pagina, trage o imagine in ea si deschide aceeasi pagina intr-o a doua fereastra de browser ca sa vezi editarea live. Daca imaginea apare si editarile se sincronizeaza intre ferestre, Redis, stocarea locala si WebSocket-urile functioneaza.
Ori de cate ori modifici ulterior outline.env, aplica schimbarea cu docker compose up -d --force-recreate outline, care recreeaza doar containerul Outline si nu atinge datele.
Pasul 8: Backup pentru Outline si test de restore
Un wiki devine repede locul unde stau cele mai importante cunostinte ale echipei, deci backup-ul nu e optional. Trebuie salvate trei lucruri: baza de date PostgreSQL (documente, utilizatori, permisiuni), volumul de fisiere (upload-uri si imagini) si fisierele de configurare (mai ales outline.env, cu SECRET_KEY). Redis tine doar date temporare de coada si nu are nevoie de backup.
Creeaza ~/outline/backup.sh:
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
STAMP=$(date +%F)
mkdir -p backups
chmod 700 backups
docker compose exec -T postgres pg_dump -U outline -d outline -Fc > "backups/outline-db-$STAMP.dump"
docker run --rm -v outline_files:/data:ro -v "$PWD/backups":/backup alpine \
sh -c "tar czf /backup/outline-files-$STAMP.tar.gz -C /data . && chown $(id -u):$(id -g) /backup/outline-files-$STAMP.tar.gz"
tar czf "backups/outline-config-$STAMP.tar.gz" .env outline.env docker-compose.yml Caddyfile
find backups -type f -mtime +14 -delete
echo "Backup $STAMP gata"
Fa-l executabil si ruleaza-l o data:
chmod +x ~/outline/backup.sh
~/outline/backup.sh
ls -lh ~/outline/backups
Ar trebui sa vezi trei fisiere cu data de azi. Cateva note despre cum functioneaza:
pg_dumpruleaza in interiorul containerului bazei de date si se conecteaza prin socket-ul local, pe care imaginea oficiala PostgreSQL il considera de incredere, deci nicio parola nu apare in linia de comanda sau in lista de procese.-Fcproduce un dump comprimat in “custom format”, pe care il intelegepg_restore.- Arhiva de fisiere e creata de un container Alpine temporar care ruleaza ca root, de aceea scriptul se termina cu un
chowninapoi la utilizatorul tau. Daca vreodata creezi singur arhive cusudo tarin folderul home, ele vor apartine lui root; ruleazasudo chown "$USER": fisierinainte sa le copiezi de pe server. - Backup-urile mai vechi de 14 zile se sterg.
Ca sa ruleze in fiecare noapte la 03:30, adauga-l in crontab-ul utilizatorului cu crontab -e:
30 3 * * * $HOME/outline/backup.sh >> $HOME/outline/backups/backup.log 2>&1
Backup-urile tinute pe acelasi server nu te protejeaza daca pierzi serverul. Trage-le regulat pe alta masina, de exemplu de pe laptop cu rsync -av utilizator@ip-vps:outline/backups/ ./outline-backups/.
Restore intr-o baza de date noua
Regula de aur: restaurezi intr-o baza de date goala, niciodata peste cea live. Cel mai curat test e un al doilea VPS: instalezi Docker (Pasul 2), copiezi folderul cu fisierul compose, Caddyfile, .env, outline.env si fisierele de backup, apoi pornesti doar baza de date si Redis. PostgreSQL creeaza o baza outline goala la prima pornire, pe care Outline inca nu a atins-o:
cd ~/outline
docker compose up -d postgres redis
docker compose ps
docker compose exec -T postgres pg_restore -U outline -d outline --no-owner < backups/outline-db-2026-11-10.dump
docker run --rm -v outline_files:/data -v "$PWD/backups":/backup alpine \
tar xzf /backup/outline-files-2026-11-10.tar.gz -C /data
docker compose up -d
Asteapta pana cand docker compose ps arata postgres ca healthy inainte de pg_restore si inlocuieste datele cu cea a backup-ului tau. Daca vrei sa restaurezi pe serverul original, opreste mai intai Outline ca nimic sa nu mai scrie in baza, apoi sterge-o si recreeaz-o goala:
cd ~/outline
docker compose stop outline
docker compose exec -T postgres dropdb -U outline outline
docker compose exec -T postgres createdb -U outline -O outline outline
docker compose exec -T postgres pg_restore -U outline -d outline --no-owner < backups/outline-db-2026-11-10.dump
docker compose start outline
Operatiunea e distructiva prin definitie: tot ce s-a scris dupa backup se pierde. Restaureaza volumul de fisiere in acelasi fel, daca e nevoie, cat timp Outline e oprit. Testeaza restore-ul macar o data; un backup netestat e doar o speranta.
Actualizarea in siguranta a lui Outline
Outline scoate versiuni noi des. O rutina sigura:
- Ruleaza
~/outline/backup.shsi confirma ca fisierele exista. - Citeste notele de release de pe pagina de release-uri , pentru schimbari incompatibile sau variabile noi obligatorii.
- Daca ai fixat o versiune, modifica tag-ul imaginii in
docker-compose.yml. - Descarca si reporneste:
cd ~/outline
docker compose pull
docker compose up -d
docker compose logs -f outline
Outline aplica automat migrarile bazei de date la pornire. Cand log-ul se linisteste, testeaza login-ul si deschide cateva documente. Pentru ca migrarile modifica baza de date, intoarcerea la o versiune mai veche inseamna restaurarea backup-ului de dinainte de upgrade intr-o baza noua, ca mai sus. Trecerea PostgreSQL la o versiune majora noua (de exemplu de la 17 la 18) e un proiect separat: faci dump, pornesti noua majora cu un volum nou, gol, si restaurezi in el. Retine ca imaginea PostgreSQL 18 si-a schimbat si directorul implicit de date, deci se schimba si calea de montare a volumului.
Depanare si greseli frecvente
- Containerul Outline se tot restarteaza. Ruleaza
docker compose logs outline. Mesajele despre variabile de mediu lipsa indica o greseala de scriere inoutline.env. “Connection refused” pentru baza de date inseamna de obicei ca PostgreSQL nu era inca gata (healthcheck-ul ar trebui sa previna asta) sau caPOSTGRES_PASSWORDa fost schimbata dupa crearea volumului; parola se aplica doar la prima pornire, pe un volum gol. - Pagina de login nu are niciun buton. Nicio metoda de autentificare nu e configurata sau un nume de variabila e gresit. Compara numele
OIDC_*sauSMTP_*cu cele de la Pasul 6, apoi ruleazadocker compose up -d --force-recreate outline. - OIDC spune “redirect_uri mismatch” sau “invalid redirect”. Callback-ul inregistrat in furnizor trebuie sa fie exact
https://domeniul-tau/auth/oidc.callback, iarURLdinoutline.envtrebuie sa coincida cu domeniul folosit de utilizatori, cuhttpssi fara slash la final. - Login-ul merge, dar ajungi la o eroare legata de email. Furnizorul nu trimite claim-ul de email. Adauga scope-ul
emailsi verifica faptul ca utilizatorii au adresa de email setata. - Caddy nu poate obtine certificatul. DNS-ul trebuie sa indice VPS-ul, iar portul 80 trebuie sa fie accesibil din internet. Verifica
docker compose logs caddysi asigura-te cusudo ss -tlnpca nimic altceva de pe host (un Apache sau nginx vechi) nu ocupa deja porturile 80 sau 443. - Imaginile nu se pot urca. Daca ai inlocuit volumul cu nume cu un bind mount (un folder de pe host), folderul trebuie sa poata fi scris de utilizatorul Outline din container:
sudo chown -R 1001:1001 /cale/catre/folder. Verifica siFILE_STORAGE_UPLOAD_MAX_SIZE. - Editarile nu se sincronizeaza live sau apar bannere “connection lost”. WebSocket-urile nu ajung la Outline. Caddy le gestioneaza automat; un nginx custom sau alt proxy pus in fata are nevoie de header-ele de upgrade.
- Emailurile cu magic link nu ajung. Verifica combinatia port si
SMTP_SECURE, cauta erori SMTP indocker compose logs outlinesi uita-te in folderul de spam. Domeniul de pe care trimiti ar trebui sa aiba inregistrari SPF si DKIM pentru furnizorul de email folosit. - Ai schimbat domeniul ulterior. Actualizeaza impreuna
URL,Caddyfilesi redirect URI-ul OIDC, apoi recreeaza containerele. Linkurile vechi catre domeniul anterior nu vor mai functiona. - Docker refuza sa porneasca intr-un container LXC. Nesting-ul nu e activat pentru container. Cere furnizorului sa il activeze sau treci pe un VPS KVM.
Note de securitate
- Publica doar Caddy. Outline, PostgreSQL si Redis nu au sectiune
ports:, deci nu sunt accesibile deloc din internet. Rezista tentatiei de a publica 3000 sau 5432 “doar pentru test”: porturile publicate de Docker ocolesc ufw, deci ar fi deschise pentru oricine. - Protejeaza secretele.
.envsioutline.envauchmod 600, la fel si folderul de backup-uri. Nu le pune niciodata intr-un repository Git. Pastreaza o copie offline a luiSECRET_KEY; fara el, datele criptate nu mai pot fi citite. - Controleaza inscrierea. Cu OIDC, limiteaza accesul in furnizor (grupuri sau asignari de aplicatie). Cu email, restrictioneaza domeniile permise sau pastreaza workspace-ul doar pe invitatie si revizuieste din cand in cand lista de membri.
- Trateaza grupul docker ca pe root. Oricine e in el controleaza tot serverul. Pastreaza autentificarea SSH cu chei, dezactiveaza login-ul SSH cu parola si tine sistemul la zi cu
sudo apt update && sudo apt full-upgrade. - Ramai la zi. Outline, Caddy si imaginile bazelor de date primesc fix-uri de securitate. Urmeaza lunar rutina de actualizare de mai sus sau aboneaza-te la notificarile de release Outline de pe GitHub.
- Tine backup-urile in afara serverului si cripteaza-le daca parasesc infrastructura pe care o controlezi, pentru ca ele contin toate documentele si fisierul cu secrete.
Deci, e Outline wiki-ul potrivit pentru echipa ta?
Daca vrei o baza de cunostinte rapida, aratoasa, cu colaborare live, permisiuni logice si o cautare care chiar gaseste lucruri, si preferi sa tii aceste cunostinte pe un server pe care il controlezi, Outline e una dintre cele mai bune optiuni de azi. Singurul obstacol real e autentificarea, iar dupa ce OIDC sau SMTP sunt puse la punct, experienta de zi cu zi e la fel de fluida ca la orice wiki hostat platit. Daca ai nevoie de permisiuni foarte complexe la nivel de pagina, editare offline sau o licenta strict aprobata OSI, uita-te mai degraba la alternative precum BookStack sau Wiki.js.
Poti rula exact stack-ul din acest ghid pe un VPS in data center-ul nostru din Romania, iar 2-4 GB RAM ajung pentru majoritatea echipelor. Daca nu vrei sa te ocupi singur de Docker, certificate, integrarea SSO si backup-uri, echipa noastra de administrare servere poate instala, securiza si intretine Outline pentru tine.
Intrebari frecvente
Este Outline gratuit pentru self-hosting?
Da. Outline e publicat sub Business Source License 1.1, care iti permite sa il gazduiesti gratuit pentru propria organizatie. Ce interzice este oferirea lui Outline ca serviciu hostat comercial, concurent cu cel oficial.
Pot folosi Outline fara SSO?
Da, cu magic links pe email. Ai nevoie de setari SMTP functionale; utilizatorii se logheaza apoi cu un link de unica folosinta primit in inbox. Outline tot nu are parole clasice, ceea ce multe echipe considera un avantaj de securitate.
Folosesc stocare locala sau S3 pentru fisiere?
Stocarea locala, ca in acest ghid, e cea mai simpla varianta si merge perfect pe un singur server; doar include volumul de fisiere in backup-uri. Stocarea compatibila S3 are sens cand rulezi mai multe instante Outline sau ai volume foarte mari de atasamente.
Merge Outline intr-un container LXC?
Docker poate rula in LXC doar daca nesting-ul e activat pentru containerul respectiv, ceea ce nu e implicit la containerele neprivilegiate. Un VPS KVM evita complet problema.
Pot importa continut din Notion sau Markdown?
Da. Outline poate importa fisiere Markdown si exporturi din Notion, printre alte formate, din setarile workspace-ului. Importurile mari folosesc temporar mai mult RAM si CPU, asa ca pe un VPS mic ruleaza-le in afara orelor de lucru.