Déployer sur Node.js

Sur cette page

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

  1. Construisez le projet :

    npm run build
  2. Démarrez le serveur :

    node ./dist/server/entry.mjs

    Définissez EMDASH_ENCRYPTION_KEY et 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 .env automatiquement. Pour un lancement local qui utilise le fichier .env généré, démarrez avec node --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.

VariableDescription
EMDASH_PREVIEW_SECRETOverride du secret HMAC d’aperçu auto-généré.
EMDASH_IP_SALTOverride du sel de hachage d’IP des commentateurs auto-généré.
EMDASH_AUTH_SECRETOptionnel. 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

VariableDescriptionExemple
DATABASE_PATHChemin vers la base SQLite/data/emdash.db
HOSTHôte du serveur0.0.0.0
PORTPort du serveur4321
S3_ENDPOINTURL de l’endpoint S3https://xxx.r2.cloudflarestorage.com
S3_BUCKETNom du bucket S3my-media-bucket
S3_ACCESS_KEY_IDClé d’accès S3AKIA...
S3_SECRET_ACCESS_KEYClé secrète S3...
S3_REGIONRégion S3auto
S3_PUBLIC_URLURL publique pour les médiashttps://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 :

  1. Demandez /health et une page de contenu publique. Les deux doivent renvoyer une réponse réussie.
  2. Exécutez npx emdash migrate --check depuis le projet construit. Il doit signaler aucune migration en attente ou inconnue pour la base configurée.
  3. Connectez-vous à /_emdash/admin, créez ou modifiez un brouillon jetable et publiez-le. Confirmez que la page publique montre le changement.
  4. Téléversez un fichier média jetable et ouvrez son URL renvoyée. Supprimez le fichier après vérification.
  5. 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.