EmDash se ejecuta en Node.js 22.16 o posterior. Esta guía usa SQLite y almacenamiento local para un servidor. Usa 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
Configura 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",
}),
}),
],
});
Construir y ejecutar
-
Construye el proyecto:
npm run build -
Inicia el servidor:
node ./dist/server/entry.mjsEstablece
EMDASH_ENCRYPTION_KEYy otras credenciales de runtime a través del entorno de proceso del proveedor de hosting antes de iniciar el servidor. La entrada Node standalone no carga.envautomáticamente. Para una ejecución local que use el archivo.envgenerado, inícialo connode --env-file=.env ./dist/server/entry.mjs.
El servidor se ejecuta en http://localhost:4321 por defecto. Con el modo de migración auto predeterminado, la primera solicitud aplica las migraciones core pendientes. Una base de datos nueva también recibe el seed embebido. Manage core database migrations 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á en marcha. Gestiona la publicación programada, las tareas de plugins y el mantenimiento general.
Mantén al menos un proceso Node.js en ejecución continua en producción. Las tareas programadas se pausan cuando todos los procesos se detienen o duermen.
Sandbox de plugins
Los plugins del marketplace y los listados bajo sandboxed: [] necesitan un sandbox runner. En Node.js, el runner es @emdash-cms/sandbox-workerd, que ejecuta plugins en un proceso hijo workerd. Plugin Sandbox cubre la instalación, cómo se ejecuta el proceso workerd y sus modos de fallo.
Elegir servicios de datos de producción
Usa el siguiente patrón cuando la base de datos permanezca en un volumen persistente y los medios se muevan 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
Añade un .dockerignore para mantener pequeño el contexto de build:
node_modules
dist
.git
Crea 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 build y se incrusta en el bundle, por lo que no necesita copiarse a la imagen de runtime. Las migraciones se ejecutan en la primera solicitud tras un deploy; 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.
Construye la imagen y ejecuta 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 con nombre:
services:
emdash:
build: .
ports:
- "4321:4321"
volumes:
- emdash-data:/app/data
restart: unless-stopped
volumes:
emdash-data:
Inicia el stack en segundo plano:
docker compose up -d
Entorno de runtime
Lee las credenciales de base de datos y almacenamiento del entorno del proceso cuando el servidor arranca. Las siguientes variables admiten la configuración anterior:
Cifrado de ajustes de plugins
EMDASH_ENCRYPTION_KEY cifra los ajustes de plugins declarados como secrets. Un valor malformado produce un mensaje de arranque orientado al operador, y las operaciones de ajustes secretos de plugins fallan hasta que se corrija el valor.
Genera un valor válido y añade el resultado al entorno del proceso del servidor:
npx emdash secrets generate # add the result to your environment
El valor lo proporciona el operador y no se almacena en la base de datos. Guárdalo en un gestor de secrets y en una copia de recuperación separada. Durante la rotación, proporciona primero la nueva clave y retiene las claves antiguas tras comas hasta que cada secret de plugin se haya guardado de nuevo. EmDash no informa actualmente qué IDs de clave siguen en uso, así que rastrea cada credencial vuelva a guardarse y verifica su integración antes de eliminar una clave antigua. Restaurar la base de datos sin una clave referenciada deja ilegibles los ajustes correspondientes.
Opcional: overrides 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 siguientes los fijan a un valor que controlas — útil cuando un proceso separado necesita compartir un secreto con tu sitio principal.
| Variable | Descripción |
|---|---|
EMDASH_PREVIEW_SECRET | Override del secreto HMAC de vista previa autogenerado. |
EMDASH_IP_SALT | Override de la sal de hash de IP del comentarista autogenerada. |
EMDASH_AUTH_SECRET | Opcional. Si está definida, se usa como fuente de sal de IP (salvo que también esté EMDASH_IP_SALT, que tiene precedencia), manteniendo estables los hashes de IP del comentarista para instalaciones que ya dependen de ella. Déjala sin definir en un despliegue nuevo. |
Consulta Secrets and key management para el formato de clave, cada secreto admitido y los efectos de la rotación o pérdida.
Base de datos y almacenamiento
| Variable | Descripción | Ejemplo |
|---|---|---|
DATABASE_PATH | Ruta a la base de datos SQLite | /data/emdash.db |
HOST | Host del servidor | 0.0.0.0 |
PORT | Puerto del servidor | 4321 |
S3_ENDPOINT | URL del endpoint S3 | https://xxx.r2.cloudflarestorage.com |
S3_BUCKET | Nombre del bucket S3 | my-media-bucket |
S3_ACCESS_KEY_ID | Clave de acceso S3 | AKIA... |
S3_SECRET_ACCESS_KEY | Clave secreta S3 | ... |
S3_REGION | Región S3 | auto |
S3_PUBLIC_URL | URL pública para medios | https://cdn.example.com |
Almacenamiento persistente
SQLite requiere almacenamiento en disco persistente. Asegúrate de que tu plataforma de hosting proporcione:
- Un volumen montado o disco persistente
- Acceso de escritura al directorio de la base de datos
- Mecanismos de copia de seguridad para el archivo de la base de datos
Haz copia de seguridad tanto del archivo SQLite como del directorio de subidas. Detén el proceso antes de reemplazar cualquiera durante la recuperación. Consulta Backups.
Comprobaciones de salud
Añade un endpoint de health check 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 migraciones o el sandbox de plugins estén sanos. Verifica esas dependencias por separado antes de enviar tráfico a un nuevo release.
Verificar antes de enviar tráfico
Tras iniciar un nuevo build, verifica los mismos servicios de runtime que usan las solicitudes de producción:
- Solicita
/healthy una página de contenido pública. Ambas deben devolver una respuesta correcta. - Ejecuta
npx emdash migrate --checkdesde el proyecto construido. Debe informar de que no hay migraciones pendientes o desconocidas para la base de datos configurada. - Inicia sesión en
/_emdash/admin, crea o edita un borrador desechable y publícalo. Confirma que la página pública muestra el cambio. - Sube un archivo multimedia desechable y abre su URL devuelta. Elimina el archivo tras verificarlo.
- Si el sitio usa plugins sandboxed, invoca una ruta o hook de plugin y confirma que el log del servidor no tiene errores de sandbox-unavailable ni de arranque de
workerd.
Mantén la nueva instancia fuera del balanceador de carga hasta que cada comprobación aplicable pase.