mirror of
https://github.com/ether/etherpad-lite.git
synced 2026-07-17 16:47:05 +00:00
* docs: design spec for #7524 drop swagger-ui + privacy opt-outs Three-deliverable plan: vendor RapiDoc to replace swagger-ui-express (Scarf-injecting), add privacy.updateCheck and privacy.pluginCatalog opt-outs for our two outbound calls, and ship PRIVACY.md as a public stance doc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: implementation plan for #7524 swagger-ui + privacy opt-outs Twelve TDD-flavoured tasks: privacy settings shape, UpdateCheck + installer opt-outs (each with a failing-test-first cycle), admin backend/UI plumbing, dependency drop, vendored RapiDoc, PRIVACY.md, final verification matrix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(privacy): add privacy block to settings shape Adds privacy.updateCheck and privacy.pluginCatalog, both defaulting to true so behavior is unchanged until operators opt out. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(privacy): honour privacy.updateCheck=false in UpdateCheck check() and getLatestVersion() now early-return when the setting is off. Logs once on first skip. The admin "update available" panel already tolerates an undefined latestVersion. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(privacy): honour privacy.pluginCatalog=false in installer Extracts the gate into pluginCatalogGuard.ts so it can be unit-tested under vitest without dragging in the CJS require() chain from installer.ts. getAvailablePlugins() now throws the tagged disabled error before any fetch. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(privacy): emit results:catalogDisabled when pluginCatalog off Short-circuits the four catalog-driven socket events. The install/ uninstall events are untouched so operators can still install by plugin name even when the catalog is disabled. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(bin): stalePlugins reads updateServer and honours privacy flag Was hardcoding static.etherpad.org and ignoring opt-out. Now exits 0 cleanly when privacy.pluginCatalog=false. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(settings): document privacy block in settings template Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(api-docs): replace swagger-ui-express with RapiDoc shell Drops the swagger-ui-express dep (third-party Scarf telemetry pixel, see swagger-api/swagger-ui#10573) and serves /api-docs with a static HTML shell that mounts <rapi-doc>. /api-docs.json is unchanged. The vendored RapiDoc asset is added in the next commit so the tree is broken for one diff hunk — pair this with the rapidoc-min.js commit during review. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(api-docs): vendor RapiDoc 9.3.4 (MIT) as static asset Pinned bundle with checksum in VERSION. Replaces swagger-ui-dist which shipped a Scarf telemetry pixel. Disables RapiDoc's bundled Google Fonts request via load-fonts="false" plus explicit regular-font/mono-font system stacks — RapiDoc's CSS @font-face rules would otherwise fetch Open Sans from fonts.gstatic.com at render time. Also fixes the /api-docs route's res.sendFile to use an absolute path resolved via settings.root (the previous {root: 'src/static'} was resolved from CWD which is already src/, producing src/src/static). Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * feat(admin): banner when plugin catalog is disabled Subscribes to results:catalogDisabled and renders a localized info banner on the plugins page. install/uninstall still function via CLI. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs: PRIVACY.md and README/CHANGELOG pointers Publishes Etherpad's stance on telemetry: two documented, opt-out outbound calls; no third-party analytics; no install-time phone-homes in our deps. Refs #7524 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(admin): await checkPluginForUpdates and emit array on error Qodo flagged that checkUpdates emitted the unresolved Promise (missing await) and emitted {} for updatable on the error path, both breaking the admin UI's expected string[] shape. Pre-existing bug surfaced when the surrounding block was edited for the privacy.pluginCatalog gate. Refs #7524 * feat(api-docs): swap RapiDoc for Scalar (actively maintained) Per @SamTV12345's review on #7757: RapiDoc has been effectively unmaintained for a while. Scalar (https://github.com/scalar/scalar) is MIT-licensed, actively developed, and ships a self-contained standalone bundle that works the same way for our purposes. Privacy posture is preserved by configuring the embed: - withDefaultFonts: false (no fonts.scalar.com woff2 fetch) - telemetry: false (defensive) - agent.disabled: true (no api.scalar.com/vector/* calls) - mcp.disabled: true (no MCP integration) - showDeveloperTools: 'never' - hideClientButton: true Verified with headless Chromium: page loads /api-docs, mounts Scalar, renders the Etherpad OpenAPI document, and makes zero requests to any host other than localhost. Vendor: - src/static/vendor/scalar/standalone.js (@scalar/api-reference 1.57.2) - src/static/vendor/scalar/VERSION (sha256 pinned) - src/static/vendor/scalar/LICENSE (MIT) Removed: - src/static/vendor/rapidoc/* Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
375 lines
15 KiB
Markdown
375 lines
15 KiB
Markdown
# Etherpad — the editor for documents that matter
|
|
|
|
> Real-time collaborative editing where authorship is the default, your server is the only server, and you decide what AI (if any) ever touches your text.
|
|
|
|

|
|
|
|
## About
|
|
|
|
**Etherpad is a real-time collaborative editor for documents that matter.**
|
|
|
|
Every keystroke is attributed to its author. Every revision is preserved. The timeslider lets you scrub through a document's entire history, character by character. Author colours make collaboration visible at a glance — not buried in a menu.
|
|
|
|
Etherpad runs on your server, under your governance. No telemetry. No upsells. AI is a plugin you install, pointed at the model you choose, running on infrastructure you control — not a feature decided for you in a boardroom you weren't in. See [PRIVACY.md](PRIVACY.md) for the two opt-out network calls Etherpad's own code makes and how to disable each.
|
|
|
|
The code is Apache 2.0. The data format is open. It [scales to thousands of simultaneous editors per pad](http://scale.etherpad.org/). Translated into 105 languages. Extended through hundreds of plugins. Used by Wikimedia, governments, public-sector institutions, and self-hosters worldwide since 2009.
|
|
|
|
[Full data export](https://github.com/ether/etherpad/wiki/Understanding-Etherpad's-Full-Data-Export-capabilities) is built in. The history is yours.
|
|
|
|
## Try it out
|
|
|
|
[Try out a public Etherpad instance](https://scanner.etherpad.org)
|
|
|
|
## Project Status
|
|
|
|
Etherpad has been doing the same thing — well — since 2009. No pivots, no acquisitions, no enshittification. Maintained by a small volunteer team.
|
|
|
|
**We are actively looking for maintainers.** If you have experience with Node.js, real-time systems, or institutional collaboration tooling and you want to work on infrastructure that thousands of organisations quietly depend on, please [open an issue](https://github.com/ether/etherpad/issues) or contact [John McLear](https://github.com/JohnMcLear).
|
|
|
|
### Code Quality
|
|
|
|
[](https://github.com/ether/etherpad/actions/workflows/codeql-analysis.yml)
|
|
|
|
### Testing
|
|
|
|
[](https://github.com/ether/etherpad/actions/workflows/backend-tests.yml)
|
|
[](https://github.com/ether/etherpad/actions/workflows/load-test.yml)
|
|
[](https://github.com/ether/etherpad/actions/workflows/rate-limit.yml)
|
|
[](https://github.com/ether/etherpad/actions/workflows/docker.yml)
|
|
[](https://github.com/ether/etherpad/actions/workflows/frontend-admin-tests.yml)
|
|
[](https://github.com/ether/etherpad/actions/workflows/frontend-tests.yml)
|
|
|
|
### Engagement
|
|
|
|
[](https://hub.docker.com/r/etherpad/etherpad)
|
|
[](https://discord.com/invite/daEjfhw)
|
|
[](https://etherpad.org/plugins)
|
|

|
|

|
|
|
|
## Who uses Etherpad
|
|
|
|
For more than a decade, Etherpad has quietly underpinned the documents that matter to:
|
|
|
|
- **Wikimedia Foundation** — collaborative drafting across editor communities.
|
|
- **Public-sector institutions across the EU** — including organisations that legally cannot use US-cloud SaaS for sovereignty and GDPR reasons.
|
|
- **Universities and schools worldwide** — including jurisdictions where Google Workspace is no longer permitted in education.
|
|
- **Civic-tech and democratic-deliberation projects** — citizen assemblies, participatory budgeting, public consultations.
|
|
- **Newsrooms and investigative journalism teams** — where authorship and editing history matter for legal and editorial integrity.
|
|
- **Tens of thousands of self-hosted instances** worldwide, run by IT teams who chose Etherpad because it is theirs.
|
|
|
|
[Public Etherpad Instances for you to try out. Third party instances not provided by the Etherpad foundation](https://scanner.etherpad.org/).
|
|
|
|
## Installation
|
|
|
|
### Quick install (one-liner)
|
|
|
|
The fastest way to get Etherpad running. Requires `git` and Node.js >= 24.
|
|
|
|
**macOS / Linux / WSL:**
|
|
|
|
```sh
|
|
curl -fsSL https://raw.githubusercontent.com/ether/etherpad/master/bin/installer.sh | sh
|
|
```
|
|
|
|
**Windows (PowerShell):**
|
|
|
|
```powershell
|
|
irm https://raw.githubusercontent.com/ether/etherpad/master/bin/installer.ps1 | iex
|
|
```
|
|
|
|
Both installers clone Etherpad into `./etherpad-lite`, install dependencies, and
|
|
build the frontend. When the installer finishes, run:
|
|
|
|
```sh
|
|
cd etherpad-lite && pnpm run prod
|
|
```
|
|
|
|
Then open <http://localhost:9001>.
|
|
|
|
To install and start in one go:
|
|
|
|
```sh
|
|
# macOS / Linux / WSL
|
|
ETHERPAD_RUN=1 sh -c "$(curl -fsSL https://raw.githubusercontent.com/ether/etherpad/master/bin/installer.sh)"
|
|
```
|
|
|
|
```powershell
|
|
# Windows
|
|
$env:ETHERPAD_RUN=1; irm https://raw.githubusercontent.com/ether/etherpad/master/bin/installer.ps1 | iex
|
|
```
|
|
|
|
### Docker-Compose
|
|
|
|
The official image is published to both Docker Hub (`etherpad/etherpad`) and GitHub Container Registry (`ghcr.io/ether/etherpad`) with identical tags. Use whichever suits your environment; GHCR avoids Docker Hub's anonymous pull rate limits.
|
|
|
|
```yaml
|
|
services:
|
|
app:
|
|
user: "0:0"
|
|
image: etherpad/etherpad:latest # or: ghcr.io/ether/etherpad:latest
|
|
tty: true
|
|
stdin_open: true
|
|
volumes:
|
|
- plugins:/opt/etherpad-lite/src/plugin_packages
|
|
- etherpad-var:/opt/etherpad-lite/var
|
|
depends_on:
|
|
- postgres
|
|
environment:
|
|
NODE_ENV: production
|
|
ADMIN_PASSWORD: ${DOCKER_COMPOSE_APP_ADMIN_PASSWORD:-admin}
|
|
DB_CHARSET: ${DOCKER_COMPOSE_APP_DB_CHARSET:-utf8mb4}
|
|
DB_HOST: postgres
|
|
DB_NAME: ${DOCKER_COMPOSE_POSTGRES_DATABASE:-etherpad}
|
|
DB_PASS: ${DOCKER_COMPOSE_POSTGRES_PASSWORD:-admin}
|
|
DB_PORT: ${DOCKER_COMPOSE_POSTGRES_PORT:-5432}
|
|
DB_TYPE: "postgres"
|
|
DB_USER: ${DOCKER_COMPOSE_POSTGRES_USER:-admin}
|
|
# For now, the env var DEFAULT_PAD_TEXT cannot be unset or empty; it seems to be mandatory in the latest version of etherpad
|
|
DEFAULT_PAD_TEXT: ${DOCKER_COMPOSE_APP_DEFAULT_PAD_TEXT:- }
|
|
DISABLE_IP_LOGGING: ${DOCKER_COMPOSE_APP_DISABLE_IP_LOGGING:-false}
|
|
SOFFICE: ${DOCKER_COMPOSE_APP_SOFFICE:-null}
|
|
TRUST_PROXY: ${DOCKER_COMPOSE_APP_TRUST_PROXY:-true}
|
|
restart: always
|
|
ports:
|
|
- "${DOCKER_COMPOSE_APP_PORT_PUBLISHED:-9001}:${DOCKER_COMPOSE_APP_PORT_TARGET:-9001}"
|
|
|
|
postgres:
|
|
image: postgres:15-alpine
|
|
environment:
|
|
POSTGRES_DB: ${DOCKER_COMPOSE_POSTGRES_DATABASE:-etherpad}
|
|
POSTGRES_PASSWORD: ${DOCKER_COMPOSE_POSTGRES_PASSWORD:-admin}
|
|
POSTGRES_PORT: ${DOCKER_COMPOSE_POSTGRES_PORT:-5432}
|
|
POSTGRES_USER: ${DOCKER_COMPOSE_POSTGRES_USER:-admin}
|
|
PGDATA: /var/lib/postgresql/data/pgdata
|
|
restart: always
|
|
# Exposing the port is not needed unless you want to access this database instance from the host.
|
|
# Be careful when other postgres docker container are running on the same port
|
|
# ports:
|
|
# - "5432:5432"
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
|
|
volumes:
|
|
postgres_data:
|
|
plugins:
|
|
etherpad-var:
|
|
```
|
|
|
|
### Requirements
|
|
|
|
[Node.js](https://nodejs.org/) >= 24.
|
|
|
|
### Windows, macOS, Linux
|
|
|
|
1. Download the latest Node.js runtime from [nodejs.org](https://nodejs.org/).
|
|
2. Install pnpm: `npm install -g pnpm` (Administrator privileges may be required).
|
|
3. Clone the repository: `git clone -b master`
|
|
4. Run `pnpm i`
|
|
5. Run `pnpm run build:etherpad`
|
|
6. Run `pnpm run prod`
|
|
7. Visit `http://localhost:9001` in your browser.
|
|
|
|
### Docker container
|
|
|
|
Find [here](doc/docker.adoc) information on running Etherpad in a container.
|
|
|
|
## Plugins
|
|
|
|
Etherpad is very customizable through plugins.
|
|
|
|

|
|
|
|

|
|
|
|
### Available Plugins
|
|
|
|
For a list of available plugins, see the [plugins
|
|
site](https://static.etherpad.org).
|
|
|
|
### Plugin Installation
|
|
|
|
You can install plugins from the admin web interface (e.g.,
|
|
http://127.0.0.1:9001/admin/plugins).
|
|
|
|
Alternatively, you can install plugins from the command line:
|
|
|
|
```sh
|
|
cd /path/to/etherpad-lite
|
|
pnpm run plugins i ep_${plugin_name}
|
|
```
|
|
|
|
Also see [the plugin wiki
|
|
article](https://github.com/ether/etherpad/wiki/Available-Plugins).
|
|
|
|
### Suggested Plugins
|
|
|
|
Run the following command in your Etherpad folder to get all of the features
|
|
visible in the above demo gif:
|
|
|
|
```sh
|
|
pnpm run plugins i \
|
|
ep_align \
|
|
ep_comments_page \
|
|
ep_embedded_hyperlinks2 \
|
|
ep_font_color \
|
|
ep_headings2 \
|
|
ep_markdown \
|
|
ep_webrtc
|
|
```
|
|
|
|
For user authentication, you are encouraged to run an [OpenID
|
|
Connect](https://openid.net/connect/) identity provider (OP) and install the
|
|
following plugins:
|
|
|
|
* [ep_openid_connect](https://github.com/ether/ep_openid_connect#readme) to
|
|
authenticate against your OP.
|
|
* [ep_guest](https://github.com/ether/ep_guest#readme) to create a
|
|
"guest" account that has limited access (e.g., read-only access).
|
|
* [ep_user_displayname](https://github.com/ether/ep_user_displayname#readme)
|
|
to automatically populate each user's displayed name from your OP.
|
|
* [ep_stable_authorid](https://github.com/ether/ep_stable_authorid#readme) so
|
|
that each user's chosen color, display name, comment ownership, etc. is
|
|
strongly linked to their account.
|
|
|
|
### Upgrade Etherpad
|
|
|
|
Run the following command in your Etherpad folder to upgrade
|
|
|
|
1. Stop any running Etherpad (manual, systemd ...)
|
|
2. Get present version
|
|
```sh
|
|
git -P tag --contains
|
|
```
|
|
3. List versions available
|
|
```sh
|
|
git -P tag --list "v*" --merged
|
|
```
|
|
4. Select the version
|
|
```sh
|
|
git checkout v2.2.5
|
|
git switch -c v2.2.5
|
|
```
|
|
5. Upgrade Etherpad
|
|
```sh
|
|
./bin/run.sh
|
|
```
|
|
6. Stop with [CTRL-C]
|
|
7. Restart your Etherpad service
|
|
|
|
## Next Steps
|
|
|
|
### Tweak the settings
|
|
|
|
You can modify the settings in `settings.json`. If you need to handle multiple
|
|
settings files, you can pass the path to a settings file to `bin/run.sh`
|
|
using the `-s|--settings` option: this allows you to run multiple Etherpad
|
|
instances from the same installation. Similarly, `--credentials` can be used to
|
|
give a settings override file, `--apikey` to give a different APIKEY.txt file
|
|
and `--sessionkey` to give a non-default `SESSIONKEY.txt`. **Each configuration
|
|
parameter can also be set via an environment variable**, using the syntax
|
|
`"${ENV_VAR}"` or `"${ENV_VAR:default_value}"`. For details, refer to
|
|
`settings.json.template`. Once you have access to your `/admin` section,
|
|
settings can be modified through the web browser.
|
|
|
|
If you are planning to use Etherpad in a production environment, you should use
|
|
a dedicated database such as `mysql`, since the `dirtyDB` database driver is
|
|
only for testing and/or development purposes.
|
|
|
|
### Secure your installation
|
|
|
|
If you have enabled authentication in `users` section in `settings.json`, it is
|
|
a good security practice to **store hashes instead of plain text passwords** in
|
|
that file. This is _especially_ advised if you are running a production
|
|
installation.
|
|
|
|
Please install [ep_hash_auth plugin](https://www.npmjs.com/package/ep_hash_auth)
|
|
and configure it. If you prefer, `ep_hash_auth` also gives you the option of
|
|
storing the users in a custom directory in the file system, without having to
|
|
edit `settings.json` and restart Etherpad each time.
|
|
|
|
### Customize the style with skin variants
|
|
|
|
Open http://127.0.0.1:9001/p/test#skinvariantsbuilder in your browser and start
|
|
playing!
|
|
|
|

|
|
|
|
## Helpful resources
|
|
|
|
The [wiki](https://github.com/ether/etherpad/wiki) is your one-stop
|
|
resource for Tutorials and How-to's.
|
|
|
|
Documentation can be found in `doc/`.
|
|
|
|
## Development
|
|
|
|
### Things you should know
|
|
|
|
You can debug Etherpad using `bin/debugRun.sh`.
|
|
|
|
You can run Etherpad quickly launching `bin/fastRun.sh`. It's convenient for
|
|
developers and advanced users. Be aware that it will skip the dependencies
|
|
update, so remember to run `bin/installDeps.sh` after installing a new
|
|
dependency or upgrading version.
|
|
|
|
If you want to find out how Etherpad's `Easysync` works (the library that makes
|
|
it really realtime), start with this
|
|
[PDF](https://github.com/ether/etherpad/raw/master/doc/easysync/easysync-full-description.pdf)
|
|
(complex, but worth reading).
|
|
|
|
### Contributing
|
|
|
|
Read our [**Developer
|
|
Guidelines**](https://github.com/ether/etherpad/blob/master/CONTRIBUTING.md)
|
|
|
|
### HTTP API
|
|
|
|
Etherpad is designed to be easily embeddable and provides a [HTTP
|
|
API](https://github.com/ether/etherpad/wiki/HTTP-API) that allows your web
|
|
application to manage pads, users and groups. It is recommended to use the
|
|
[available client
|
|
implementations](https://github.com/ether/etherpad/wiki/HTTP-API-client-libraries)
|
|
in order to interact with this API.
|
|
|
|
OpenAPI (previously swagger) definitions for the API are exposed under
|
|
`/api/openapi.json`.
|
|
|
|
### jQuery plugin
|
|
|
|
There is a [jQuery plugin](https://github.com/ether/etherpad-lite-jquery-plugin)
|
|
that helps you to embed Pads into your website.
|
|
|
|
### Plugin Framework
|
|
|
|
Etherpad offers a plugin framework, allowing you to easily add your own
|
|
features. By default your Etherpad is extremely light-weight and it's up to you
|
|
to customize your experience. Once you have Etherpad installed you should [visit
|
|
the plugin page](https://static.etherpad.org/) and take control.
|
|
|
|
### Translations / Localizations (i18n / l10n)
|
|
|
|
Etherpad comes with translations into all languages thanks to the team at
|
|
[TranslateWiki](https://translatewiki.net/).
|
|
|
|
If you require translations in [plugins](https://static.etherpad.org/) please
|
|
send pull request to each plugin individually.
|
|
|
|
## FAQ
|
|
|
|
Visit the **[FAQ](https://github.com/ether/etherpad/wiki/FAQ)**.
|
|
|
|
## Get in touch
|
|
|
|
The official channel for contacting the development team is via the [GitHub
|
|
issues](https://github.com/ether/etherpad/issues).
|
|
|
|
For **responsible disclosure of vulnerabilities**, please write a mail to the
|
|
maintainers (a.mux@inwind.it and contact@etherpad.org).
|
|
|
|
Join the official [Etherpad Discord
|
|
Channel](https://discord.com/invite/daEjfhw).
|
|
|
|
## License
|
|
|
|
[Apache License v2](http://www.apache.org/licenses/LICENSE-2.0.html)
|