Alternativa Google Contacts 
=====================
Aceasta solutie prezinta o alternativa la google contacts. Pe propriul server instalati o aplicatie la care se conecteaza telefonul si va hosteaza numerele de telefon din agenda.
Configurarea serverului
In locatia unde instalezi aplicatia(cu docker) trebuie sa ai ip public si un DNS. Ex: example.com
Trebuie sa creati in zona DNS o inregistrare catre IP public cum aveti, sa zicem 11.22.33.44:
A contacts.example.com 11.22.33.44 #DNS pt management web
Aplicatia se numeste Baikal si se pune intr-un folder, de ex /root/contacts:
Se creeaza reteaua docker mai intai pt varianta in care aceasta aplicatie va folosi mysql:
docker network create --driver=bridge --subnet=172.19.10.0/24 marianet
Pe acelasi server asa cum am mai explicat si
aici se creeaza fisierul care va porni containerul:
Deci acesta este start.sh care va porni containerul baikal care depinde de mysql. Vedeti la linkul de mai sus cu bitwarden cum se configureaza containerul mysql si cum se porneste!.
Se poate folosi fara mysql insa e mai safe asa intrucat se poate face un mysqldump, probabilitatea sa pierdeti tot devine nula
Daca se strica ceva pur si simplu importati in mysql un backup.sql si totul revine la normal.
Userul si parola mysql sunt deja setate. Pt acces in consola mysql:
$ docker exec -it mysql57 mysql -u root -p
mysql> CREATE DATABASE baikal CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
mysql> CREATE USER 'baikal_user'@'%' IDENTIFIED BY 'parola_baikal';
mysql> GRANT ALL PRIVILEGES ON baikal.* TO 'baikal_user'@'%';
mysql> FLUSH PRIVILEGES;
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| vaultwarden |
| baikal |
+--------------------+
mysql> exit;
Acum ca baza de date si drepturile aferente sunt deja rezolvate, revenim la containerul baikal:
pwd - /root/contacts #(aici facem cele 2 subfoldere:)
mkdir config
mkdir Specific
Dupa ce am facut folderele astea putem porni containerul cu ./start.sh. Evident trebuie sa fie si executabil deci in prealabil trebuie si chmod +x start.sh
Dupa ce se porneste containerul se verifica cu docker logs baikal ca sa ne asiguram ca este functional.
Pt acces securizat avem nevoie si de un reverse proxy nginx unde trebuie sa avem certificat LetsEncrypt.
Am explicat de mai multe ori cum se poate seta un nginx, aici voi atasa doar continutul vhost-ului:
Deci se (re)porneste nginx cu acest vhost in plus si se verifica daca functioneaza corect.
Daca nu s-a pornit intre timp baikal, se porneste si la fel, trebuie sa ne asiguram ca toate sunt pornite si merg: nginx, baikal, mysql.
Daca totul functioneaza corect se deschide in browser interfata web pentru configurare initiala: https://contacts.example.com/admin/
Acolo vei vedea pagina de setup initiala unde baikal te va pune sa:
- Configurezi un user si o parola pentru administrator
- Alegi tipul de baza de date (care deja va fi MySQL, fiind definit in docker run si completezi exact ip host samd ca in docker run)
Dupa setup-ul initial, te loghezi in admin si adaugi un utilizator nou, care va fi folosit pentru sincronizarea contactelor(de ex gigel).
In momentul asta este totul configurat pe partea de server insa va trebui sa importam contactele (one time only operation):
Accesam in browser google contacts si exportam toate contactele ca fisier .vcf.
Instaleaza Thunderbird pe PC si deschide-l.
Creezi un adressbook nou (myserver) cu user si pass gigel/parola cu URL: https://contacts.example.com/card.php/addressbooks/gigel/default/
import de jos importa Selecteaza fisierul .vcf. si in lista alegi myserver si apoi butonul de submit, ce o scrie pe el...si dupa import url-ul se schimba, in loc de default va avea un UUID:
se poate verifica in browser dupa import si va arata ceva de genul:
https://contacts.example.com/card.php/addressbooks/gigel/40d0a148-cca2-5a1e-8c21-d43c2e91b8e3/
Aici veti observa ca fiecare contact a fost importat ca .vcf separat, asa functioneaza. Puteti verifica cateva prin sondaj sa fiti sigur ca importul s-a efectuat cu succes.
In momentul asta thunderbird se poate dezinstala. Exista metode direct pe server sa faceti importul dar e putina bataie de cap, e mai simplu cu thunderbird.
Configuratie clusterizata
Se va folosi scenariul de
aici unde se folosesc 3 noduri legate intre ele prin tunele wireguard (VPS, nod1 si nod2) unde exista si un VIP care primary sta pe nod1.
De asemeni nu vom mai folosi mysql 5.7 ci galera cluster explicata in detaliu pe aceeasi pagina.
A record-ul DNS-ului va fi IP-ul VPS-ului unde exista oricum un haproxy si acolo o sa mai adaugam un entry care va pointa prin tunelul wg catre nod1 (10.0.6.2):
frontend vps2_contacts
bind *:8445
mode http
default_backend vip_backend
backend vip_backend
mode http
server vip 10.0.6.10:443 check ssl verify none
Aplicatia asta este foarte ciudata, nu am reusit sa pun nginx pe VPS si sa fac acolo SSL termination pt ca pe nodul unde ruleaza baikal, e facuta de asa natura imaginea cu apache, php si aplicatia in sine
incat necesita 3 blocuri diferite in nginx: /, /admin si /card.php. Asa ca trebuie un server pus in fata sa asculte pe 443 si de acolo rp in nginx nod1.
Cum pe VPS nu mai pot folosi 443, am facut un tunel Zero trust la Clodflare cu public domain setat sa bata in LAN IP VPS:8445 (vedeti listen 8445 la haproxy). E un caz particular, asa l-am facut sa mearga.
Asadar cand scrieti in browser https://contacts.example.com, aveti tunel cloudflare->VPS, acolo haproxy care bate prin Wg pana la VIP nginx nod1 (care VIP in caz de avarie se muta) unde aveti de fapt certificatul LetsEncrypt cu cele 3 blocuri, numai asa am reusit sa il pacalesc...
nginx ramane identic pe nod1 si 2 si trebuie sa schimbati configul baikal care acum va folosi galera. Primul pas este sa exportati DB baikal din mysql 57, apoi in consola galera creati DB baikal goala, drepturi samd identic cum este explicat aici mai sus, galera foloseste mariadb care e 99% identic cu mysql deci faceti docker exec si folositi EXACT aceleasi comenzi pt DB, user, drepturi.
Ulterior tot din containerul galera importati fisierul sql in DB baikal exportat mai devreme, nu mai explic cum se face, e banal.
Din pacate containerul baikal nu se mai poate folosi pt ca ai nevoie ca baikal si galera sa functioneze pe aceeasi retea. In cazul explicat mai sus, asa merg lucrurile cu mysql57 pe reteaua marianet insa cu galera am avut foarte mari batai de cap cand am facut bitwarden si nu am reusit sa il fac sa functioneze decat cu network host. In condiile astea, si baikal de data asta va trebui pornit tot cu network host insa el e gandit din imagine sa ruleze pe 80, ori eu porneam baikal pe 5232 si nu mai ai cum sa il pacalesti. Daca reusiti sa porniti galera pe un docker network dedicat asa cum am prezentat aici mai sus cum pornea pe marianet cu mysql57, nu mai e nevoie sa faceti ce explic dedesubt, adica cum fac o imagine docker baikal custom care porneste default pe 5232 (network host).
Deci pt imaginea custom avem nevoie de Dockerfile si un fisier custom-entrypoint.sh:
Facem build la imagine
docker build -t baikal:custom .
In start.sh cu care pornim baikal trebuie urmatoarele modificari:
- network host in loc de --network=marianet
- IMAGE="baikal:custom" in loc de "ckulka/baikal"
- p $HOST_PORT:80 \ se scoate de tot pt ca pleaca implicit pe 5232
Ma repet, daca reusiti sa porniti galera si baikal pe o retea separata asa cum am facut sus cu mysql5.7, nu mai sunt necesare modificarile astea.
Testati si daca merge ok pe nod1 unde e VIP, copiati absolut toata configuratia in oglinda si pe nod2 dupa care testati failover sa se mute VIP pe nod2.
Ultima mentiune: fisierul baikal.yaml din folderul config ar trebui sa fie pe un shared storage cum am facut la bitwarden insa pt un singur fisier nu merita. Singurul scenariu unde creaza probleme este cand schimbati parola admin pe nod1 care din pacate sta in acel fisier si nu in DB, restul userilor sunt complet in DB, o idiotenie. La failover, fisierul pe nod2 nu mai e la fel si nu merge login, logic.
Nu merita NFS doar pt un singur fisier, exista n solutii sa il sincronizati automat, exemplu cu systemd cu watch cum am facut
aici de ex. Dar cine schimba parola la admin? Puneti de la bun inceput o parola strong si aia e! Nu prea merita efortul...
Configurarea clientilor (telefoanele mobile)
Se instaleaza pe telefon https://github.com/bitfireAT/davx5-ose/releases/download/v4.4.8-ose/davx5-ose-4.4.8-ose-release.apk
Adaugi un cont CardDAV in davx5 cu:
URL: https://contacts.example.com/card.php/principals/gigel/
User: gigel
Parola: parola
next prima optiune->next a doua optiune (contacte separate) si gata, ai adaugat contul pe care il verifici si observi ca url-ul este:
https://contacts.example.com/card.php/addressbooks/gigel/40d0a148-cca2-5a1e-8c21-d43c2e91b8e3.
Se da sync manual si apoi se verifica ora la care s-a facut syncul dupa care deschizi google contacts si vezi cum iti aduce contactele....
Cel mai bine e ca in momentul in care ajungi aici, contactele din google sa fie deja sterse.
In setarile aplicatiei se poate vedea ca face sync la 4 ore sau cand ai editat un contact. se poate cobora intervalul.
Exita o setare cand porneste aplicatia (Regular sync intervals) care ii da allow for run in the background dar nu am activat-o pe principiul ca poate consuma prea mult. O sa testez.
Pe orice telefon e bine sa ai aplicatia google contacts care vede automat davx5 si dai sa afiseze doar contactele respective. Am testat, merge si cu Samsung Contacts.
Cam asta e tot, acum aplicatia de contacte de pe telefon foloseste davx5 si nu mai ai nicio legatura cu Google Contacts!
Eu am 2 telefoane in care sunt conectat cu 2 conturi google diferite si cum editez pe un telefon un contact, apare si pe al doilea cu mentiunea ca trebuie sa fi facut sync.
Am scris mai sus, poti sa il lasi sa faca permanent dar nu merita, posibil sa manance baterie inutil.
O mica mentiune, se poate pune si poza la contact, pozele sunt stocate in mysql cu base64!
Enjoy!
Last update 17 Jul 2025.