O EmDash roda no Node.js 22.16 ou posterior. Este guia usa SQLite e armazenamento local para um servidor. Use PostgreSQL ou libSQL quando várias instâncias precisarem de um banco, e armazenamento compatível com S3 quando a mídia precisar sobreviver independentemente do disco do servidor.
Pré-requisitos
- Node.js v22.16.0 ou superior
- Um provedor de hospedagem Node.js ou VPS
Configurar o site
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
-
Compile o projeto:
npm run build -
Inicie o servidor:
node ./dist/server/entry.mjsDefina
EMDASH_ENCRYPTION_KEYe outras credenciais de runtime pelo ambiente de processo do provedor de hospedagem antes de iniciar o servidor. A entrada Node standalone não carrega.envautomaticamente. Para uma execução local que use o arquivo.envgerado, inicie comnode --env-file=.env ./dist/server/entry.mjs.
O servidor roda em http://localhost:4321 por padrão. Com o modo de migração auto padrão, a primeira solicitação aplica as migrações core pendentes. Um banco novo também recebe o seed embutido. Manage core database migrations explica como migrar antes de retomar o tráfego de produção.
Tarefas agendadas
O agendador embutido roda somente enquanto um processo Node.js estiver em execução. Ele cuida de publicação agendada, tarefas de plugins e manutenção geral.
Mantenha pelo menos um processo Node.js em execução contínua em produção. Tarefas agendadas pausam quando todos os processos param ou dormem.
Sandbox de plugins
Plugins do marketplace e os listados sob sandboxed: [] precisam de um sandbox runner. 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 roda e seus modos de falha.
Escolher serviços de dados de produção
Use o seguinte padrão quando o banco permanecer em um volume persistente e a mídia for para armazenamento compatível com S3:
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
database: sqlite({ url: `file:${process.env.DATABASE_PATH}` }),
storage: s3(),
}),
],
});
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 build e embutido no bundle, portanto não precisa ser copiado para a imagem de runtime. As migrações rodam na primeira solicitação após um deploy; o seed só se aplica quando o banco não tem collections e a configuração não foi concluída — dados existentes nunca são sobrescritos.
Compile 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
Ambiente de runtime
Leia as credenciais de banco e armazenamento do ambiente do processo quando o servidor iniciar. As seguintes variáveis suportam a configuração acima:
Criptografia de configurações de plugins
EMDASH_ENCRYPTION_KEY criptografa configurações de plugins declaradas como secrets. Um valor malformado produz uma mensagem de inicialização voltada ao operador, e operações de configurações secretas de plugins falham até o valor ser corrigido.
Gere um valor válido e adicione o resultado ao ambiente do processo do servidor:
npx emdash secrets generate # add the result to your environment
O valor é fornecido pelo operador e não é armazenado no banco. Mantenha-o em um gerenciador de secrets e em um backup de recuperação separado. Durante a rotação, forneça primeiro a nova chave e retenha chaves mais antigas após vírgulas até que cada secret de plugin tenha sido salvo novamente. O EmDash não reporta atualmente quais IDs de chave permanecem em uso, então acompanhe cada credencial resalva e verifique sua integração antes de remover uma chave antiga. Restaurar o banco sem uma chave referenciada deixa as configurações correspondentes ilegíveis.
Opcional: overrides de valores estáveis
O EmDash gera automaticamente o secret HMAC de preview e o salt de hash de IP do comentarista e os persiste no banco no primeiro uso. As variáveis de ambiente abaixo os fixam em um valor que você controla — útil quando um processo separado precisa compartilhar um secret com o site principal.
| Variável | Descrição |
|---|---|
EMDASH_PREVIEW_SECRET | Override do secret HMAC de preview gerado automaticamente. |
EMDASH_IP_SALT | Override do salt de hash de IP do comentarista gerado automaticamente. |
EMDASH_AUTH_SECRET | Opcional. Se definido, usado como fonte do salt de IP (a menos que EMDASH_IP_SALT também esteja definido, o que tem precedência), mantendo estáveis os hashes de IP do comentarista para instalações que já dependem dele. Deixe indefinido para uma nova implantação. |
Veja Secrets and key management para o formato da chave, cada secret suportado e os efeitos de rotação ou perda.
Banco de dados e armazenamento
| Variável | Descrição | Exemplo |
|---|---|---|
DATABASE_PATH | Caminho para o 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_REGION | Região S3 | auto |
S3_PUBLIC_URL | URL pública para mídia | https://cdn.example.com |
Armazenamento persistente
SQLite exige armazenamento em disco persistente. Garanta que sua plataforma de hospedagem forneça:
- Um volume montado ou disco persistente
- Acesso de escrita ao diretório do banco
- Mecanismos de backup para o arquivo do banco
Faça backup do arquivo SQLite e do diretório de uploads. Pare o processo antes de substituir qualquer um durante a recuperação. Veja Backups.
Verificações de saúde
Adicione um endpoint de health check para balanceadores de carga:
export const GET = () => {
return new Response("OK", { status: 200 });
};
Este endpoint prova que o processo Node.js pode servir rotas Astro. Não prova que o banco, o backend de armazenamento, o estado de migrações ou o sandbox de plugins estão saudáveis. Verifique essas dependências separadamente antes de enviar tráfego a um novo release.
Verificar antes de enviar tráfego
Após iniciar um novo build, verifique os mesmos serviços de runtime que as solicitações de produção usam:
- Solicite
/healthe uma página de conteúdo pública. Ambas devem retornar uma resposta bem-sucedida. - Execute
npx emdash migrate --checka partir do projeto compilado. Deve relatar nenhuma migração pendente ou desconhecida para o banco configurado. - Entre em
/_emdash/admin, crie ou edite um rascunho descartável e publique-o. Confirme que a página pública mostra a alteração. - Envie um arquivo de mídia descartável e abra a URL retornada. Exclua o arquivo após verificar.
- Se o site usa plugins sandboxed, invoque uma rota ou hook de plugin e confirme que o log do servidor não tem erro sandbox-unavailable nem de inicialização do
workerd.
Mantenha a nova instância fora do balanceador de carga até que cada verificação aplicável passe.