Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Self-hosted static build for the obsidian-vault-platform's Tier-A
# "obsidian-web serverless/OPFS" (plans/obsidian-vault-platform/SPEC.md §2/§4
# in grepleria/grepleria-configs). Reuses the SAME static-asset pipeline the
# Cloudflare Workers deployment uses (src/deployments/cloudflare/), because
# that's the ONLY deployment mode with NO server-side vault storage — vaults
# live entirely in browser OPFS (see src/deployments/cloudflare/README.md).
# That property is load-bearing: SPEC's storm table forbids a shared
# server-backed vault folder across 2+ browsers, and OPFS-only sidesteps the
# question by construction (nothing server-side to share).
#
# The Node.js server deployment (src/runtime-server/server/) is NOT used
# here -- it defaults new vaults to server-backed storage ('server' vault
# type, real filesystem), which is the Tier-B (single-writer Coder
# workspace) shape, not Tier-A (SPEC §1/§3).
#
# Stage 1 does the actual "proprietary renderer" pull: the official Obsidian
# Android APK, extracted + build-time-patched into vendor/obsidian-mobile/
# (scripts/update-obsidian-mobile.js) -- never committed to this repo
# (gitignored), never redistributed; it's baked into THIS image only, which
# is then pushed to the org's own artifact-keeper registry, never a public one.
FROM node:22-alpine AS builder
RUN apk add --no-cache unzip bash
WORKDIR /src
COPY . .
# Pulls + extracts + patches the Obsidian Android APK bundle into
# vendor/obsidian-mobile/ (network access to GitHub releases required).
RUN node scripts/update-obsidian-mobile.js
# build-assets.sh only shells out to `node -e` (built-ins) -- no `npm install`
# needed (that would also pull in wrangler, a deploy-only devDependency this
# self-hosted build never uses). Also pulls the LiveSync plugin release
# (network access to GitHub releases; WARNs and continues if unreachable --
# see build-assets.sh, this is not a hard build dependency).
RUN bash src/deployments/cloudflare/scripts/build-assets.sh

FROM nginx:1.27-alpine AS runtime
COPY --from=builder /src/.tmp/deployments/cloudflare/public /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
25 changes: 25 additions & 0 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Self-hosted static server for the OPFS-only build (see Dockerfile header).
# Mirrors src/deployments/cloudflare/index.js's routing: /starter and
# /vault/<id> are client-side routes read from location.pathname by
# boot.js, not real files -- they must get the app shell back as a 200 (a
# redirect would lose the deep link). try_files with an /index.html
# fallback covers that generically for any unmatched path, which is a
# superset of the Worker's explicit /starter + /vault/* check.
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;

location / {
try_files $uri $uri/ /index.html;
}

# Known gap (mirrors the upstream CF deployment's own "Known gaps" #4):
# no self-hosted equivalent of /api/proxy-request exists here yet (the
# CORS proxy that lets the in-app community-plugin browser fetch
# GitHub/obsidian.md). Community-plugin install-from-UI will fail with a
# CORS error until src/deployments/cloudflare/proxy-worker.js is ported
# to an nginx/Node route. Not a blocker for Tier-A's pre-configured
# infra vaults (obsidian-runner seeds obsidian-livesync directly).
}