Skip to content

datalevin/docs

Repository files navigation

Datalevin Documentation Site

Prerequisites

  • Java 21+
  • Clojure CLI 1.12+
  • Node.js / npm (for Tailwind CSS)

Setup

# Clone with submodules
git clone --recurse-submodules <repo-url>

# Or if already cloned, init submodules
git submodule update --init --recursive

# Install npm dependencies (Tailwind CSS)
npm install

# Create .env from example
cp .env.example .env

Edit .env as needed. The defaults work for local development; GitHub OAuth credentials are optional.

Development

Start the nREPL:

clojure -M:dev

Then in the REPL:

(require 'dev)
(dev/start)

This starts:

  • Web server on http://localhost:3000
  • Tailwind CSS watcher (recompiles on class changes)
  • Live reload via file watcher — editing .clj, .css, or .md files triggers an automatic browser refresh

Other REPL commands:

(dev/stop)      ; stop everything
(dev/restart)   ; full restart
(dev/reload!)   ; manually trigger a browser refresh

Build CSS (production)

npm run css:build

Build uberjar

Build a standalone jar for small VMs:

npm run css:build
clojure -T:build uber

This produces:

target/datalevin-docs-standalone.jar

The uberjar avoids resolving the production classpath on every boot and is the preferred deployment target on a 1 GB VM.

Production

Start the docs site from the built uberjar with explicit JVM heap limits:

clojure -T:build uber
scripts/start-prod.sh

Set ENV=prod and a real SESSION_SECRET before starting. Startup now fails fast if ENV=prod and SESSION_SECRET is missing. In production, startup also fails fast unless outbound email is configured with MAIL_FROM and SMTP_HOST.

That wrapper runs the same jar-based startup pattern as the systemd unit:

java -Xms256m -Xmx384m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+UseStringDeduplication -XX:MaxMetaspaceSize=128m -jar target/datalevin-docs-standalone.jar

On small VMs, setting -Xms and a conservative -Xmx avoids the JVM expanding until the host OOM killer intervenes while still leaving more room for Datalevin's mmap usage. Provision at least 1 GB of swap on these hosts so short bursts of heap or page-cache pressure do not immediately turn into an OOM kill. The prod wrapper also defaults to G1 with string deduplication and a 128 MB metaspace cap. You can override the defaults if needed:

JAVA_XMS=256m JAVA_XMX=768m scripts/start-prod.sh

If you want a lower-overhead collector on a very small VM, switch the wrapper to Serial GC:

JAVA_GC=serial scripts/start-prod.sh

Override APP_JAR if the jar lives outside the repo checkout:

APP_JAR=/opt/datalevin-docs/datalevin-docs-standalone.jar scripts/start-prod.sh

systemd

An example unit file is included at deploy/systemd/datalevin-docs.service. It keeps MemoryHigh=800M and OOMPolicy=stop, while relying on the JVM heap limits and Datalevin's own mapsize instead of a hard MemoryMax cap.

Typical install steps:

sudo install -d /opt/datalevin-docs /etc/datalevin-docs
sudo install -m 0644 target/datalevin-docs-standalone.jar /opt/datalevin-docs/datalevin-docs-standalone.jar
sudo install -m 0644 deploy/systemd/datalevin-docs.service /etc/systemd/system/datalevin-docs.service

Create /etc/datalevin-docs/datalevin-docs.env with at least:

ENV=prod
PORT=3000
BASE_URL=https://docs.example.com
DB_PATH=/var/lib/datalevin-docs/data
SESSION_SECRET=replace-with-a-real-secret
MAIL_FROM="Datalevin Docs <noreply@example.com>"
SMTP_HOST=smtp.example.com
SMTP_PORT=587
SMTP_USER=smtp-user
SMTP_PASS=smtp-password
SMTP_TLS=true

Without SMTP config, development keeps logging verification and reset links to the console instead of sending email.

Then enable the service:

sudo systemctl daemon-reload
sudo systemctl enable --now datalevin-docs

About

Documentation Site of Datalevin

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors