Déployer sur Node.js

Sur cette page

EmDash fonctionne sur Node.js 22.16 ou ultérieur. Ce guide utilise SQLite avec un stockage local ou compatible S3 ; libSQL et PostgreSQL fonctionnent de la même manière sur Node.js — voir Options de base de données.

Prérequis

  • Node.js v22.16.0 ou supérieur
  • Un fournisseur d’hébergement Node.js ou VPS

Configuration

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",
			}),
		}),
	],
});

Compiler et exécuter

  1. Compiler le projet :

    npm run build
  2. Démarrer le serveur :

    node ./dist/server/entry.mjs

Le serveur tourne sur http://localhost:4321 par défaut. Les migrations sont appliquées à la première requête. Si la base de données est vide et que la configuration n’est pas terminée, votre fichier seed (ou le fichier par défaut intégré si vous n’en avez pas) est également appliqué à cette première requête.

Tâches planifiées

Le planificateur intégré ne fonctionne que tant qu’un processus Node.js est en cours d’exécution. Il gère la publication planifiée, les tâches de plugins et la maintenance générale.

Gardez au moins un processus Node.js en exécution continue en production. Les tâches planifiées se mettent en pause lorsque tous les processus s’arrêtent ou se mettent en veille.

Sandbox de plugins

Les plugins du marketplace et ceux listés sous sandboxed: [] nécessitent un runner de sandbox. Sur 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.

Stockage de production

Pour la production, utilisez un stockage compatible S3 au lieu du système de fichiers local :

import emdash, { s3 } from "emdash/astro";

export default defineConfig({
	integrations: [
		emdash({
			database: sqlite({ url: `file:${process.env.DATABASE_PATH}` }),
			storage: s3({
				endpoint: process.env.S3_ENDPOINT,
				bucket: process.env.S3_BUCKET,
				accessKeyId: process.env.S3_ACCESS_KEY_ID,
				secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
				publicUrl: process.env.S3_PUBLIC_URL, // URL CDN optionnelle
			}),
		}),
	],
});

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é dans le bundle, il n’a donc pas besoin d’être copié dans l’image de runtime. Les migrations s’exécutent à la première requête après un déploiement ; le seed est appliqué uniquement lorsque la base de données 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 stack en arrière-plan :

docker compose up -d

Variables d’environnement

Recommandé : clé de chiffrement

EMDASH_ENCRYPTION_KEY est la clé pour chiffrer les secrets des plugins au repos. La clé est validée au démarrage ; le chiffrement des secrets de plugins l’utilise une fois activé. Définissez-la à chaque déploiement pour que les secrets soient protégés sans changement de configuration ultérieur.

Générez une clé et ajoutez le résultat à votre environnement :

npx emdash secrets generate  # ajoutez le résultat à votre environnement

La clé est fournie par vous et jamais stockée dans la base de données ; seul le texte chiffré est stocké. Sauvegardez-la dans un endroit durable (un gestionnaire de mots de passe, KMS ou le stockage de secrets de votre équipe) — la perdre signifie perdre chaque secret chiffré avec elle.

Optionnel : overrides de valeur stable

EmDash auto-génère le secret HMAC de preview et le sel de hachage d’IP du commentateur et les persiste dans la base de données au premier usage. 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 pour le secret HMAC de preview auto-généré.
EMDASH_IP_SALTOverride pour le sel de hachage d’IP du commentateur auto-généré.
EMDASH_AUTH_SECRETOptionnel. Si défini, utilisé comme source du sel d’IP (sauf si EMDASH_IP_SALT est aussi défini, qui a priorité), gardant les hachages d’IP stables pour les installations qui en dépendent déjà. Laissez non défini pour un nouveau déploiement.

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 du 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_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 disque persistant
  • Un accès en écriture au répertoire de la base de données
  • Des mécanismes de sauvegarde pour le fichier de base de données

Vérifications de santé

Ajoutez un endpoint de vérification de santé pour les répartiteurs de charge :

export const GET = () => {
  return new Response("OK", { status: 200 });
};

Configurez votre plateforme pour vérifier /health pour les sondes de vivacité.