Deploy no Node.js

Nesta página

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

  1. Compilar o projeto:

    npm run build
  2. 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ávelDescrição
EMDASH_PREVIEW_SECRETSobrescrita para o secret HMAC de preview auto-gerado.
EMDASH_IP_SALTSobrescrita para o salt de hash de IP de comentaristas auto-gerado.
EMDASH_AUTH_SECRETOpcional. 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ávelDescriçãoExemplo
DATABASE_PATHCaminho do banco SQLite/data/emdash.db
HOSTHost do servidor0.0.0.0
PORTPorta do servidor4321
S3_ENDPOINTURL do endpoint S3https://xxx.r2.cloudflarestorage.com
S3_BUCKETNome do bucket S3my-media-bucket
S3_ACCESS_KEY_IDChave de acesso S3AKIA...
S3_SECRET_ACCESS_KEYChave secreta S3...
S3_PUBLIC_URLURL pública para mídiahttps://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.