Aller au contenu

Le faire tourner

Une application Next.js et une base Postgres.

Il n’existe pas de version hébergée : le faire tourner, c’est le faire tourner vous-même. C’est fait pour rester petit : rien à exploiter au-delà de ce qui tourne sur Vercel, ou un dossier et deux appels planifiés ailleurs.

Ce que ça coûte

Trailic n’a ni licence à payer, ni sièges, ni crédits. Vous payez ce que votre hébergeur et votre base vous facturent, et nous ne citons pas leurs tarifs ici parce qu’ils changent.

  • Sur le plan Hobby de Vercel, une tâche cron horaire ne se déploie pas : l’écriture horaire de vercel.json demande le plan Pro, ou un planning à vous.
  • Vercel Queues est disponible sur tous les plans, en bêta : la bêta est le risque, et un petit port dans le code est la réponse.
  • Un Postgres serverless se facture à l’heure d’éveil. Les événements l’atteignent par lots horaires et un tampon vide ne le réveille pas : il peut dormir entre-temps.

En local

Il vous faut Node 20 ou plus, pnpm et Postgres. Docker vous en donne un.

docker run -d --name trailic-db -e POSTGRES_PASSWORD=local -e POSTGRES_DB=trailic \
  -p 127.0.0.1:5432:5432 postgres:17-alpine
git clone https://github.com/trailic/trailic.git && cd trailic
pnpm install
cp .env.example .env.local   # then fill it in
pnpm db:migrate
pnpm dev

La connexion demande l’une des méthodes listées dans le README. Le plus rapide en local : TRAILIC_PASSWORD_SIGN_IN=true avec RESEND_API_KEY renseignée, et votre adresse dans TRAILIC_ADMINS. Les événements attendent que l’écriture passe, donc en local vous l’appelez vous-même :

curl -H "Authorization: Bearer $CRON_SECRET" http://localhost:3000/api/cron/flush

Sur Vercel

vercel.json le déploie avec ses fonctions à Francfort (fra1). Rien d’autre n’est nécessaire pour le tampon : Vercel Queues s’authentifie par le jeton du déploiement. Appliquez les migrations avec pnpm db:migrate avant de lancer une nouvelle version. La limite de débit de l’application compte par instance de serveur : pour une vraie limite contre un afflux, ajoutez une règle dans le pare-feu de Vercel.

Ailleurs

  • Réglez TRAILIC_BUFFER=file et pointez TRAILIC_BUFFER_DIR vers un disque qui dure, ou écrivez un autre tampon : c’est un petit port.
  • Appelez GET /api/cron/flush toutes les heures et GET /api/cron/retention tous les jours, avec Authorization: Bearer <CRON_SECRET>. Sans rien à faire, ils répondent sans toucher la base.
  • Ce que le collecteur et les tâches savent des sites est gardé avec le use cache: remote de Next. Sans gestionnaire de cache, cela vit dans la mémoire du serveur : très bien pour un seul serveur.
  • Placez-le derrière un proxy qui pose X-Real-IP ou X-Forwarded-For, et X-Vercel-IP-Country si vous voulez les pays. Sans proxy qui les écrase, n’importe qui peut prétendre à n’importe quelle adresse.

L’environnement à renseigner

TRAILIC_DATABASE_URL
Postgres. Le rôle doit pouvoir créer des tables : les événements bruts ont une nouvelle partition chaque mois.
BETTER_AUTH_SECRET
Au moins 32 caractères. Signe les sessions : le changer déconnecte tout le monde.
BETTER_AUTH_URL
L’adresse publique de l’instance. Les codes d’installation et les jetons des assistants en dépendent.
TRAILIC_SECRET
Au moins 32 caractères. Signe les clés des sites et dérive le sel de chaque jour.
TRAILIC_ADMINS
Les adresses qui peuvent s’inscrire et créer des espaces. Les autres rejoignent sur invitation.
CRON_SECRET
Le jeton avec lequel appeler les tâches. Sans lui, elles refusent tout le monde.

Et une façon de se connecter : le fournisseur OpenID Connect d’une société, Google, ou des mots de passe. Toutes les variables sont dans le README.

Ce qu’a mesuré le test de charge

Mesuré avec pnpm load-test sur Postgres 17 limité à un CPU et 4 Go : 5 millions d’événements synthétiques sur 120 jours et 30 sites, le plus gros avec un quart du trafic. Ce sont des événements synthétiques sur une machine, pas du vrai trafic, et vous pouvez lancer le même test.

Ce qu’a mesuré le test de chargeUn CPUUn quart de CPU
Écriture de 4 500 lots4 s36 s
Vue d’ensemble, plus gros site, 90 jours70 ms200 ms
Vue d’ensemble, tous les sites, 90 jours600 ms2,7 s
Funnel, trois étapes, plus gros site, 90 jours130 ms700 ms
Rétention, 13 semaines150 ms700 ms
Parcours depuis la première page du plus gros site, 90 jours3,5 s20 s

Les événements bruts ont pris 1,64 Go, environ 340 octets par événement, et les agrégats 139 Mo.