Déploiement
Ce qu’un déploiement sert
Section intitulée « Ce qu’un déploiement sert »Un projet Rebase se déploie comme un serveur à une URL (sur Rebase Cloud : https://<project>.rebase.website). Ce serveur gère :
/api/*— l’API de données, l’authentification, le temps réel et le stockage- tout le reste — votre
frontend/compilé en tant que SPA statique
Il n’y a pas d’URL d’administration séparée : le panneau d’administration fait partie de votre frontend, donc l’endroit où il apparaît dépend de ce qu’est votre frontend.
| Type de projet | L’URL racine affiche | Le panneau d’administration se trouve à |
|---|---|---|
Scaffold par défaut (rebase init) |
Le panneau d’administration | / — le frontend est l’administration |
| Frontend produit personnalisé | Votre app | Là où vous le montez, généralement /admin — voir Changer l’URL de base |
| Projet backend uniquement | Rien (API seulement) | Non déployé |
Docker Compose (Recommandé)
Section intitulée « Docker Compose (Recommandé) »Le projet généré inclut déjà un docker-compose.yml fonctionnel (Postgres + backend + frontend) ainsi que les Dockerfiles backend//frontend/ — ce fichier généré est la source de vérité ; utilisez-le tel quel plutôt que d’en écrire un à la main. Voici sa structure :
services: db: image: postgres:18-alpine environment: POSTGRES_USER: rebase_app POSTGRES_PASSWORD: ${DATABASE_PASSWORD:-changeme} POSTGRES_DB: rebase ports: - "5432:5432"
backend: build: # Context is the PROJECT ROOT so the image can copy # pnpm-workspace.yaml, backend/, and config/. A `./backend` # context would fail — the Dockerfile lives at backend/Dockerfile. context: . dockerfile: backend/Dockerfile ports: - "3001:3001" env_file: .env depends_on: - db
volumes: postgres_data: uploads:docker compose up -dCréer le schéma de base de données
Section intitulée « Créer le schéma de base de données »Démarrer la pile ne suffit pas à lui seul. Le backend démarre et
crée automatiquement les tables d’authentification, mais il ne crée pas les tables de
vos propres collections — vous exécutez cela une fois, explicitement, sur la base de
données de production. Depuis un checkout de votre projet (avec les dépendances installées), définissez
DATABASE_URL sur votre base de données de production et poussez le schéma :
pnpm run db:pushdb:push est l’option rapide — elle applique le schéma directement, sans
fichiers de migration. Pour un workflow versionné et en équipe, validez les fichiers de migration
avec pnpm run db:generate et exécutez pnpm run db:migrate comme étape de release
à la place. Quelle que soit l’option choisie, elle s’exécute sur le DATABASE_URL de production
depuis un checkout du projet (ou votre job CI), et non à l’intérieur du conteneur en cours d’exécution —
l’image de production est livrée sans la CLI.
Liste de contrôle pour la production
Section intitulée « Liste de contrôle pour la production »Avant de déployer en production, assurez-vous de :
| Élément | Détails |
|---|---|
| Schéma de base de données | Exécutez pnpm run db:push (ou pnpm run db:migrate pour des migrations versionnées) une fois sur la base de données de production. L’application démarre sans vos tables de collections, mais chaque collection échoue tant qu’elles n’existent pas. |
| JWT_SECRET | Utilisez une chaîne aléatoire cryptographiquement forte (≥ 32 caractères). Ne la réutilisez jamais entre environnements. |
| DATABASE_URL | Utilisez une instance Postgres gérée (Neon, Supabase, RDS) avec TLS activé |
| CORS | Configurez les origines autorisées sur votre backend si le frontend et le backend sont sur des domaines différents |
| Volumes de stockage | Montez des volumes persistants pour les téléversements de fichiers. Ou passez à S3 pour la production. |
| HTTPS | Terminez TLS au niveau de votre reverse proxy (nginx, Cloudflare, équilibreur de charge) |
| Inscription | Définissez ALLOW_REGISTRATION=false après avoir créé votre compte administrateur |
Servir le frontend
Section intitulée « Servir le frontend »En production, le backend peut servir le frontend en tant que SPA statique :
import { serveSPA } from "@rebasepro/server";import path from "path";
// After initializeRebaseBackend()serveSPA(app, { frontendPath: path.resolve(process.cwd(), "../frontend/dist") });Compilez d’abord le frontend :
cd frontend && pnpm buildDe cette façon, vous n’avez qu’à déployer un seul serveur qui gère à la fois la SPA et l’API.
Guides de déploiement par plateforme
Section intitulée « Guides de déploiement par plateforme »Guides détaillés étape par étape pour chaque plateforme :
| Plateforme | Type | Guide |
|---|---|---|
| AWS | App Runner / ECS + RDS | Déployer sur AWS → |
| Google Cloud | Cloud Run + Cloud SQL | Déployer sur GCP → |
| Azure | Container Apps + PostgreSQL | Déployer sur Azure → |
| Hetzner Cloud | VPS + Docker Compose | Déployer sur Hetzner → |
| Scaleway | Conteneurs serverless | Déployer sur Scaleway → |
| Railway | PaaS (détection auto du Dockerfile) | Déployer sur Railway → |
| Fly.io | Runtime de conteneurs | Déployer sur Fly.io → |
Changer l’URL de base
Section intitulée « Changer l’URL de base »Si vous voulez que Rebase s’exécute sur un sous-chemin (par ex. /admin) :
Frontend — Mettez à jour le basename de BrowserRouter :
<BrowserRouter basename="/admin"> <App /></BrowserRouter>Backend — Mettez à jour le chemin de base :
await initializeRebaseBackend({ // ... basePath: "/admin/api"});App produit + administration dans un seul déploiement
Section intitulée « App produit + administration dans un seul déploiement »La raison courante de déplacer l’administration vers /admin est de livrer votre propre app produit
à la racine du même déploiement. Un seul point d’entrée Vite peut servir les deux, séparés par URL,
de sorte que chaque app est chargée en lazy et que les visiteurs du produit ne téléchargent jamais le bundle d’administration :
const isAdmin = window.location.pathname.startsWith("/admin");
const ProductApp = lazy(() => import("./App"));const AdminApp = lazy(() => import("./AdminApp")); // renders <RebaseAdmin basePath="/admin" />
if (isAdmin) { // The admin uses useBlocker → needs a data router const router = createBrowserRouter([{ path: "/admin/*", element: <AdminApp /> }]); root.render(<RouterProvider router={router} />);} else { root.render(<BrowserRouter><ProductApp /></BrowserRouter>);}Le backend ne nécessite aucune modification pour ce modèle — l’API reste à /api et le catch-all de la SPA
sert index.html à la fois pour / et /admin/*.
Étapes suivantes
Section intitulée « Étapes suivantes »- Aperçu du backend — Configuration complète du backend
- Configuration du stockage — Configuration de S3 pour la production
