O EmDash roda no Node.js 22.16 ou posterior. Este guia usa SQLite com armazenamento local ou compatível com S3; libSQL e PostgreSQL funcionam da mesma forma no Node.js — veja Opções de banco de dados.
Pré-requisitos
- Node.js v22.16.0 ou superior
- Um provedor de hospedagem Node.js ou VPS
Configuração
Configure o EmDash para implantação no 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 e executar
-
Compilar o projeto:
npm run build -
Iniciar o servidor:
node ./dist/server/entry.mjs
O servidor roda em http://localhost:4321 por padrão. As migrações são aplicadas na primeira requisição. Se o banco de dados estiver vazio e a configuração não tiver sido concluída, seu arquivo seed (ou o padrão integrado se você não tiver um) também é aplicado nessa primeira requisição.
Tarefas agendadas
O agendador integrado roda apenas enquanto um processo Node.js está em execução. Ele lida com publicação agendada, tarefas de plugins e manutenção geral.
Mantenha pelo menos um processo Node.js rodando continuamente em produção. As tarefas agendadas pausam quando todos os processos param ou entram em modo de suspensão.
Sandbox de plugins
Os plugins do marketplace e os listados sob sandboxed: [] precisam de um runner de sandbox. No Node.js, o runner é @emdash-cms/sandbox-workerd, que executa plugins em um processo filho workerd. Plugin Sandbox cobre a instalação, como o processo workerd funciona e seus modos de falha.
Armazenamento de produção
Para produção, use armazenamento compatível com S3 em vez do sistema de arquivos 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 opcional
}),
}),
],
});
Docker
Adicione um .dockerignore para manter o contexto de build pequeno:
node_modules
dist
.git
Crie um 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"]
O arquivo seed é lido no momento do build e incorporado no bundle, então não precisa ser copiado para a imagem de runtime. As migrações são executadas na primeira requisição após uma implantação; o seed é aplicado apenas quando o banco de dados não tem coleções e a configuração não foi concluída — dados existentes nunca são sobrescritos.
Construa a imagem e execute o container:
docker build -t my-emdash-site .
docker run -p 4321:4321 -v emdash-data:/app/data my-emdash-site
Um arquivo Docker Compose gerencia o mesmo container com um volume nomeado:
services:
emdash:
build: .
ports:
- "4321:4321"
volumes:
- emdash-data:/app/data
restart: unless-stopped
volumes:
emdash-data:
Inicie a stack em segundo plano:
docker compose up -d
Variáveis de ambiente
Recomendado: chave de criptografia
EMDASH_ENCRYPTION_KEY é a chave para criptografar os segredos dos plugins em repouso. A chave é validada na inicialização; a criptografia de segredos de plugins a usa uma vez habilitada. Defina-a em cada implantação para que os segredos fiquem protegidos sem uma alteração de configuração posterior.
Gere uma chave e adicione o resultado ao seu ambiente:
npx emdash secrets generate # adicione o resultado ao seu ambiente
A chave é fornecida por você e nunca armazenada no banco de dados; apenas texto cifrado é armazenado. Faça backup em um local durável (um gerenciador de senhas, KMS ou o cofre de segredos da sua equipe) — perdê-la significa perder cada segredo criptografado com ela.
Opcional: overrides de valor estável
O EmDash auto-gera o segredo HMAC de preview e o salt de hash de IP do comentarista e os persiste no banco de dados no primeiro uso. As variáveis de ambiente abaixo os fixam a um valor que você controla — útil quando um processo separado precisa compartilhar um segredo com seu site principal.
| Variável | Descrição |
|---|---|
EMDASH_PREVIEW_SECRET | Override para o segredo HMAC de preview auto-gerado. |
EMDASH_IP_SALT | Override para o salt de hash de IP do comentarista auto-gerado. |
EMDASH_AUTH_SECRET | Opcional. Se definido, usado como fonte do salt de IP (a menos que EMDASH_IP_SALT também esteja definido, que tem precedência), mantendo os hashes de IP estáveis para instalações que já dependem dele. Deixe sem definir para uma nova implantação. |
Banco de dados e armazenamento
| Variável | Descrição | Exemplo |
|---|---|---|
DATABASE_PATH | Caminho para banco SQLite | /data/emdash.db |
HOST | Host do servidor | 0.0.0.0 |
PORT | Porta do servidor | 4321 |
S3_ENDPOINT | URL do endpoint S3 | https://xxx.r2.cloudflarestorage.com |
S3_BUCKET | Nome do bucket S3 | my-media-bucket |
S3_ACCESS_KEY_ID | Chave de acesso S3 | AKIA... |
S3_SECRET_ACCESS_KEY | Chave secreta S3 | ... |
S3_PUBLIC_URL | URL pública para mídia | https://cdn.example.com |
Armazenamento persistente
O SQLite requer armazenamento de disco persistente. Certifique-se de que sua plataforma de hospedagem forneça:
- Um volume montado ou disco persistente
- Acesso de escrita ao diretório do banco de dados
- Mecanismos de backup para o arquivo do banco de dados
Verificações de saúde
Adicione um endpoint de verificação de saúde para balanceadores de carga:
export const GET = () => {
return new Response("OK", { status: 200 });
};
Configure sua plataforma para verificar /health para sondas de liveness.