Héberger son propre serveur Firefox Sync
J'utilise Firefox Sync depuis des années pour retrouver mes marque-pages et mots de passe sur tous mes appareils. Ça marche bien. Mais récemment, je me suis demandé : est-ce que je peux héberger ça moi-même ?
Spoiler : oui. Mais j'ai passé une heure à debugger une erreur que la documentation ne mentionne nulle part.
Pourquoi faire ça ?
Honnêtement ? Surtout par curiosité. Mozilla chiffre déjà les données côté client, donc même eux ne peuvent pas les lire (source). L'auto-hébergement ne change pas grand-chose à la vie privée — vos données étaient déjà illisibles.
Mais ça fait un service de moins qui dépend d'un tiers. Et c'était un bon prétexte pour apprendre comment Firefox Sync fonctionne.
Ce qu'il faut savoir avant de commencer
Mozilla a open-sourcé le serveur sous le nom syncstorage-rs. C'est du Rust, ça supporte PostgreSQL, MySQL ou Spanner.
Le truc un peu décevant : l'authentification reste chez Mozilla. Vous avez toujours besoin d'un compte Firefox pour vous connecter. Impossible de créer des comptes locaux. Votre serveur stocke les données, mais Mozilla gère l'identité.
Firefox → accounts.firefox.com (Mozilla) → votre serveur
↑ auth ↑ stockage
Prérequis
- Un serveur avec Docker
- Un sous-domaine (par exemple
ffsync.votredomaine.org) - Un reverse proxy avec SSL (nginx-proxy dans mon cas)
- Un compte Firefox
Si vous partez de zéro, j'ai publié: docker-compose-homelab. C'est le setup que j'utilise au quotidien : nginx-proxy pour le SSL automatique, et une architecture où chaque service est dans son propre fichier YAML.
L'installation
DNS
Rien de spécial, un enregistrement A vers votre serveur :
sync.example.org A 1.2.3.4
Secrets
Générez trois secrets :
openssl rand -hex 32 # master secret
openssl rand -hex 32 # metrics secret
openssl rand -base64 24 # mot de passe postgres
Mettez-les dans .env :
SYNCSTORAGE_MASTER_SECRET=...
SYNCSTORAGE_METRICS_SECRET=...
SYNCSTORAGE_DB_USER=syncstorage
SYNCSTORAGE_DB_PASSWORD=...
Docker Compose
Voici le fichier complet. Un point important : l'image Docker mozilla/syncstorage-rs:latest ne marche pas avec PostgreSQL. Elle est compilée pour Spanner. Il faut utiliser une image avec le suffixe -postgres. J'ai perdu du temps là-dessus.
services:
syncstorage:
image: mozilla/syncstorage-rs:11659d98f9c69948a0aab353437ce2036c388711-postgres
container_name: syncstorage
environment:
- SYNC_HOST=0.0.0.0
- SYNC_MASTER_SECRET=${SYNCSTORAGE_MASTER_SECRET}
- SYNC_SYNCSTORAGE__DATABASE_URL=postgres://${SYNCSTORAGE_DB_USER}:${SYNCSTORAGE_DB_PASSWORD}@syncstorage-db:5432/syncstorage
- SYNC_SYNCSTORAGE__ENABLED=true
- SYNC_TOKENSERVER__DATABASE_URL=postgres://${SYNCSTORAGE_DB_USER}:${SYNCSTORAGE_DB_PASSWORD}@syncstorage-tokendb:5432/tokenserver
- SYNC_TOKENSERVER__ENABLED=true
- SYNC_TOKENSERVER__RUN_MIGRATIONS=true
- SYNC_TOKENSERVER__FXA_EMAIL_DOMAIN=api.accounts.firefox.com
- SYNC_TOKENSERVER__FXA_OAUTH_SERVER_URL=https://oauth.accounts.firefox.com
- SYNC_TOKENSERVER__FXA_METRICS_HASH_SECRET=${SYNCSTORAGE_METRICS_SECRET}
- VIRTUAL_HOST=sync.example.org
- VIRTUAL_PORT=8000
networks:
- proxy-tier
- syncstorage-internal
restart: unless-stopped
depends_on:
syncstorage-db:
condition: service_healthy
syncstorage-tokendb:
condition: service_healthy
syncstorage-db:
image: postgres:17-alpine
container_name: syncstorage-db
environment:
- POSTGRES_DB=syncstorage
- POSTGRES_USER=${SYNCSTORAGE_DB_USER}
- POSTGRES_PASSWORD=${SYNCSTORAGE_DB_PASSWORD}
volumes:
- /data/syncstorage/postgres-sync:/var/lib/postgresql/data
networks:
- syncstorage-internal
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${SYNCSTORAGE_DB_USER} -d syncstorage"]
interval: 10s
timeout: 5s
retries: 5
syncstorage-tokendb:
image: postgres:17-alpine
container_name: syncstorage-tokendb
environment:
- POSTGRES_DB=tokenserver
- POSTGRES_USER=${SYNCSTORAGE_DB_USER}
- POSTGRES_PASSWORD=${SYNCSTORAGE_DB_PASSWORD}
volumes:
- /data/syncstorage/postgres-token:/var/lib/postgresql/data
networks:
- syncstorage-internal
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${SYNCSTORAGE_DB_USER} -d tokenserver"]
interval: 10s
timeout: 5s
retries: 5
networks:
proxy-tier:
external: true
syncstorage-internal:
Créez les répertoires et lancez :
sudo mkdir -p /data/syncstorage/postgres-sync /data/syncstorage/postgres-token
sudo chown -R $(id -u):$(id -g) /data/syncstorage
docker compose -f docker-compose.yml -f syncstorage.yml up -d
L'étape que personne ne mentionne
Tout démarre, le healthcheck passe, le SSL fonctionne. Je configure Firefox, je me connecte et... erreur 503. Dans les logs Firefox (about:sync-log) :
"Unexpected error: unable to get a node"
J'ai cherché cette erreur pendant un moment. Le problème : le tokenserver a une table nodes qui liste les serveurs de stockage disponibles. Chez Mozilla, il y en a plusieurs pour la répartition de charge. Chez vous, il y en a un. Et il faut le déclarer manuellement.
docker exec syncstorage-tokendb psql -U syncstorage -d tokenserver -c \
"INSERT INTO nodes (service, node, available, current_load, capacity, downed, backoff) \
VALUES (1, 'https://sync.example.org', 1, 0, 1000000, 0, 0);"
Vérifiez :
docker exec syncstorage-tokendb psql -U syncstorage -d tokenserver -c "SELECT * FROM nodes;"
Après ça, tout fonctionne.
Configurer Firefox
Dans about:config, cherchez identity.sync.tokenserver.uri. Si ça n'existe pas, créez-le (clic droit → Nouveau → Chaîne). Valeur :
https://sync.example.org/1.0/sync/1.5
Redémarrez Firefox. C'est lu au démarrage, pas à chaud.
Si vous étiez déjà connecté avant de changer le tokenserver : déconnectez-vous, redémarrez, reconnectez-vous. Sinon Firefox continue d'utiliser l'ancien serveur en cache.
Vérifier que ça marche
Côté serveur, vous pouvez voir les données synchronisées :
docker exec syncstorage-db psql -U syncstorage -d syncstorage -c "
SELECT c.name as collection, COUNT(b.bso_id) as items
FROM bsos b
JOIN collections c ON b.collection_id = c.collection_id
GROUP BY c.name
ORDER BY items DESC;"
Chez moi après la première sync :
collection | items
-------------------+-------
bookmarks | 59
addons | 8
tabs | 2
clients | 2
Côté Firefox, about:sync-log doit montrer votre domaine, pas sync.services.mozilla.com.
Ce qui ne marche pas
Pas de migration. Les données qui étaient sur les serveurs Mozilla y restent. La première sync avec votre serveur part de zéro. Si vous avez des bookmarks sur deux machines avec des serveurs différents, vous aurez des fusions intéressantes.
Pas de comptes locaux. Vous dépendez toujours de Firefox Accounts pour l'authentification.
Conclusion
Ça marche. Mes deux Firefox (un Mac, un Linux) synchronisent via mon serveur. L'installation prend 20 minutes si vous connaissez l'astuce du node, une heure sinon.
Astuce: demandez à votre assistant IA de faire le job en mentionnant cette article !
Sources
- syncstorage-rs — le repo GitHub de Mozilla
- Documentation officielle
- Firefox Sync Privacy — comment le chiffrement fonctionne
- Images Docker — les tags disponibles
- docker-compose-homelab — La base de mon setup