GROWI Documentation
repository·master·Indexed 23 days ago
https://github.com/growilabs/growiA pluggable, markdown-based wiki platform supporting hierarchical pages, real-time collaborative editing, and authentication via LDAP, OAuth, and SAML. Includes guides for Docker and Helm deployment, V8 memory management, and the GROWI Vault feature which allows cloning the wiki as a read-only git repository of Markdown files. Also covers developer documentation for Jotai state management migration and apiv3 authorization regression testing.
What's inside GROWI
- The PDF-Converter is a specialized service used by GROWI to facilitate the bulk export of pages in PDF format. When a user executes a bulk PDF export from the GROWI page menu, GROWI uses this app to convert markdown pages into PDF files.
Use Startup Memory A/B Tools to compare GROWI builds
masterThe Startup Memory A/B Tools are lightweight Linux-only tools (designed for devcontainers) used to compare the boot-time memory footprint and loaded-module set of two GROWI production builds. Use these tools when you need to answer "what does the server load and cost at startup?" rather than analyzing memory behavior under sustained load.
Key Metrics to Watch:
- installed-idle stable RSS: The steady-state memory usage after the server has finished booting and idling.
- boot-phase max: The transient peak memory usage during startup, which is critical for preventing OOM-kills in resource-constrained environments (like Kubernetes pods).
Use remark-drawio to draw diagrams with draw.io
masterTheremark-drawioplugin allows GROWI users to create and render diagrams using draw.io (diagrams.net). It functions as a remark plugin within the GROWI ecosystem to integrate diagramming capabilities directly into the markdown workflow.Understand growi-vault-manager MVP limitations
masterThe current version of
growi-vault-managerhas the following limitations:- Read-only:
git push(write-back) is not supported. Changes in the vault are not synced to GROWI. - No Attachments: Binary files attached to pages are not exported.
- No Metadata: Comments, likes, bookmarks, and tags are not exported.
- No Drafts: Only published pages are exported.
- No Pre-existing History: Only revisions created after the vault feature is enabled are captured.
- Limited Filtering: Only the published
sparse:oidspec (for excludinguser/) is supported. Other filters likeblob:noneor client-chosen patterns are refused by the server.
- Read-only:
What is PDF-Converter
masterPDF-Converter is a specialized service for GROWI that enables the bulk export of pages into PDF format. It is responsible for the actual conversion of Markdown pages into PDF files when a user triggers the bulk export process from the page menu in GROWI.What is GROWI Vault and how does it work?
masterGROWI Vault turns a GROWI wiki into a git repository, allowing users to
git clonethe wiki as a tree of Markdown files. This enables searching withgrep, using local editors, or providing files to AI agents.Key Characteristics:
- Read-Only:
git pushis rejected. Attachments, comments, likes, and tags are not exported. - Permission-Aware: Each clone contains only the pages the specific user is authorized to read. Unauthorized pages are completely absent from the tree and refs.
- Architecture: The Vault Manager is not a standalone application. It is an engine that runs alongside the GROWI app container. The GROWI app handles all domain knowledge (access control, authentication, group resolution) and proxies clone traffic to the Vault Manager, which maintains the bare git repository and serves
git upload-pack.
- Read-Only:
Use the @growi/editor playground for feature simulation
masterThe@growi/editorpackage includes a playground designed to simulate features of@growi/app. If you need to test or simulate specific application behaviors, you can implement them within the playground environment. The playground implementation is located in thecomponents/playgrounddirectory.How GROWI page paths are mapped to filenames
masterThe
VaultPathMapperconverts GROWI page paths into deterministic git-tree file paths. This allows the vault to reconstruct file paths from page records without a reverse index.Encoding Rules (v1)
Rules are applied in order:
- Windows reserved characters:
<>:"/\|?*are percent-encoded (e.g.,<→%3C). - Control characters: U+0000–U+001F or U+007F are percent-encoded.
- Leading/trailing spaces: Percent-encoded (
%20). - Windows reserved filenames: Segments matching
CON,PRN,AUX,NUL,COM0-9, orLPT0-9(case-insensitive) are prefixed with_(e.g.,CON→_CON). - Case collision (reactive): If two paths in the same view differ only by case (e.g.,
/Fooand/foo), a__<hash8>suffix (first 8 chars ofsha1(<path>.md)) is appended to the filename component. - Length limit: If a component exceeds 255 UTF-8 bytes, it is shortened (on character boundaries) and appended with a
__<hash8>suffix. - Orphan pages: Paths
/trashor starting with/trash/are prefixed with_orphaned/. - Extension:
.mdis appended to the final component.
Key Behaviors
- Parent pages with children: A page with children does not use
README.md. Instead, it uses<name>.mdalongside a<name>/directory. mapPrefix(pagePath): A variant that applies encoding and reserved-name prefixing but does not append.mdor the__<hash8>suffix. Used for directory-only operations.
- Windows reserved characters:
Syntax: Generic Directives
masterThis extension implements the generic directives proposal. There are three types of directives:
1. Text Directives
Used within text lines. Syntax:
:name[label]{attributes}. Example::cite[smith04]or:abbr[HTML]{title="HyperText Markup Language"}.2. Leaf Directives
Block-level directives without content. Syntax:
::name[label]{attributes}on its own line. Example:::youtube[Video]{vid=01ab2cd3efg}.3. Container Directives
Blocks that can contain other content. Syntax:
:::nameto open and:::to close. Example::::spoiler Content here :::Rules & Constraints:
- Naming: The
nameis required. It must start with a letter. Other characters can be alphanumeric,-, or_.-or_cannot end a name. - Labels: The
[label]part is optional.:xand:x[]are equivalent. Labels can include text constructs like emphasis (:x[a *b* c]). - Attributes: The
{attributes}part is optional. Supports standard HTML attribute syntax.- Shortcuts:
{#id}for{id=id}and{.class}for{class=class}. - Multiple classes:
{.red .blue}or{class="red blue"}are both valid.
- Shortcuts:
- Nesting: Containers can be nested using more colons (e.g.,
::::to wrap:::) and must be closed with an equal or greater number of colons. - Strictness: No whitespace is allowed between colons and the name, or between name/label/attributes. Labels and attributes cannot contain line endings.
- Naming: The
Preventing double application of changes during Accept
masterWhen using
useUnifiedMergeView, executing an Accept action in Editor 1 can cause changes to be applied twice. This happens because the change applied to theprimaryDocis synchronized back to Editor 1 via Yjs, which then attempts to apply it to theoriginalDocagain.Solution: Using Yjs Transaction Origins
To prevent this, you must track the source of the transaction using a unique origin token.
- When Accepting: Wrap the
primaryDoctransaction with a specific origin. - During Synchronization: Check the transaction origin and skip processing if it matches the acceptance token.
Implementation Pattern:
// 1. Define a unique origin token const SYNC_BY_ACCEPT_CHUNK = 'accept'; // 2. When performing the Accept action primaryDoc.transact(() => { // ... apply changes ... }, SYNC_BY_ACCEPT_CHUNK); // 3. In the synchronization handler if (event.transaction.origin === SYNC_BY_ACCEPT_CHUNK) { return; // Skip to prevent double application }- When Accepting: Wrap the
Analyze memory-profiler output files
masterThe tool generates four files in the specified
--outputDir:snapshot-a.heapsnapshot: Heap snapshot at the baseline boundary (end of baseline idle phase).snapshot-b.heapsnapshot: Heap snapshot at the load boundary (end of load phase).snapshot-c.heapsnapshot: Heap snapshot at the drain boundary (end of drain idle phase).rss-timeseries.csv: Process RSS / heap time-series sampled throughout the run.
The CSV file uses the following fixed header:
timestamp,phase,rss,heap_used,heap_total,externalSecurity Warning: Heap snapshots (
*.heapsnapshot) may contain sensitive runtime data (user content, session tokens, secrets). Do not commit these files to the repository or share them externally without explicit review.Requirements for GROWI Vault
masterTo run GROWI Vault, you must meet the following requirements:
- GROWI Version: GROWI >= 8.0.0 (
growilabs/growi:8) with the Vault feature enabled. - MongoDB: MongoDB (>= 6.0) running as a replica set. The vault uses MongoDB change streams to stay up to date; a single-node replica set is sufficient.
- Shared Filesystem: A persistent filesystem for the bare repository that is shared between the GROWI app container and the Vault Manager container.
- Note: The Vault Manager container starts as root to set permissions, then drops to the
nodeuser (uid/gid 1000), matching the GROWI app's user for volume compatibility.
- Note: The Vault Manager container starts as root to set permissions, then drops to the
- GROWI Version: GROWI >= 8.0.0 (