Desplegar en Node.js

En esta página

EmDash se ejecuta en Node.js 22.16 o superior. Esta guía utiliza SQLite y almacenamiento local para un servidor. Use PostgreSQL o libSQL cuando varias instancias necesiten una base de datos, y almacenamiento compatible con S3 cuando los medios deban sobrevivir independientemente del disco del servidor.

Requisitos previos

  • Node.js v22.16.0 o superior
  • Un proveedor de hosting Node.js o VPS

Configurar el sitio

Configure EmDash para el despliegue en 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",
			}),
		}),
	],
});

Compilar y ejecutar

  1. Compilar el proyecto:

    npm run build
  2. Iniciar el servidor:

    node ./dist/server/entry.mjs

El servidor se ejecuta en http://localhost:4321 por defecto. Con el modo de migración predeterminado auto, la primera solicitud aplica las migraciones core pendientes. Una base de datos nueva también recibe el seed incorporado. Gestionar migraciones de base de datos core explica cómo migrar antes de reiniciar el tráfico de producción.

Tareas programadas

El programador integrado solo se ejecuta mientras un proceso Node.js está activo. Maneja publicaciones programadas, tareas de plugins y mantenimiento general.

Mantenga al menos un proceso Node.js ejecutándose continuamente en producción. Las tareas programadas se pausan cuando todos los procesos se detienen o entran en suspensión.

Sandbox de plugins

Los plugins del marketplace y los listados bajo sandboxed: [] necesitan un ejecutor de sandbox. En Node.js, el ejecutor es @emdash-cms/sandbox-workerd, que ejecuta plugins en un proceso hijo workerd. Sandbox de plugins cubre la instalación, cómo se ejecuta el proceso workerd y sus modos de fallo.

Elegir servicios de datos de producción

Use el siguiente patrón cuando la base de datos permanece en un volumen persistente y los medios se mueven a almacenamiento compatible con S3:

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

export default defineConfig({
	integrations: [
			emdash({
				database: sqlite({ url: `file:${process.env.DATABASE_PATH}` }),
				storage: s3(),
		}),
	],
});

Docker

Agregue un .dockerignore para mantener el contexto de compilación pequeño:

node_modules
dist
.git

Cree 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"]

El archivo seed se lee en tiempo de compilación y se integra en el bundle, por lo que no necesita copiarse en la imagen de runtime. Las migraciones se ejecutan en la primera solicitud después de un despliegue; el seed solo se aplica cuando la base de datos no tiene colecciones y la configuración no se ha completado — los datos existentes nunca se sobrescriben.

Compile la imagen y ejecute el contenedor:

docker build -t my-emdash-site .
docker run -p 4321:4321 -v emdash-data:/app/data my-emdash-site

Un archivo Docker Compose gestiona el mismo contenedor con un volumen nombrado:

services:
  emdash:
    build: .
    ports:
      - "4321:4321"
    volumes:
      - emdash-data:/app/data
    restart: unless-stopped

volumes:
  emdash-data:

Inicie el stack en segundo plano:

docker compose up -d

Entorno de ejecución

Lea las credenciales de base de datos y almacenamiento del entorno del proceso cuando el servidor inicie. Las siguientes variables soportan la configuración anterior:

Validación de clave de cifrado

EMDASH_ENCRYPTION_KEY actualmente no cifra secretos de plugins ni otros datos almacenados. Si la variable está establecida, EmDash verifica su formato durante el inicio, pero los valores de secretos de plugins permanecen en texto plano en la base de datos.

Si establece la variable, genere un valor válido y agregue el resultado a su entorno:

npx emdash secrets generate  # agregar el resultado a su entorno

El valor es proporcionado por el operador y no se almacena en la base de datos. Perderlo no tiene impacto en la recuperación de datos porque ningún dato almacenado depende de él. Trate la base de datos y sus copias de seguridad como sensibles porque contienen secretos de plugins en texto plano.

Opcional: sobreescrituras de valores estables

EmDash genera automáticamente el secreto HMAC de vista previa y la sal de hash de IP del comentarista y los persiste en la base de datos en el primer uso. Las variables de entorno a continuación los fijan a un valor que usted controla — útil cuando un proceso separado necesita compartir un secreto con su sitio principal.

VariableDescripción
EMDASH_PREVIEW_SECRETSobreescritura del secreto HMAC de vista previa generado automáticamente.
EMDASH_IP_SALTSobreescritura de la sal de hash de IP del comentarista generada automáticamente.
EMDASH_AUTH_SECRETOpcional. Si se establece, se usa como fuente de la sal de IP (a menos que EMDASH_IP_SALT también esté establecida, que tiene precedencia), manteniendo estables los hashes de IP del comentarista para instalaciones que ya dependen de él. No establecer para un nuevo despliegue.

Vea Secretos y gestión de claves para el formato de clave, cada secreto soportado y los efectos de rotación o pérdida.

Base de datos y almacenamiento

VariableDescripciónEjemplo
DATABASE_PATHRuta a la base de datos SQLite/data/emdash.db
HOSTHost del servidor0.0.0.0
PORTPuerto del servidor4321
S3_ENDPOINTURL del endpoint S3https://xxx.r2.cloudflarestorage.com
S3_BUCKETNombre del bucket S3my-media-bucket
S3_ACCESS_KEY_IDClave de acceso S3AKIA...
S3_SECRET_ACCESS_KEYClave secreta S3...
S3_REGIONRegión S3auto
S3_PUBLIC_URLURL pública para medioshttps://cdn.example.com

Almacenamiento persistente

SQLite requiere almacenamiento en disco persistente. Asegúrese de que su plataforma de hosting proporcione:

  • Un volumen montado o disco persistente
  • Acceso de escritura al directorio de la base de datos
  • Mecanismos de respaldo para el archivo de base de datos

Respalde tanto el archivo SQLite como el directorio de cargas. Detenga el proceso antes de reemplazar cualquiera durante la recuperación. Vea Copias de seguridad.

Verificaciones de salud

Agregue un endpoint de verificación de salud para balanceadores de carga:

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

Este endpoint demuestra que el proceso Node.js puede servir rutas Astro. No demuestra que la base de datos, el backend de almacenamiento, el estado de migración o el sandbox de plugins esté saludable. Verifique esas dependencias por separado antes de enviar tráfico a una nueva versión.

Verificar antes de enviar tráfico

Después de iniciar una nueva compilación, verifique los mismos servicios de runtime que usan las solicitudes de producción:

  1. Solicite /health y una página de contenido público. Ambas deben devolver una respuesta exitosa.
  2. Ejecute npx emdash migrate --check desde el proyecto compilado. Debe reportar que no hay migraciones pendientes ni desconocidas para la base de datos configurada.
  3. Inicie sesión en /_emdash/admin, cree o edite un borrador desechable y publíquelo. Confirme que la página pública muestra el cambio.
  4. Suba un archivo multimedia desechable y abra su URL devuelta. Elimine el archivo después de verificarlo.
  5. Si el sitio usa plugins sandboxed, invoque una ruta o hook de plugin y confirme que el registro del servidor no tiene errores de sandbox-no-disponible o inicio de workerd.

Mantenga la nueva instancia fuera del balanceador de carga hasta que cada verificación aplicable pase.