Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
299 changes: 172 additions & 127 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,107 @@
# cryptpad-server

[![Build cryptpad](https://github.com/Scille/cryptpad-server/actions/workflows/build.yml/badge.svg)](https://github.com/Scille/cryptpad-server/actions/workflows/build.yml) [![Build & Publish docker cryptpad](https://github.com/Scille/cryptpad-server/actions/workflows/docker-cryptpad.yml/badge.svg)](https://github.com/Scille/cryptpad-server/actions/workflows/docker-cryptpad.yml) ![GitHub Release](https://img.shields.io/github/v/release/Scille/cryptpad-server?display_name=release&style=flat&logoSize=auto)

A Parsec-compatible distribution of [CryptPad](https://cryptpad.org) for self-hosted (on-premise) deployments.

This repository packages a specific version of CryptPad together with the customizations required for integration with [Parsec](https://parsec.cloud), and provides two installation methods: direct install (Node.js) and Docker.

## Prerequisites
## Install

- **Node.js** v20 or v22
- **npm** v10+
- **Git**
- Linux/macOS: `rsync`, `unzip`, `rdfind` (for the compression step — install via your package manager, see `Aptfile`)
- For OnlyOffice support: `unzip`
We recommend that you install CryptPad using Docker

## Installation
```bash
docker pull ghcr.io/scille/cryptpad-server/cryptpad:latest
```

### Method 1 — Direct install (Node.js)
### Install Without Docker

**1. Clone this repository**
- Download our built server from [the latest release](https://github.com/Scille/cryptpad-server/releases/latest):

```bash
git clone https://github.com/Scille/cryptpad-server.git
cd cryptpad-server
```
Download the asset `cryptpad-server.zip` from the release:

**2. Install system dependencies** (Debian/Ubuntu)
You can use [GitHub CLI](https://cli.github.com/) to download the archive from the latest release:

```bash
sudo apt-get install -y $(cat Aptfile)
```
```bash
gh release download --pattern cryptpad-server.zip
```

**3. Build**
Once the archive obtained, extract it:

```bash
# Full build including OnlyOffice
npm run build
```
```bash
unzip -d cryptpad cryptpad-server.zip
```

The build script will:
- Clone the CryptPad source at the pinned commit
- Install Node.js dependencies
- Build frontend assets
- Install OnlyOffice (unless skipped)
- Copy the Parsec customizations from `./resources/` into the CryptPad directory
- [Manually build the server from the sources](#build-from-sources)

**4. Configure**
## Startup with Docker

```bash
cp .env.example .env
# Edit .env and set at minimum CRYPTPAD_HTTP_UNSAFE_ORIGIN and CRYPTPAD_HTTP_SAFE_ORIGIN
```
1. [Configure the env variables file](#configure-env-variables-file)

**5. Start**
2. Start the container with:

```bash
npm run start
```
```bash
docker run -d \
--name cryptpad-server \
--restart unless-stopped \
-p 3000:3000 -p 3003:3003 \
-v cryptpad_data:/app/cryptpad/data \
-v cryptpad_datastore:/app/cryptpad/datastore \
-v cryptpad_blob:/app/cryptpad/blob \
-v cryptpad_block:/app/cryptpad/block \
-v cryptpad_customize:/app/cryptpad/customize \
--env-file .env \
ghcr.io/scille/cryptpad-server/cryptpad:latest
```

> [!NOTE]
> The command configures some [paths that need to be persisted](#data-persistence)

## Startup with Docker Compose

1. [Configure the env variables file](#configure-env-variables-file)

2. We provide a minimal `docker-compose` stack here: [docker-compose.yml](./docker-compose.yml).

```bash
docker compose -f ./docker-compose.yml up
```

The stack will expose the service through the port `3000` (main) and `3003` (websocket) by default.

> [!NOTE]
> The stack will automatically create volume for the [data that need to be made persistent](#data-persistence)

## Startup Without Docker

1. [Configure the env variables file](#configure-env-variables-file)

1. Go into the `cryptpad` directory

```bash
cd cryptpad
```

The server listens on port `3000` by default.
> [!NOTE]
> You obtained the `cryptpad` directory after following the instructions to [install CryptPad without Docker](#install-without-docker).

**6. Keep the server running (production)**
2. Start the server:

Install [PM2](https://pm2.keymetrics.io/), a Node.js process manager that handles auto-restart and survives reboots:
You can either:

- Do it with `npm`:

```bash
npm run start
```

- Or directly with `nodejs`:

```bash
node server.js
```

For a more permanent solution, you can use [PM2](https://pm2.keymetrics.io/) to manage the process:

```bash
npm install -g pm2
Expand All @@ -79,121 +120,125 @@ pm2 restart cryptpad
pm2 stop cryptpad
```

> For Linux servers that prefer native systemd, an example unit file is available at `scripts/cryptpad-server.service`.
We also provide a systemd unit file as an example that can be found here: [`scripts/cryptpad-server.service`](./scripts/cryptpad-server.service).

**7. Set up a reverse proxy with nginx (production)**
## Build from Sources

CryptPad requires **two separate domains** (main + sandbox) and needs TLS in production.
A ready-to-edit nginx config is provided at `scripts/nginx.example.conf`.
### Build Prerequisites

```bash
# Install nginx and certbot
sudo apt-get install -y nginx python3-certbot-nginx
- **Node.js** v22
- **npm** v10+
- **Git**
- Linux/macOS: `rsync`, `unzip`, `rdfind`

# Copy and edit the example config
sudo cp scripts/nginx.example.conf /etc/nginx/sites-available/cryptpad
# Replace YOUR_MAIN_DOMAIN, YOUR_SANDBOX_DOMAIN and cert paths
sudo nano /etc/nginx/sites-available/cryptpad
If you're on a Linux disto similar to Debian/Ubuntu, we provide an [Aptfile](./Aptfile) with the dependencies

```bash
sudo apt-get install -y $(cat Aptfile)
```

sudo ln -s /etc/nginx/sites-available/cryptpad /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
- For OnlyOffice support: `unzip`

# Obtain TLS certificates (replaces the cert placeholders automatically)
sudo certbot --nginx -d YOUR_MAIN_DOMAIN -d YOUR_SANDBOX_DOMAIN
```
### Build Steps

Then set the matching values in your `.env`:
1. Ensure you fill the build's prerequisites
2. Clone this repository

```bash
CRYPTPAD_HTTP_UNSAFE_ORIGIN=https://YOUR_MAIN_DOMAIN
CRYPTPAD_HTTP_SAFE_ORIGIN=https://YOUR_SANDBOX_DOMAIN
CRYPTPAD_HTTP_ADDRESS=127.0.0.1
```
```bash
git clone https://github.com/Scille/cryptpad-server.git
cd cryptpad-server
```

Restart the service to apply: `sudo systemctl restart cryptpad-server`
3. Build

---
```bash
npm run build
```

### Method 2 — Docker
The build script will:
- Clone the CryptPad source at the pinned commit
- Install Node.js dependencies
- Build frontend assets
- Install OnlyOffice (unless skipped)
- Copy the Parsec customizations from `./resources/` into the CryptPad directory (`./cryptpad`)

**Option A — Docker Compose (recommended)**
## Build Using Docker

```bash
git clone https://github.com/Scille/cryptpad-server.git
cd cryptpad-server
### Build Using Docker - Prerequisites

cp .env.example .env
# Edit .env
- **Git**
- **Docker**

docker compose up -d --build
```
### Build Using Docker - Steps

Exposes ports `3000` (main) and `3003` (websocket). Named volumes for all persistent data are created automatically.
Build the Docker image from sources:

```bash
docker compose stop # stop without removing the container
docker compose start # restart the existing container
docker compose logs -f # follow logs
docker compose down -v # stop and delete volumes (destructive)
```
1. Clone this repository:

**Option B — Docker CLI**
```bash
git clone https://github.com/Scille/cryptpad-server.git
```

```bash
# Build the image
docker build -t cryptpad-server .

# Run
docker run -d \
--name cryptpad-server \
--restart unless-stopped \
-p 3000:3000 -p 3003:3003 \
-v cryptpad_data:/app/cryptpad/data \
-v cryptpad_datastore:/app/cryptpad/datastore \
-v cryptpad_blob:/app/cryptpad/blob \
-v cryptpad_block:/app/cryptpad/block \
-v cryptpad_customize:/app/cryptpad/customize \
-e CRYPTPAD_HTTP_UNSAFE_ORIGIN=https://cryptpad.example.com \
-e CRYPTPAD_HTTP_SAFE_ORIGIN=https://cryptpad-sandbox.example.com \
-e CRYPTPAD_HTTP_ADDRESS=0.0.0.0 \
cryptpad-server
```
2. Build using Docker:

**Data persistence**
```bash
docker build -t cryptpad-server .
```

The following paths inside the container hold user data and must be persisted across container restarts:
> [!NOTE]
> We build the image and assign it the tag `cryptpad-server`, feel free to change it and/or add tags.

| Path | Content |
|---|---|
| `/app/cryptpad/data` | Server state (user accounts, quota, etc.) |
| `/app/cryptpad/datastore` | Encrypted document storage |
| `/app/cryptpad/blob` | Binary files |
| `/app/cryptpad/block` | Login blocks |
| `/app/cryptpad/customize` | Runtime customizations |
## Configure Env Variables File

Docker Compose creates named volumes for all of these automatically. With `docker run`, pass them as `-v` flags as shown above.
CryptPad needs some env variables to be able to work correctly and to customize it.

---
We provide an [example env file](./.env.example) which provide a start point:

```bash
cp .env.example .env
```

But you need to edit that file to set at least

- `CRYPTPAD_HTTP_UNSAFE_ORIGIN`
- `CRYPTPAD_HTTP_SAFE_ORIGIN`

## Environment Variables
### Environment Variables

All variables are optional. Defaults are suited for local development (`localhost:3000`).

| Variable | Default | Description |
|---|---|---|
| `CRYPTPAD_HTTP_UNSAFE_ORIGIN` | `http://localhost:3000` | Main URL clients use to reach CryptPad |
| `CRYPTPAD_HTTP_SAFE_ORIGIN` | `http://safe.localhost:3000` | Sandbox URL (must be a different domain/subdomain in production) |
| `CRYPTPAD_HTTP_ADDRESS` | `localhost` | Address the Node.js server binds to (`0.0.0.0` to accept external connections) |
| `CRYPTPAD_CUSTOM_PROTOCOL` | `parsec-desktop:` | Custom protocol for Parsec CSP integration |
| `CRYPTPAD_MAX_WORKERS` | _(all cores)_ | Maximum number of worker processes |
| `CRYPTPAD_DATASTORE_PATH` | `./datastore` | Folder where cryptpad will store document |
| `CRYPTPAD_DATA_PATH` | `./data` | Folder where CryptPad will store its data |
| `CRYPTPAD_BLOCK_PATH` | `./block` | Folder where will reside users' authenticated blocks |
| `CRYPTPAD_BLOB_PATH` | `./blob` | Folder where are stored encrypted blob |
| `CRYPTPAD_LOG_PATH` | `{{ CRYPTPAD_DATA_PATH }}/logs` | Folder where log files are located
| `WEBSOCKET_PORT` | `3003` | The port the server use to listen to websocket |

> **Production note:** `CRYPTPAD_HTTP_SAFE_ORIGIN` must point to a **different domain or subdomain** than `CRYPTPAD_HTTP_UNSAFE_ORIGIN`. Using the same domain will break the CryptPad sandboxing model.
| Variable | Default | Description |
| ----------------------------- | ------------------------------- |--- |
| `PORT` | `3000` | Port the server will listen to |
| `WEBSOCKET_PORT` | `3003` | The port the server uses to listen to websocket |
| `CRYPTPAD_HTTP_UNSAFE_ORIGIN` | `http://localhost:3000` | Main URL clients use to reach CryptPad |
| `CRYPTPAD_HTTP_SAFE_ORIGIN` | `http://safe.localhost:3000` | Sandbox URL (must be a different domain/subdomain in production) |
| `CRYPTPAD_HTTP_ADDRESS` | `localhost` | Address the Node.js server binds to (`0.0.0.0` to accept external connections) |
| `CRYPTPAD_CUSTOM_PROTOCOL` | `parsec-desktop:` | Custom protocol for Parsec CSP integration |
| `CRYPTPAD_MAX_WORKERS` | _(all cores)_ | Maximum number of worker processes |
| `CRYPTPAD_DATASTORE_PATH` | `./datastore` | Folder where cryptpad will store document |
| `CRYPTPAD_DATA_PATH` | `./data` | Folder where CryptPad will store its data |
| `CRYPTPAD_BLOCK_PATH` | `./block` | Folder where will reside users' authenticated blocks |
| `CRYPTPAD_BLOB_PATH` | `./blob` | Folder where are stored encrypted blob |
| `CRYPTPAD_LOG_PATH` | `{{ CRYPTPAD_DATA_PATH }}/logs` | Folder where log files are located |

> [!IMPORTANT]
>
> `CRYPTPAD_HTTP_SAFE_ORIGIN` must point to a **different domain or subdomain** than `CRYPTPAD_HTTP_UNSAFE_ORIGIN`.
>
> Using the same domain will break the CryptPad sandboxing model.

### Data Persistence

The following paths need to be persisted across restarts:

| Path | Content |
| ------------------------------------------- | --- |
| `CRYPTPAD_DATA_PATH` | Server state (user accounts, quota, etc.) |
| `CRYPTPAD_DATASTORE_PATH` | Encrypted document storage |
| `CRYPTPAD_BLOB_PATH` | Binary files |
| `CRYPTPAD_BLOCK_PATH` | Login blocks |
| `./customize` (relative to cryptpad folder) | Runtime customizations |

---

Expand Down
29 changes: 29 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
services:
cryptpad:
build: .
image: cryptpad-server
container_name: cryptpad-server
restart: unless-stopped
ports:
- "3000:3000"
- "3003:3003"
env_file:
- path: .env
required: false
environment:
- NODE_ENV=production
- PORT=3000
- CRYPTPAD_HTTP_ADDRESS=0.0.0.0
volumes:
- cryptpad_data:/app/cryptpad/data
- cryptpad_datastore:/app/cryptpad/datastore
- cryptpad_blob:/app/cryptpad/blob
- cryptpad_block:/app/cryptpad/block
- cryptpad_customize:/app/cryptpad/customize

volumes:
cryptpad_data:
cryptpad_datastore:
cryptpad_blob:
cryptpad_block:
cryptpad_customize:
Loading