mirror of
https://github.com/ether/etherpad-lite.git
synced 2026-07-18 00:57:55 +00:00
* docs: migrate useful wiki content into the VitePress manual (#7990) The GitHub wiki is being retired; documentation should ship with the software. This migrates the still-accurate, non-duplicate wiki pages into the published VitePress site (doc/**/*.md + the sidebar in doc/.vitepress/config.mts) so they are versioned, searchable and portable: - deployment.md: reverse-proxy configs (Nginx/Apache/Caddy/Traefik/ HAProxy) with the WebSocket-upgrade rules, subdirectory hosting via X-Proxy-Path, native HTTPS via the ssl block, a systemd unit, and the Istio manifest (with the Redis-adapter multi-replica caveat). - accessibility.md: editor keyboard shortcuts (verified against ace2_inner.ts / broadcast_slider.ts / pad_editbar.ts), toolbar navigation, NVDA notes. - faq.md: install methods, URL-path reference, listing/deleting pads (API-first), backup/restore, and history pruning. - development.md: source-tree tour, the pad<->format conversion pipeline, the internal DB API, and the Fontello toolbar-icon workflow. - database.md: the key/value schema plus connecting MySQL/PostgreSQL/Redis backends and a pgloader MySQL->PostgreSQL migration (database docs were previously absent from the VitePress site). Every page was checked against the current source before inclusion: corrected the apt instructions to the live signed repo (stable/main, signed-by key), dropped the unpublished snap, fixed the Redis dbSettings (flat host/port/password or url, not the obsolete client_options), dropped charset from the PostgreSQL example, and removed a phantom getEtherpad API reference. The VitePress site builds cleanly (pnpm run docs:build) with the dead-link checker enabled. Closes #7990 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: add verified hands-on changeset/atext walkthrough (#7990) Migrate the practical Changeset-library tutorial from the wiki into changeset_library.md, rewritten against the current API: unpack(), deserializeOps() (replacing the deprecated opIterator) and new AttributePool() (replacing the removed AttributePoolFactory). Every example output was produced by running the code against the current Changeset.ts / AttributePool.ts, not copied from the wiki. Also fixes a stale ether/etherpad-lite source link. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
204 lines
5.8 KiB
Markdown
204 lines
5.8 KiB
Markdown
# Database structure
|
|
|
|
## Keys and their values
|
|
|
|
### groups
|
|
A list of all existing groups (a JSON object with groupIDs as keys and `1` as values).
|
|
|
|
### pad:$PADID
|
|
Contains all information about pads
|
|
|
|
- **atext** - the latest attributed text
|
|
- **pool** - the attribute pool
|
|
- **head** - the number of the latest revision
|
|
- **chatHead** - the number of the latest chat entry
|
|
- **public** - flag that disables security for this pad
|
|
- **passwordHash** - string that contains a salted sha512 sum of this pad's password
|
|
|
|
### pad:$PADID:revs:$REVNUM
|
|
Saves a revision $REVNUM of pad $PADID
|
|
|
|
- **meta**
|
|
- **author** - the autorID of this revision
|
|
- **timestamp** - the timestamp of when this revision was created
|
|
- **changeset** - the changeset of this revision
|
|
|
|
### pad:$PADID:chat:$CHATNUM
|
|
Saves a chat entry with num $CHATNUM of pad $PADID
|
|
|
|
- **text** - the text of this chat entry
|
|
- **userId** - the authorID of this chat entry
|
|
- **time** - the timestamp of this chat entry
|
|
|
|
### pad2readonly:$PADID
|
|
Translates a padID to a readonlyID
|
|
|
|
### readonly2pad:$READONLYID
|
|
Translates a readonlyID to a padID
|
|
|
|
### token2author:$TOKENID
|
|
Translates a token to an authorID
|
|
|
|
### globalAuthor:$AUTHORID
|
|
Information about an author
|
|
|
|
- **name** - the name of this author as shown in the pad
|
|
- **colorID** - the colorID of this author as shown in the pad
|
|
|
|
### mapper2group:$MAPPER
|
|
Maps an external application identifier to an internal group
|
|
|
|
### mapper2author:$MAPPER
|
|
Maps an external application identifier to an internal author
|
|
|
|
### group:$GROUPID
|
|
a group of pads
|
|
|
|
- **pads** - object with pad names in it, values are 1
|
|
|
|
### session:$SESSIONID
|
|
a session between an author and a group
|
|
|
|
- **groupID** - the groupID the session belongs too
|
|
- **authorID** - the authorID the session belongs too
|
|
- **validUntil** - the timestamp until this session is valid
|
|
|
|
### author2sessions:$AUTHORID
|
|
saves the sessions of an author
|
|
|
|
- **sessionsIDs** - object with sessionIDs in it, values are 1
|
|
|
|
### group2sessions:$GROUPID
|
|
|
|
- **sessionsIDs** - object with sessionIDs in it, values are 1
|
|
|
|
# Connecting to a database backend
|
|
|
|
Etherpad stores everything in a single key/value table through
|
|
[ueberDB](https://www.npmjs.com/package/ueberdb2), so the same data model works
|
|
across many backends. The backend is selected with `dbType` in `settings.json`,
|
|
and backend-specific connection options go in `dbSettings`.
|
|
|
|
The default `dirty` backend writes to a local file (`var/dirty.db`) and needs no
|
|
setup, which is convenient for development but not recommended for production.
|
|
For a production instance, point Etherpad at a real database such as MySQL/MariaDB,
|
|
PostgreSQL or Redis. Etherpad creates its own table on first run; you only need
|
|
to provision an empty database and a user with access to it.
|
|
|
|
## MySQL / MariaDB
|
|
|
|
Create the database and a user, then grant access:
|
|
|
|
```sql
|
|
CREATE DATABASE `etherpad` CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
|
CREATE USER 'etherpad'@'localhost' IDENTIFIED BY 'a-secure-password';
|
|
GRANT CREATE,ALTER,SELECT,INSERT,UPDATE,DELETE ON `etherpad`.* TO 'etherpad'@'localhost';
|
|
```
|
|
|
|
Then configure `settings.json`:
|
|
|
|
```json
|
|
"dbType": "mysql",
|
|
"dbSettings": {
|
|
"user": "etherpad",
|
|
"host": "localhost",
|
|
"port": 3306,
|
|
"password": "a-secure-password",
|
|
"database": "etherpad",
|
|
"charset": "utf8mb4"
|
|
}
|
|
```
|
|
|
|
Setting `charset` to `utf8mb4` is strongly recommended so that the full range of
|
|
Unicode (including emoji) is stored correctly. To connect over a local socket
|
|
instead of TCP, replace `host`/`port` with `"socketPath": "/var/run/mysqld/mysqld.sock"`.
|
|
|
|
## PostgreSQL
|
|
|
|
Create the user and a database owned by it:
|
|
|
|
```sql
|
|
CREATE USER etherpad WITH PASSWORD 'a-secure-password';
|
|
CREATE DATABASE etherpad OWNER etherpad;
|
|
```
|
|
|
|
Then configure `settings.json`:
|
|
|
|
```json
|
|
"dbType": "postgres",
|
|
"dbSettings": {
|
|
"user": "etherpad",
|
|
"host": "localhost",
|
|
"port": 5432,
|
|
"password": "a-secure-password",
|
|
"database": "etherpad"
|
|
}
|
|
```
|
|
|
|
The `dbSettings` object is passed straight to the `node-postgres` connection
|
|
pool, so any option it accepts (including a single `"connectionString"`) works.
|
|
On Debian/Ubuntu you can use peer authentication over the local socket by
|
|
setting `"host": "/var/run/postgresql"` and an empty password, provided the
|
|
operating-system user that runs Etherpad matches the PostgreSQL role.
|
|
|
|
## Redis
|
|
|
|
Install Redis and make sure it persists data to disk. Configure `settings.json`
|
|
with either discrete fields or a single connection URL:
|
|
|
|
```json
|
|
"dbType": "redis",
|
|
"dbSettings": {
|
|
"host": "localhost",
|
|
"port": 6379,
|
|
"password": "a-secure-redis-password"
|
|
}
|
|
```
|
|
|
|
```json
|
|
"dbType": "redis",
|
|
"dbSettings": {
|
|
"url": "redis://:a-secure-redis-password@localhost:6379"
|
|
}
|
|
```
|
|
|
|
## Migrating from MySQL to PostgreSQL
|
|
|
|
[pgloader](https://pgloader.io/) can copy an existing Etherpad database from
|
|
MySQL to PostgreSQL. Stop Etherpad first so the source database is quiescent.
|
|
|
|
```bash
|
|
sudo apt-get install postgresql pgloader
|
|
|
|
# Create the target role and database
|
|
sudo -u postgres createuser etherpad
|
|
sudo -u postgres createdb -O etherpad etherpad
|
|
|
|
# Describe and run the migration
|
|
cat > pgloader.load <<'EOF'
|
|
LOAD DATABASE
|
|
FROM mysql://etherpad:MYSQL_PASSWORD@127.0.0.1/etherpad
|
|
INTO postgresql:///etherpad
|
|
WITH preserve index names, prefetch rows = 100
|
|
ALTER SCHEMA 'etherpad' RENAME TO 'public';
|
|
EOF
|
|
|
|
pgloader --verbose pgloader.load
|
|
```
|
|
|
|
Afterwards set the PostgreSQL user's password and make sure it can read and
|
|
write the migrated table:
|
|
|
|
```sql
|
|
ALTER USER etherpad WITH PASSWORD 'a-secure-password';
|
|
GRANT pg_read_all_data TO etherpad;
|
|
GRANT pg_write_all_data TO etherpad;
|
|
```
|
|
|
|
Then point `settings.json` at PostgreSQL as shown above and start Etherpad.
|
|
|
|
::: tip
|
|
To move data between *any* two backends supported by ueberDB, you can also
|
|
use the `migrateDB` CLI tool, which reads every record from a source database
|
|
descriptor and writes it to a target one. See the [CLI chapter](./cli.md).
|
|
:::
|