EmDash는 모든 Node.js 22+ 호스팅 플랫폼에서 실행됩니다. 이 가이드에서는 로컬 또는 S3 호환 스토리지와 함께 SQLite를 사용합니다. libSQL과 PostgreSQL도 Node.js에서 동일하게 작동합니다 — 데이터베이스 옵션을 참조하세요.
사전 요구 사항
- Node.js v22.12.0 이상
- Node.js 호스팅 공급자 또는 VPS
설정
Node.js 배포를 위해 EmDash를 설정합니다:
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",
}),
}),
],
});
빌드 및 실행
-
프로젝트 빌드:
npm run build -
서버 시작:
node ./dist/server/entry.mjs
서버는 기본적으로 http://localhost:4321에서 실행됩니다. 마이그레이션은 첫 번째 요청 시 적용됩니다. 데이터베이스가 비어 있고 설정이 완료되지 않은 경우, 시드 파일(없으면 내장 기본값)도 첫 번째 요청 시 적용됩니다.
프로덕션 스토리지
프로덕션에서는 로컬 파일 시스템 대신 S3 호환 스토리지를 사용합니다:
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, // 선택적 CDN URL
}),
}),
],
});
Docker
빌드 컨텍스트를 작게 유지하기 위해 .dockerignore를 추가합니다:
node_modules
dist
.git
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"]
시드 파일은 빌드 시 읽혀서 번들에 인라인되므로 런타임 이미지에 복사할 필요가 없습니다. 마이그레이션은 배포 후 첫 번째 요청 시 실행됩니다. 시드는 데이터베이스에 컬렉션이 없고 설정이 완료되지 않은 경우에만 적용됩니다 — 기존 데이터는 절대 덮어쓰지 않습니다.
해당 오류가 발생하면 npm ci 전에 빌더 단계에서 도구 체인을 설치합니다:
# Alpine 기반 이미지 (node:22-alpine)
RUN apk add --no-cache python3 make g++
# Debian 기반 이미지 (node:22-slim)
RUN apt-get update && apt-get install -y --no-install-recommends python3 make g++ \
&& rm -rf /var/lib/apt/lists/*
이미지 빌드 및 컨테이너 실행:
docker build -t my-emdash-site .
docker run -p 4321:4321 -v emdash-data:/app/data my-emdash-site
Docker Compose 파일은 이름 있는 볼륨으로 동일한 컨테이너를 관리합니다:
services:
emdash:
build: .
ports:
- "4321:4321"
volumes:
- emdash-data:/app/data
restart: unless-stopped
volumes:
emdash-data:
백그라운드에서 스택 시작:
docker compose up -d
환경 변수
권장: 암호화 키
EMDASH_ENCRYPTION_KEY는 플러그인 시크릿을 저장 시 암호화하기 위한
키입니다. 키는 시작 시 검증되며, 플러그인 시크릿 암호화는
활성화되면 이를 사용합니다. 모든 배포에서 설정하여 나중에 설정을 변경하지 않고도
시크릿이 보호되도록 하세요.
키를 생성하고 결과를 환경에 추가합니다:
npx emdash secrets generate # 결과를 환경에 추가
키는 사용자가 제공하며 데이터베이스에 저장되지 않습니다. 암호화된 암호문만 저장됩니다. 영구적인 곳(비밀번호 관리자, KMS, 팀의 시크릿 저장소)에 백업하세요 — 잃으면 그것으로 암호화된 모든 시크릿을 잃게 됩니다.
선택 사항: 안정 값 오버라이드
EmDash는 프리뷰 HMAC 시크릿과 댓글 작성자 IP 해시 솔트를 자동 생성하고 첫 사용 시 데이터베이스에 저장합니다. 아래 환경 변수는 당신이 제어하는 값으로 고정합니다 — 별도 프로세스가 메인 사이트와 시크릿을 공유해야 할 때 유용합니다.
| 변수 | 설명 |
|---|---|
EMDASH_PREVIEW_SECRET | 자동 생성된 프리뷰 HMAC 시크릿의 오버라이드. |
EMDASH_IP_SALT | 자동 생성된 댓글 작성자 IP 해시 솔트의 오버라이드. |
EMDASH_AUTH_SECRET | 선택 사항. 설정되면 IP 솔트 소스로 사용됩니다(EMDASH_IP_SALT도 설정된 경우 후자가 우선). 이미 이에 의존하는 설치의 댓글 작성자 IP 해시를 안정적으로 유지합니다. 새 배포에서는 설정하지 마세요. |
데이터베이스 및 스토리지
| 변수 | 설명 | 예시 |
|---|---|---|
DATABASE_PATH | SQLite 데이터베이스 경로 | /data/emdash.db |
HOST | 서버 호스트 | 0.0.0.0 |
PORT | 서버 포트 | 4321 |
S3_ENDPOINT | S3 엔드포인트 URL | https://xxx.r2.cloudflarestorage.com |
S3_BUCKET | S3 버킷 이름 | my-media-bucket |
S3_ACCESS_KEY_ID | S3 액세스 키 | AKIA... |
S3_SECRET_ACCESS_KEY | S3 시크릿 키 | ... |
S3_PUBLIC_URL | 미디어용 퍼블릭 URL | https://cdn.example.com |
영구 스토리지
SQLite는 영구 디스크 스토리지가 필요합니다. 호스팅 플랫폼이 다음을 제공하는지 확인하세요:
- 마운트된 볼륨 또는 영구 디스크
- 데이터베이스 디렉토리에 대한 쓰기 권한
- 데이터베이스 파일의 백업 메커니즘
헬스 체크
로드 밸런서용 헬스 체크 엔드포인트를 추가합니다:
export const GET = () => {
return new Response("OK", { status: 200 });
};
라이브니스 프로브를 위해 /health를 확인하도록 플랫폼을 설정하세요.