diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..d759239 --- /dev/null +++ b/.env.example @@ -0,0 +1,51 @@ +# cp .env.example .env — and fill it in. Docker Compose reads .env from this +# directory, next to docker-compose.yml; nothing looks for it anywhere else. +# +# Back the finished .env up together with the database: without ENCRYPTION_KEY +# the stored notes cannot be read again, and a backup of one without the other +# is worth nothing. + +# Signs session tokens. Changing it logs everyone out. +# openssl rand -hex 32 +JWT_SECRET= + +# Encrypts note bodies at rest. LOSING THIS MEANS LOSING THE NOTES. +# Must be exactly 32 bytes as hex. +# openssl rand -hex 32 +ENCRYPTION_KEY= + +# The first administrator. +# +# There is no public sign-up — accounts are created by an admin inside the app +# under Account → Administration. These two settle who the first one is: +# +# empty database → the account is created from both values +# existing users, → INKNOTE_ADMIN_USER names which of them becomes admin. +# no admin yet Without it, the oldest account is promoted. +# an admin exists → both are ignored entirely +# +# So they can never reset an existing password or take rights away; the worst +# they can do on a running instance is nothing. +INKNOTE_ADMIN_USER= +INKNOTE_ADMIN_PASSWORD= + +# ── Where the data lives ── +# A plain directory on the Docker host, so the host's own backup covers it. +# Create it before the first start: +# mkdir -p /srv/inknote/{db,uploads} && chown -R 1000:1000 /srv/inknote +# INKNOTE_DATA_DIR=/srv/inknote # dev compose defaults to ./data +# INKNOTE_UID=1000 # must own the directory above +# INKNOTE_GID=1000 + +# ── Optional tuning ── +# Leave unset to keep the defaults shown. +# MAX_VERSIONS_PER_NOTE=50 # versions kept per note +# VERSION_RETENTION_DAYS=90 # and for how long +# VERSION_COALESCE_MINUTES=5 # edits within this window share a version +# +# Only if the UI is served from a different host than the API. With a reverse +# proxy in front, or the bundled nginx, leave it empty — same-origin needs none. +# ALLOWED_ORIGINS=https://notes.example.com +# +# PORT is deliberately not here: the bundled nginx proxies to port 4000 by +# name, so changing it would only break that. diff --git a/backend/.env.example b/backend/.env.example deleted file mode 100644 index 2899a42..0000000 --- a/backend/.env.example +++ /dev/null @@ -1,34 +0,0 @@ -# Copy to ../.env next to docker-compose.yml and fill in. -# Back this file up together with the database: without ENCRYPTION_KEY the -# stored notes cannot be read again. - -# Signs session tokens. Changing it logs everyone out. -# openssl rand -hex 32 -JWT_SECRET= - -# Encrypts note bodies at rest. LOSING THIS MEANS LOSING THE NOTES. -# Must be exactly 32 bytes as hex. -# openssl rand -hex 32 -ENCRYPTION_KEY= - -# The first administrator. -# -# There is no public sign-up — accounts are created by an admin inside the app -# under Account → Administration. These two settle who the first one is: -# -# empty database → the account is created from both values -# existing users, → INKNOTE_ADMIN_USER names which of them becomes admin. -# no admin yet Without it, the oldest account is promoted. -# an admin exists → both are ignored entirely -# -# So they can never reset an existing password or take rights away; the worst -# they can do on a running instance is nothing. -INKNOTE_ADMIN_USER= -INKNOTE_ADMIN_PASSWORD= - -# ── Optional ── -# PORT=4000 -# ALLOWED_ORIGINS= # only if the UI is served from another host -# MAX_VERSIONS_PER_NOTE=50 -# VERSION_RETENTION_DAYS=90 -# VERSION_COALESCE_MINUTES=5 diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index caa207b..64de105 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -29,6 +29,11 @@ services: - INKNOTE_ADMIN_USER=${INKNOTE_ADMIN_USER:-} - INKNOTE_ADMIN_PASSWORD=${INKNOTE_ADMIN_PASSWORD:-} - NODE_ENV=development + # Optional tuning; unset means the server's own defaults apply. + - ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-} + - MAX_VERSIONS_PER_NOTE=${MAX_VERSIONS_PER_NOTE:-} + - VERSION_RETENTION_DAYS=${VERSION_RETENTION_DAYS:-} + - VERSION_COALESCE_MINUTES=${VERSION_COALESCE_MINUTES:-} # Bind mounts, not named volumes: the data sits in a plain directory on the # Docker host where the host's own backup picks it up. user: "${INKNOTE_UID:-1000}:${INKNOTE_GID:-1000}" diff --git a/docker-compose.yml b/docker-compose.yml index 9778cee..354ff79 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,6 +27,11 @@ services: - INKNOTE_ADMIN_USER=${INKNOTE_ADMIN_USER:-} - INKNOTE_ADMIN_PASSWORD=${INKNOTE_ADMIN_PASSWORD:-} - NODE_ENV=production + # Optional tuning; unset means the server's own defaults apply. + - ALLOWED_ORIGINS=${ALLOWED_ORIGINS:-} + - MAX_VERSIONS_PER_NOTE=${MAX_VERSIONS_PER_NOTE:-} + - VERSION_RETENTION_DAYS=${VERSION_RETENTION_DAYS:-} + - VERSION_COALESCE_MINUTES=${VERSION_COALESCE_MINUTES:-} # Bind mounts, not named volumes: the data sits in a plain directory on the # Docker host, so whatever backs up the host also backs up InkNote. # Create it first: mkdir -p /srv/inknote/{db,uploads} && chown -R 1000:1000 /srv/inknote diff --git a/readme.md b/readme.md index 0d97d34..dfc78e4 100644 --- a/readme.md +++ b/readme.md @@ -42,13 +42,13 @@ A cross-platform note-taking application with rich text editing, freehand drawin inknote/ ├── docker-compose.yml # Deploy from the Gitea registry ├── docker-compose.dev.yml # Build from source for local work +├── .env.example # Copy to .env — Compose reads it from here ├── build.sh # Build & push images to Gitea ├── backend/ │ ├── server.js # Express API + WebSocket server │ ├── sync-client.js # Client-side sync engine library │ ├── package.json # Node dependencies -│ ├── Dockerfile # Server container -│ └── .env.example # Environment variable template +│ └── Dockerfile # Server container ├── frontend/ │ ├── src/ │ │ ├── App.jsx # Root: where the user is, which dialog is open