Files
RawMark/docs/deployment.md
T

8.4 KiB

Deployment and maintenance

English · 简体中文

Project home · User guide · Development guide

RawMark embeds the frontend in its Go service and uses SQLite and the filesystem at runtime. No separate database service is needed. Docker images are currently built from source; the commands below do not depend on a prepublished image registry.

Docker quick start

With Git and Docker installed:

git clone https://github.com/eezd/RawMark.git
cd RawMark
docker build -t rawmark .
docker run -d --name rawmark --restart unless-stopped \
  -p 127.0.0.1:21000:8080 \
  -v rawmark-data:/data \
  rawmark

Open http://localhost:21000 to set the initial password. The named volume rawmark-data holds application data; reuse it when recreating the container and do not delete it. For a remote server, reach its local port through an SSH tunnel to complete setup:

ssh -L 21000:127.0.0.1:21000 user@your-server

The container defaults to UID/GID 65532:65532. A new Docker named volume inherits permissions from the image's data directory.

Docker Compose

The repository includes deploy/docker-compose.yml, which persists data in the host's deploy/data/. For a first deployment on Linux:

mkdir -p deploy/data
sudo chown 65532:65532 deploy/data
docker compose -f deploy/docker-compose.yml up -d --build --wait

This configuration publishes port 21000 on all network interfaces by default. Complete initialization and configure access boundaries before exposing it publicly. With a reverse proxy, you can change the Compose port binding to 127.0.0.1:${RAWMARK_PORT:-21000}:8080. For a custom port, use RAWMARK_PORT=21001 docker compose -f deploy/docker-compose.yml up -d --build --wait.

Do not point the quick-start container and a Compose instance at the same database or vault concurrently. Stop the old instance, back up, and verify data locations before switching deployment methods.

Storage and configuration

Environment variable Default Description
RAWMARK_DATA /data Application database, index, resources, and default vault directory
RAWMARK_VAULT $RAWMARK_DATA/vault Markdown vault; can be a separately mounted existing directory
RAWMARK_ADDR :8080 Listen address inside the container or binary

Main data locations:

Path Contents
vault/ Markdown files, attachments, and vault metadata; stored at the configured location when using an external vault
rawmark.db Password, sessions, API tokens, settings, and other application state
index.db Rebuildable search index
fonts/, themes/, plugins/ User-imported fonts, themes, and plugins
backups/ Rollback backups created before imports or restores
logs/ Runtime logs

To use an existing folder, mount it separately and set RAWMARK_VAULT:

docker run -d --name rawmark --restart unless-stopped \
  --user "$(id -u):$(id -g)" \
  -p 127.0.0.1:21000:8080 \
  -v "$HOME/rawmark-data:/data" \
  -v "$HOME/notes:/vault" \
  -e RAWMARK_VAULT=/vault \
  rawmark

Create $HOME/rawmark-data and $HOME/notes first and ensure the selected user can write to them. This example runs as the current host user, which suits an existing personal directory. Without --user, grant write access to the container's default user. RawMark modifies notes and links, so back up an existing directory before first use.

HTTPS and reverse proxy

Use HTTPS for remote access. The proxy must forward Host, protocol, and client address information and support WebSocket upgrades and long-lived connections. Browser event connections use /api/v1/resources/<ticket>/events/. Proxy upload limits should accommodate your imports.

The repository's Nginx configuration includes examples of WebSocket support and redacted ticket logging. Its domain, certificate includes, anti-bot includes, port, and log paths belong to the original deployment environment: adapt them to your server rather than installing the file unchanged. Define the $connection_upgrade map in Nginx's http context as well.

Resource tickets are credentials. Proxies, CDNs, and access logs must not record plaintext tickets, query parameters, or credential-bearing Referer headers. The application's no-store policy does not replace proxy log redaction. Nginx error logs can also contain raw request paths; the repository example disables error logging for ticket resource paths while retaining redacted access logs and application error logs.

When using a CDN, configure its custom domain and TLS certificate separately, and ensure APIs, private resources, and WebSocket connections are not cached incorrectly. DNS configuration alone does not complete HTTPS setup.

Backup and restore

Choose an export type under Settings → Storage:

Type Intended use Restore behavior
Plain Markdown vault Move to another note-taking tool Imports into a new folder without replacing the instance
Settings and resources Migrate preferences, plugin data, fonts, themes, and plugins Merges resources, replaces matching IDs, and retains resources absent from the archive
Full instance Migrate or restore RawMark Replaces application data, including login credentials, recycle bin, and resources; requires signing in again

Settings imports and full restores accept only RawMark's versioned ZIP format. A rollback archive is kept in backups/ before applying changes. Uploads use sequential 8 MiB chunks. Limits are 2 GiB compressed, 8 GiB expanded, and 100,000 entries. Operational environment configuration, derived indexes, and temporary files are excluded.

Stop other programs from directly modifying the vault before a full restore. API operations pause during maintenance; the restore closes databases and background tasks, and rolls back to the pre-operation backup if interrupted. Full exports contain sensitive account and note data. Store them securely; do not commit them or attach them to public issues.

In addition to application backups, stop the service before upgrades and back up the complete data directory, external vault, deployment configuration, and previous image. SQLite may have WAL files while running; copying only an actively written rawmark.db is not a consistent backup.

Upgrade and rollback

  1. Check the target version's behavior and data compatibility; retain the current image and deployment configuration.
  2. Stop the old service and back up application data and any external vault.
  3. Update the source, rebuild, and start the new instance with the same mounts. Do not run old and new services concurrently.
  4. Verify container health, sign-in, notes, and attachments. Roll back using the matching previous image and data backup.

The Bearer authentication upgrade requires the frontend and backend to be released together. Old Cookie-based pages require signing in again. Startup creates the resource-ticket table and indexes through the existing SQLite initialization flow; notes, passwords, settings, and existing API tokens are retained. Third-party clients must follow the current JSON protocol.

scripts/remove-sharing.sql and scripts/reset-shortcuts.sql are one-time historical migrations. The former removes old sharing data; the latter clears old shortcut overrides. New deployments do not need them, and instances that have already run them must not rerun them. Execute one separately only after confirming an applicable old version, stopping the service, and backing up.

Routine maintenance and troubleshooting

  • The container includes a health check. You can also call GET /api/v1/health; a healthy result does not verify every business workflow.
  • Index optimization/rebuilding affects only derived indexes. Temporary-file cleanup does not delete user files, active uploads, or restore backups.
  • Resetting settings retains the account, resources, plugin storage, and local tabs.
  • Logs live in logs/, with three rotated files retained, each up to 10 MiB. Settings can export logs and a version summary; this does not reconstruct historical logs.
  • If the interface breaks after an update, first check that the frontend and backend come from the same build, then inspect browser network requests and application logs. See the user guide for plugin and appearance recovery entry points.