Bu klasör, PocketBase sync backend’ini bir VPS üzerinde Docker ile ayağa kaldırır. Eklenti istemcide kalır; VPS’te yalnızca PocketBase (+ HTTPS için Caddy) çalışır.
obsidian.hermes.bilalarikan.com gibi, VPS IP’sine yönlendirilmiş
(mevcut *.hermes wildcard kaydı bunu zaten karşılar).Neden DNS-01? Let’s Encrypt normalde 80 (HTTP-01) veya 443 (TLS-ALPN-01) ister. Caddy’yi 9443 gibi özel bir porta aldığımız için, sertifikayı port gerektirmeyen DNS-01 yöntemiyle (Cloudflare API) alırız. Böylece VPS’teki mevcut Caddy (443) ile çakışmaz.
graph LR
M[Obsidian eklentisi<br/>masaüstü/mobil] -->|HTTPS :9443| C[Caddy<br/>DNS-01 TLS + rate_limit]
C -->|8090| P[PocketBase]
P --> V[(pb_data volume)]
CF[Cloudflare DNS] -.ACME DNS-01.-> C
# 1. Projeyi VPS'e kopyala (git clone veya scp). deploy/ klasörüne gir:
cd obsidian-pocketbase-sync/deploy
# 2. Ortam dosyasını hazırla
cp .env.example .env
nano .env # PB_DOMAIN, HTTPS_PORT (9443), CF_API_TOKEN değerlerini gir
# 3. Başlat (Caddy'yi rate-limit+DNS eklentileriyle derler, migration'lar dahil)
docker compose up -d --build
# 4. Superuser (admin) hesabı oluştur
docker compose exec pocketbase /pb/pocketbase superuser upsert "you@example.com" "<güçlü-şifre>"
UFW (myhermes-vps): Yeni portlar varsayılan olarak DENY. Mobilin internetten erişebilmesi için portu public aç:
sudo ufw allow 9443/tcp comment 'obsidian-sync public'
Caddy sertifikayı Cloudflare DNS-01 ile alır (~10-30 sn). Kontrol:
curl https://obsidian.hermes.bilalarikan.com:9443/api/health # {"message":"API is healthy."...}
Admin UI: https://obsidian.hermes.bilalarikan.com:9443/_/
Admin UI → users koleksiyonu → yeni kayıt (email + şifre). Veya API ile:
BASE=https://obsidian.hermes.bilalarikan.com:9443
TOKEN=$(curl -s -X POST $BASE/api/collections/_superusers/auth-with-password \
-H "Content-Type: application/json" \
-d '{"identity":"you@example.com","password":"<güçlü-şifre>"}' | jq -r .token)
curl -X POST $BASE/api/collections/users/records \
-H "Authorization: $TOKEN" -H "Content-Type: application/json" \
-d '{"email":"obsidian@local.sync","password":"<plugin-şifre>","passwordConfirm":"<plugin-şifre>","verified":true}'
| Ayar | Değer |
|---|---|
| Server URL | https://obsidian.hermes.bilalarikan.com:9443 |
| Email / Password | users koleksiyonundaki hesap |
| Vault ID | Tüm cihazlarda birebir aynı |
Eklenti 80/443’e bağlı değildir — verdiğin Server URL‘e (port dahil) bağlanır. Artık masaüstü + mobil + VPS aynı vault’u senkronize eder.
443 boş bir VPS’te:
.env‘deHTTPS_PORT=443yapıpCF_API_TOKEN‘ı boş bırakabilirsin; o zaman Caddyfile’dakitls { dns cloudflare ... }satırını silersen Caddy standart HTTP-01/TLS-ALPN-01 ile çalışır (Cloudflare gerekmez).
Alan adın yoksa veya yalnızca yerel ağ/VPN içindeyse:
docker compose -f docker-compose.simple.yml up -d --build
# erişim: http://<vps-ip>:8095
⚠️ Bu varyant şifreleri düz HTTP üzerinden taşır — yalnızca güvenilir ağlarda kullan.
graph LR
A[İstemci] -->|443| B[Caddy<br/>rate_limit 429]
B -->|8090| C[PocketBase<br/>yerleşik limiter 429]
D[fail2ban] -.izler.-> B
D -.banlar.-> E[(host firewall<br/>DOCKER-USER)]
Migration ile otomatik açılır (pb_migrations/1750000100_enable_rate_limits.js),
IP bazlı token-bucket:
| Kural | Limit | Amaç |
|---|---|---|
*:auth |
5 / 60 sn | Login brute force engeli |
*:create |
20 / 5 sn | Spam/kayıt taşması |
/api/batch |
3 / 1 sn | Toplu işlem istismarı |
/api/ |
300 / 10 sn | Genel API tavanı |
İstek PocketBase’e ulaşmadan, proxy seviyesinde kesilir
(mholt/caddy-ratelimit eklentisi, caddy/Dockerfile ile derlenir):
| Zone | Yol | Limit |
|---|---|---|
auth |
/api/collections/*/auth-with-password |
15 / 60 sn per IP |
api |
/api/* |
600 / 60 sn per IP (anti-flood) |
Caddy’nin JSON erişim logunu izler; auth endpoint’inde tekrarlayan 400/401/429
gören IP’yi host firewall’da banlar (deploy/fail2ban/):
caddy-auth — maxretry=10, findtime=10dk, bantime=1saDOCKER-USER (Caddy bridge container’da yayınlı port kullandığı için
ban INPUT‘a değil DOCKER-USER‘a yazılır — yoksa etkisiz olur)network_mode: host + NET_ADMIN (compose’da ayarlı)# fail2ban durumu ve banlı IP'ler
docker exec fail2ban fail2ban-client status caddy-auth
# Bir IP'yi elle ban kaldır
docker exec fail2ban fail2ban-client set caddy-auth unbanip 1.2.3.4
# Filtreyi örnek log'a karşı test et
docker exec fail2ban fail2ban-regex /var/log/caddy/access.log /data/filter.d/caddy-auth.conf
Not (Linux/VPS): fail2ban’in iptables ban’ı yalnız Linux host’ta etkilidir (Docker Desktop/Windows’ta firewall katmanı farklıdır). Limit/filtre mantığı her yerde aynı çalışır; gerçek ban enforcement VPS’te devreye girer.
docker compose logs -f pocketbase # loglar
docker compose pull && docker compose up -d --build # güncelle
docker compose down # durdur (veri pb_data volume'da kalır)
Tüm veri pb_data adlı Docker volume’unda (/pb/pb_data). Yedek:
docker run --rm -v deploy_pb_data:/data -v $(pwd):/backup alpine \
tar czf /backup/pb_data_$(date +%F).tar.gz -C /data .
.env içindeki PB_VERSION değerini değiştir, sonra:
docker compose up -d --build
Migration’lar serve sırasında otomatik uygulanır; veri korunur.