EmDash roda em qualquer plataforma de hospedagem Node.js 22+. 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.12.0 ou superior
- Um provedor de hospedagem Node.js ou VPS
Configuração
Configure o EmDash para deploy em 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 embutido se você não tiver um) também é aplicado nessa primeira requisição.
Armazenamento de produção
Para produção, use armazenamento compatível com S3 ao invés 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 em tempo de build e incluído no bundle, então não precisa ser copiado para a imagem de runtime. As migrações rodam na primeira requisição após um deploy; o seed só se aplica 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.
Se você encontrar esse erro, instale a toolchain na fase builder antes de npm ci:
# Imagens baseadas em Alpine (node:22-alpine)
RUN apk add --no-cache python3 make g++
# Imagens baseadas em Debian (node:22-slim)
RUN apt-get update && apt-get install -y --no-install-recommends python3 make g++ \
&& rm -rf /var/lib/apt/lists/*
Compilar a imagem e executar 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:
Iniciar a pilha em segundo plano:
docker compose up -d
Variáveis de ambiente
Recomendado: chave de criptografia
EMDASH_ENCRYPTION_KEY é a chave para criptografar secrets de plugins em
repouso. A chave é validada na inicialização; a criptografia de secrets de plugins a
usa quando habilitada. Configure-a em cada deploy para que os secrets sejam 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 criptografado é armazenado. Faça backup em um lugar durável (gerenciador de senhas, KMS ou armazenamento de secrets da equipe) — perdê-la significa perder cada secret criptografado com ela.
Opcional: sobrescritas de valores estáveis
EmDash gera automaticamente o secret HMAC de preview e o salt de hash de IP de comentaristas 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 secret com seu site principal.
| Variável | Descrição |
|---|---|
EMDASH_PREVIEW_SECRET | Sobrescrita para o secret HMAC de preview auto-gerado. |
EMDASH_IP_SALT | Sobrescrita para o salt de hash de IP de comentaristas auto-gerado. |
EMDASH_AUTH_SECRET | Opcional. Se definido, usado como fonte de salt de IP (a menos que EMDASH_IP_SALT também esteja definido, que tem precedência), mantendo os hashes de IP de comentaristas estáveis para instalações que já dependem dele. Deixe não definido para um novo deploy. |
Banco de dados e armazenamento
| Variável | Descrição | Exemplo |
|---|---|---|
DATABASE_PATH | Caminho do 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
SQLite requer armazenamento em 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
Health Checks
Adicione um endpoint de health check para load balancers:
export const GET = () => {
return new Response("OK", { status: 200 });
};
Configure sua plataforma para verificar /health para sondas de liveness.