Déployer Ticketory
Mettez en ligne le site, le tableau de bord et l'API : Docker Compose sur un seul serveur, une application par hébergeur à partir de son Dockerfile, ou Node.js seul.
Pour le pack Full Stack
Trois façons de déployer
| Méthode | Idéal pour | Ce qu'il vous faut |
|---|---|---|
| Docker Compose sur un seul serveur | Un VPS que vous contrôlez, les trois applications ensemble | Le pack Full Stack, Docker sur le serveur, un reverse proxy pour le HTTPS |
| Une application par hébergeur, à partir de son Dockerfile | Railway, Render, Fly.io et les autres hébergeurs qui construisent depuis un Dockerfile | Le dossier de chaque application ; un volume ou MySQL et un bucket pour l'API |
| Node.js seul | N'importe quel hébergeur Node | Node.js 22 ou plus récent et Yarn 4 sur l'hôte |
Quelle que soit la méthode choisie, le site et le tableau de bord compilent l'adresse de l'API dans leur JavaScript quand ils sont construits : construisez-les donc avec les adresses publiques, jamais les adresses locales.
Docker Compose sur un seul serveur
Copiez le dossier du pack sur le serveur et placez un .env à côté de docker-compose.yml avec les trois adresses publiques. Les origines autorisées de l'API, les adresses vers lesquelles les pages de paiement renvoient les acheteurs, les liens de téléchargement des billets, les adresses des images et l'adresse d'API des frontends en sont toutes construites. REVALIDATE_SECRET remplace la valeur locale par défaut que le site et l'API partagent pour actualiser aussitôt les pages d'événement.
SITE_URL=https://www.your-domain.com
ADMIN_URL=https://dashboard.your-domain.com
API_URL=https://api.your-domain.com
MEDIA_HOSTNAME=api.your-domain.com
REVALIDATE_SECRET=a-long-random-stringMEDIA_HOSTNAME est optionnel, un hôte ou plusieurs séparés par des virgules (ajoutez l'hôte de votre bucket quand les fichiers envoyés vont dans un bucket) : les images de ces hôtes https sont redimensionnées par Next.js, et toute autre image se charge telle quelle. Puis construisez et démarrez en arrière-plan :
docker compose up --build -d- Faites pointer chaque domaine vers le serveur via un reverse proxy qui sert le HTTPS (Caddy, Nginx ou Traefik), en redirigeant vers les ports
3030,3031et8000. - Derrière ce proxy, définissez
TRUST_PROXY=1dansback-end/.env, pour que les limites de connexion, du formulaire de contact et du scan à l'entrée comptent chaque visiteur plutôt que le proxy. Le conteneur de l'API litback-end/.envs'il existe, c'est aussi là que vont les clés de paiement, d'e-mail, d'IA et de stockage. - Sans
JWT_SECRETà vous, l'API en génère un à son premier démarrage et le garde dans le volumeticketory-data. La base, les fichiers envoyés et les exports CSV se trouvent aussi dans ce volume : sauvegardez-le. - Le premier démarrage sur un nouveau volume remplit la base avec les organisateurs d'exemple, sauf si
SEED_DEMO_DATA=falsefigure dans le.env. Pour vos propres événements, démarrez sans eux et avec votre propre propriétaire, comme dans Mise en ligne avec votre propre espace de travail plus bas.
L'API à partir de son Dockerfile
Pointez l'hébergeur vers le dossier de l'API (back-end/ dans le Full Stack). L'image écoute sur PORT (8000 sauf si l'hébergeur en impose un autre), répond à GET /api/health dès que sa base répond, et garde SQLite, les fichiers envoyés et les exports CSV dans /data.
- Montez un volume persistant sur
/data. Sans volume, chaque déploiement repart d'une base vide. - Définissez
CORS_ORIGINavec les adresses du site et du tableau de bord (séparées par une virgule),FRONTEND_URLavec celle du tableau de bord,STOREFRONT_URLavec celle du site,PUBLIC_API_URLavec l'adresse publique de l'API etPUBLIC_MEDIA_URLavec cette adresse suivie de/media. - Par défaut, l'image a
SEED_DEMO_DATA=false: un nouveau volume reçoit seulement les tables, puis le premier démarrage de l'API crée votre espace de travail et son propriétaire à partir deOWNER_EMAILetOWNER_PASSWORD(voir plus bas). Définissez plutôtSEED_DEMO_DATA=truepour avoir les organisateurs d'exemple. Une base existante n'est jamais remplie une seconde fois. - Définissez votre propre
JWT_SECRET, ou laissez le conteneur en générer un et le garder dans/data/.jwt-secret. - Définissez
TRUST_PROXY=1: une plateforme d'hébergement place un proxy devant le conteneur. - Sur MySQL (
DB_TYPE=mysqlet les cinq variablesDB_*), le conteneur ne crée pas les tables. Lancez une foisnode dist/database/seeder.js(données d'exemple) ounode dist/database/sync-schema.js(tables vides) avec le même environnement. - Les fichiers téléversés sur le volume survivent à un redéploiement ; pour ne pas les garder sur le serveur, définissez les cinq variables
R2_*pour un bucket. - Définissez
REVALIDATE_SECRETavec la même longue valeur aléatoire sur l'API et sur le site, etSTOREFRONT_INTERNAL_URLquand l'API joint le site à une autre adresse queSTOREFRONT_URL.
Le site et le tableau de bord à partir de leurs Dockerfiles
Faites pointer l'hébergeur vers le dossier de l'application et donnez-lui les valeurs NEXT_PUBLIC_* comme arguments de build, non comme variables d'exécution : elles sont compilées. Chaque image sert le serveur autonome de Next.js sur PORT (3030 pour le site, 3031 pour le tableau de bord, sauf si l'hébergeur en impose un autre).
| Argument de build | Application | Valeur |
|---|---|---|
NEXT_PUBLIC_API_BASE_URL | Les deux | L'adresse publique de l'API suivie de /api |
NEXT_PUBLIC_SITE_URL | Les deux | L'adresse publique du site : les URL canoniques et le sitemap du site, le lien « View website » et les aperçus d'événement du tableau de bord |
NEXT_PUBLIC_DASHBOARD_URL | Les deux | L'adresse publique du tableau de bord : l'endroit où le « Sell tickets » du site envoie les organisateurs, et l'image de partage du tableau de bord lui-même |
NEXT_PUBLIC_MEDIA_HOSTNAME | Les deux | Optionnel. Les hôtes https qui servent les images (le domaine de l'API, celui de votre bucket, ou les deux), séparés par des virgules |
NEXT_PUBLIC_WEBSOCKET_BASE_URL | Tableau de bord | L'adresse publique de l'API sans /api, pour les notifications en direct |
Le serveur du site interroge aussi l'API quand il génère les pages d'événement, de lieu et d'organisateur et le sitemap. Avec une adresse d'API publique, cela fonctionne aussi depuis le serveur, et rien de plus n'est nécessaire ; API_INTERNAL_URL à l'exécution la remplace quand le serveur doit utiliser une autre adresse. REVALIDATE_SECRET est aussi une variable d'exécution du site, jamais un argument de build.
Node.js seul
Construisez chaque application une fois sur l'hôte, puis démarrez-la. Réglez le .env des frontends sur les adresses publiques avant yarn build.
| Application | Build | Démarrage |
|---|---|---|
| API | yarn build, puis une fois yarn seed:prod (données d'exemple) ou yarn db:sync:prod (tables vides) | yarn start:prod |
| Site public | yarn build | yarn start (port 3030) |
| Tableau de bord organisateur | yarn build | yarn start (port 3031) |
L'API écoute sur 0.0.0.0 et lit PORT. Gardez le fichier SQLite et MEDIA_UPLOAD_DIR sur un stockage qui survit à un déploiement, ou utilisez MySQL et un bucket.
Mise en ligne avec votre propre espace de travail
Les organisateurs d'exemple et leurs identifiants servent à essayer Ticketory. Pour vos propres événements, partez d'une nouvelle base sans eux : sur une base sans compte d'équipe ni espace de travail, le premier démarrage de l'API crée les données de base (les 29 permissions, les quatre rôles, les paramètres du site et les trois catégories d'événements), un espace de travail vide et son propriétaire.
Définir les variables du propriétaire
Dans
back-end/.env, ou dans la configuration de votre hébergeur pour l'API. Avec Docker Compose, placez-les dans le.envà côté dedocker-compose.yml, avecSEED_DEMO_DATA=false: Compose lit ce fichier en premier puisback-end/.env, dont la valeur l'emporte quand les deux en définissent une.back-end/.envOWNER_EMAIL=you@your-domain.com OWNER_PASSWORD=a-long-password-of-your-own OWNER_NAME=Your Name WORKSPACE_NAME=Your organisationRésultat attendu:
OWNER_NAMEetWORKSPACE_NAMEsont optionnels (OwneretTicketorys'ils ne sont pas définis), et les deux peuvent être changés plus tard, dans votre profil et sous Paramètres, Général. Le mot de passe doit faire au moins 10 caractères, et avecNODE_ENV=production, la valeur d'exemple de.env.exampleet le mot de passe des comptes d'exemple sont refusés.Démarrer sans les données d'exemple, sur une nouvelle base
Sans Docker, dans le dossier de l'API :
yarn build, puisyarn db:sync:prod(pasyarn seed), puisyarn start:prod. Avec Docker Compose, gardezSEED_DEMO_DATA=falsedans le.envà côté dedocker-compose.ymlet lancezdocker compose up --build -dsur un nouveau volume (docker compose down -vsupprime un volume existant, avec toutes ses données). Un conteneur d'API seul démarre sans-e SEED_DEMO_DATA=true, avec les variables passées par--env-file .envou-e.Résultat attendu: Le journal de l'API affiche
Un problème ?Clean start: created the workspace "Your organisation" and its Owner, avec l'e-mail.Connectez-vous et configurez l'espace de travail
Connectez-vous au tableau de bord avec
OWNER_EMAILetOWNER_PASSWORD. L'espace de travail est vide : ajoutez un lieu, puis votre premier événement. Sa devise est l'USD tant que vous ne la changez pas sous Paramètres, Général, ce que vous pouvez faire jusqu'au paiement du premier billet. Invitez ensuite votre équipe depuis la page Équipe, chacun avec le rôle dont il a besoin.
- Cela n'arrive qu'une fois. Dès qu'un compte d'équipe existe, les variables du propriétaire sont ignorées : un redémarrage ou une seconde copie de l'API ne crée donc rien de plus, et vous pouvez ensuite retirer
OWNER_PASSWORDde la configuration. Le mot de passe n'est jamais affiché. yarn seedet une base remplie avec les données d'exemple ne les lisent jamais : une telle base a déjà son équipe.- Le tableau de bord n'a pas de page d'inscription. Chaque autre compte d'équipe s'ajoute avec Invite member sur la page Équipe, avec un rôle et un mot de passe que vous communiquez vous-même (rien n'est envoyé par e-mail).
Partir plutôt des données d'exemple
Une base remplie avec les données d'exemple garde ses quatre organisateurs et leurs comptes. Si vous partez de là, faites-la vôtre avant qu'elle soit accessible depuis Internet :
- Faites vôtre le propriétaire d'exemple : changez son nom et son e-mail sous Paramètres, Profil, et son mot de passe sous Paramètres, Sécurité. C'est le seul compte qui appartient à tous les espaces de travail d'exemple, et aucun écran n'ajoute un membre existant à un autre espace de travail : gardez-le donc plutôt que de le remplacer par un nouveau compte.
- Retirez les membres d'exemple dont vous n'avez pas besoin depuis la page Équipe de chaque espace de travail, ou changez leurs mots de passe. Remove retire un membre de l'espace de travail où vous êtes ; le compte est supprimé avec son dernier espace de travail. Vous ne pouvez pas vous retirer vous-même, et chaque espace de travail garde un propriétaire.
- Définissez le nom de l'espace de travail, l'e-mail de support, la devise, les frais de réservation, le fuseau horaire et les notifications de l'équipe sous Paramètres, Général et Notifications. La devise se verrouille dès que la première commande payée est prise.
- Archivez ou annulez les événements d'exemple et remplacez les lieux d'exemple par les vôtres, avec leurs plans de salle. Il n'existe ni écran ni route pour créer un autre espace de travail : renommez-en donc un sous Paramètres, Général pour votre propre activité.
- Les participants créent leur propre compte sur le site, ou achètent en invités. Le participant d'exemple fait partie des données d'exemple : supprimez-le avec le reste.
Mettre à jour une installation qui tourne déjà
Avec NODE_ENV=production, l'API ne modifie jamais les tables elle-même. Après une mise à jour qui ajoute une colonne ou une table, synchronisez le schéma une fois sur la base existante, avant de démarrer la nouvelle version. Celle-ci ajoute la colonne locale sur orders (la langue des e-mails de chaque commande) et la table event_reminders.
Sans Docker, dans le dossier de l'API :
yarn build
yarn db:sync:prodCela n'écrit aucune ligne et garde vos données. Avec Docker, le conteneur laisse une base existante tranquille : après docker compose up --build -d, lancez le même script une fois dans le conteneur d'API en marche, puis redémarrez-le (pour un conteneur d'API seul, docker exec -u node <container> node dist/database/sync-schema.js, puis docker restart <container>) :
docker compose exec -u node api node dist/database/sync-schema.js
docker compose restart apiAvec NODE_ENV=development, comme avec yarn dev, l'API met à jour les tables d'elle-même au démarrage.
Mise en ligne
Avant que Ticketory soit accessible depuis Internet :
- Dans l'environnement de l'API,
NODE_ENV=productionet unJWT_SECRETlong et aléatoire à vous (Docker en génère un quand aucun n'est défini). En production, l'API refuse de démarrer sansCORS_ORIGINet indique quelle valeur manque. CORS_ORIGINvers le site et le tableau de bord,FRONTEND_URLvers le tableau de bord,STOREFRONT_URLvers le site,PUBLIC_API_URLvers l'API etPUBLIC_MEDIA_URLvers l'API suivie de/media.TICKET_SECRETdéfini une fois, avant la première vente : il signe les codes QR, et le changer plus tard invalide tous les billets déjà vendus.- Vos clés Stripe ou PayPal de production, et les webhooks enregistrés chez chaque fournisseur sur
/api/webhooks/stripeet/api/webhooks/paypalà l'adresse de l'API. Quand une clé de production est définie, Test payment disparaît du paiement. - La fiscalité configurée pour votre pays : Ticketory n'en applique aucune lui-même.
RESEND_API_KEYetMAIL_FROM, sinon les participants ne reçoivent ni e-mails de billets, ni codes d'inscription, ni réinitialisations de mot de passe.- La base, les fichiers envoyés et les exports CSV sur un stockage persistant, avec une sauvegarde.
- La vérification de santé de l'hébergeur sur
/api/health, etTRUST_PROXY=1derrière un proxy. - Les deux frontends construits avec les valeurs publiques
NEXT_PUBLIC_*, et le mêmeREVALIDATE_SECRETsur l'API et sur le site. - Sur le site, votre marque dans
src/config/brand.config.ts, et les textes de confidentialité, de conditions et d'annulation dansmessages/legalréécrits pour votre activité et votre pays. - Votre propre espace de travail depuis un démarrage propre, ou les mots de passe d'exemple changés et les comptes d'exemple inutiles retirés.
DEMO_MODE=falsesur l'API etNEXT_PUBLIC_DEMO_MODE=falsedans les deux frontends, comme livré.
Pas pour des données de vente réelles
yarn setup:fresh construit, supprime chaque table et alimente la base, à chaque exécution, et yarn db:reset supprime chaque table. Ils conviennent à un environnement tout neuf, jamais à une commande de démarrage ou de build.