services: trilium: image: triliumnext/trilium:v0.106.1 restart: unless-stopped environment: ADMIN_PASSWORD: ${ADMIN_PASSWORD} # Requests come through the proxy: the client's own address is the one it forwards, so that # a stranger's wrong passwords do not lock everyone out of signing in. TRILIUM_NETWORK_TRUSTEDREVERSEPROXY: uniquelocal # A new Trilium offers its setup to whoever opens it first, then asks them for the password. # So while it has no password, it runs on port 8081, which nobody reaches: a new knowledge base # is made there with the password given, and only then does Trilium answer on 8080. command: - sh - -c - | set -e if ! node -e ' const { DatabaseSync } = require("node:sqlite"); const db = new DatabaseSync(process.env.TRILIUM_DATA_DIR + "/document.db", { readOnly: true }); const row = db.prepare("select value from options where name = ?").get("passwordVerificationHash"); process.exit(row?.value ? 0 : 1); ' 2>/dev/null; then TRILIUM_PORT=8081 node ./main.mjs & setup=$$! node -e ' const base = "http://127.0.0.1:8081"; const setUp = async () => { const status = await fetch(base + "/api/setup/status").then((r) => r.json()); if (!status.isInitialized) { const made = await fetch(base + "/api/setup/new-document?skipDemoDb", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ locale: "en" }) }); if (!made.ok) throw new Error("new-document: " + made.status + " " + (await made.text())); } const password = process.env.ADMIN_PASSWORD; const set = await fetch(base + "/set-password", { method: "POST", body: new URLSearchParams({ password1: password, password2: password }), redirect: "manual" }); if (set.status !== 302) throw new Error("set-password: " + set.status + " " + (await set.text())); }; (async () => { let failure; for (let i = 0; i < 180; i++) { try { return await setUp(); } catch (error) { failure = error; await new Promise((done) => setTimeout(done, 1000)); } } console.error(failure); process.exit(1); })(); ' kill $$setup wait $$setup || true fi chown -R node:node /home/node exec su -c "node ./main.mjs" node volumes: - data:/home/node/trilium-data volumes: data: