EmDash s’exécute sur Node.js 22.16 ou plus récent. Ce guide utilise SQLite et le stockage local pour un serveur. Utilisez PostgreSQL ou libSQL lorsque plusieurs instances ont besoin d’une base, et un stockage compatible S3 lorsque les médias doivent survivre indépendamment du disque du serveur.
Prérequis
- Node.js v22.16.0 ou supérieur
- Un hébergeur Node.js ou un VPS
Configurer le site
Configurez EmDash pour un déploiement Node.js :
import { defineConfig } from "astro/config";
import node from "@astrojs/node";
import emdash, { local, s3 } from "emdash/astro";
import { sqlite } from "emdash/db";
export default defineConfig({
output: "server",
adapter: node({ mode: "standalone" }),
integrations: [
emdash({
database: sqlite({ url: "file:./data/emdash.db" }),
storage: local({
directory: "./data/uploads",
baseUrl: "/_emdash/api/media/file",
}),
}),
],
});
Construire et démarrer
-
Construisez le projet :
npm run build -
Démarrez le serveur :
node ./dist/server/entry.mjsDéfinissez
EMDASH_ENCRYPTION_KEYet les autres identifiants runtime via l’environnement de processus de l’hébergeur avant de démarrer le serveur. L’entrée Node standalone ne charge pas.envautomatiquement. Pour un lancement local qui utilise le fichier.envgénéré, démarrez avecnode --env-file=.env ./dist/server/entry.mjs.
Le serveur s’exécute par défaut sur http://localhost:4321. Avec le mode de migration auto par défaut, la première requête applique les migrations core en attente. Une base neuve reçoit aussi le seed embarqué. Manage core database migrations explique comment migrer avant de rouvrir le trafic de production.
Tâches planifiées
Le planificateur intégré ne s’exécute que pendant qu’un processus Node.js tourne. Il gère la publication planifiée, les tâches de plugins et la maintenance générale.
Maintenez au moins un processus Node.js en continu en production. Les tâches planifiées s’interrompent lorsque chaque processus s’arrête ou dort.
Sandbox de plugins
Les plugins marketplace et ceux listés sous sandboxed: [] ont besoin d’un sandbox runner. Sous Node.js, le runner est @emdash-cms/sandbox-workerd, qui exécute les plugins dans un processus enfant workerd. Plugin Sandbox couvre l’installation, le fonctionnement du processus workerd et ses modes de défaillance.
Choisir les services de données de production
Utilisez le modèle suivant lorsque la base reste sur un volume persistant et que les médias passent à un stockage compatible S3 :
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
database: sqlite({ url: `file:${process.env.DATABASE_PATH}` }),
storage: s3(),
}),
],
});
Docker
Ajoutez un .dockerignore pour garder le contexte de build petit :
node_modules
dist
.git
Créez un Dockerfile :
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
RUN mkdir -p data
ENV HOST=0.0.0.0
ENV PORT=4321
EXPOSE 4321
CMD ["node", "./dist/server/entry.mjs"]
Le fichier seed est lu au moment du build et intégré au bundle, il n’a donc pas besoin d’être copié dans l’image runtime. Les migrations s’exécutent à la première requête après un déploiement ; le seed ne s’applique que lorsque la base n’a pas de collections et que la configuration n’est pas terminée — les données existantes ne sont jamais écrasées.
Construisez l’image et lancez le conteneur :
docker build -t my-emdash-site .
docker run -p 4321:4321 -v emdash-data:/app/data my-emdash-site
Un fichier Docker Compose gère le même conteneur avec un volume nommé :
services:
emdash:
build: .
ports:
- "4321:4321"
volumes:
- emdash-data:/app/data
restart: unless-stopped
volumes:
emdash-data:
Démarrez la pile en arrière-plan :
docker compose up -d
Environnement runtime
Lisez les identifiants de base et de stockage depuis l’environnement du processus au démarrage du serveur. Les variables suivantes prennent en charge la configuration ci-dessus :
Chiffrement des paramètres de plugins
EMDASH_ENCRYPTION_KEY chiffre les paramètres de plugins déclarés comme secrets. Une valeur malformée produit un message de démarrage destiné à l’opérateur, et les opérations sur les paramètres secrets de plugins échouent jusqu’à correction de la valeur.
Générez une valeur valide et ajoutez le résultat à l’environnement du processus serveur :
npx emdash secrets generate # add the result to your environment
La valeur est fournie par l’opérateur et n’est pas stockée en base. Conservez-la dans un gestionnaire de secrets et dans une sauvegarde de récupération séparée. Pendant la rotation, fournissez d’abord la nouvelle clé et conservez les anciennes après des virgules jusqu’à ce que chaque secret de plugin ait été réenregistré. EmDash ne signale pas actuellement quels ID de clé restent en usage ; suivez donc chaque identifiant réenregistré et vérifiez son intégration avant de retirer une ancienne clé. Restaurer la base sans une clé référencée laisse illisibles les paramètres correspondants.
Optionnel : overrides de valeurs stables
EmDash génère automatiquement le secret HMAC d’aperçu et le sel de hachage d’IP des commentateurs et les persiste en base à la première utilisation. Les variables d’environnement ci-dessous les fixent à une valeur que vous contrôlez — utile lorsqu’un processus séparé doit partager un secret avec votre site principal.
| Variable | Description |
|---|---|
EMDASH_PREVIEW_SECRET | Override du secret HMAC d’aperçu auto-généré. |
EMDASH_IP_SALT | Override du sel de hachage d’IP des commentateurs auto-généré. |
EMDASH_AUTH_SECRET | Optionnel. Si défini, utilisé comme source de sel d’IP (sauf si EMDASH_IP_SALT est aussi défini, auquel cas il a priorité), maintenant stables les hachages d’IP des commentateurs pour les installations qui s’y fient déjà. Laissez-le non défini pour un nouveau déploiement. |
Voir Secrets and key management pour le format de clé, chaque secret pris en charge et les effets de la rotation ou de la perte.
Base de données et stockage
| Variable | Description | Exemple |
|---|---|---|
DATABASE_PATH | Chemin vers la base SQLite | /data/emdash.db |
HOST | Hôte du serveur | 0.0.0.0 |
PORT | Port du serveur | 4321 |
S3_ENDPOINT | URL de l’endpoint S3 | https://xxx.r2.cloudflarestorage.com |
S3_BUCKET | Nom du bucket S3 | my-media-bucket |
S3_ACCESS_KEY_ID | Clé d’accès S3 | AKIA... |
S3_SECRET_ACCESS_KEY | Clé secrète S3 | ... |
S3_REGION | Région S3 | auto |
S3_PUBLIC_URL | URL publique pour les médias | https://cdn.example.com |
Stockage persistant
SQLite nécessite un stockage disque persistant. Assurez-vous que votre plateforme d’hébergement fournit :
- Un volume monté ou un disque persistant
- Un accès en écriture au répertoire de la base
- Des mécanismes de sauvegarde pour le fichier de base
Sauvegardez à la fois le fichier SQLite et le répertoire des uploads. Arrêtez le processus avant de remplacer l’un ou l’autre pendant la récupération. Voir Backups.
Contrôles de santé
Ajoutez un endpoint de health check pour les équilibreurs de charge :
export const GET = () => {
return new Response("OK", { status: 200 });
};
Cet endpoint prouve que le processus Node.js peut servir des routes Astro. Il ne prouve pas que la base, le backend de stockage, l’état des migrations ou le sandbox de plugins sont sains. Vérifiez ces dépendances séparément avant d’envoyer du trafic vers une nouvelle release.
Vérifier avant d’envoyer du trafic
Après avoir démarré un nouveau build, vérifiez les mêmes services runtime que les requêtes de production utilisent :
- Demandez
/healthet une page de contenu publique. Les deux doivent renvoyer une réponse réussie. - Exécutez
npx emdash migrate --checkdepuis le projet construit. Il doit signaler aucune migration en attente ou inconnue pour la base configurée. - Connectez-vous à
/_emdash/admin, créez ou modifiez un brouillon jetable et publiez-le. Confirmez que la page publique montre le changement. - Téléversez un fichier média jetable et ouvrez son URL renvoyée. Supprimez le fichier après vérification.
- Si le site utilise des plugins sandboxed, invoquez une route ou un hook de plugin et confirmez que le journal serveur n’a pas d’erreur sandbox-unavailable ni de démarrage
workerd.
Gardez la nouvelle instance hors de l’équilibreur de charge jusqu’à ce que chaque contrôle applicable réussisse.