CryptPad — a privacy-first, end-to-end encrypted collaborative office suite (documents, spreadsheets, slides, forms, kanban, whiteboard) where the server has zero knowledge of your content. Deployed as a single host-networked Nomad service.
Needs nomad-pack on PATH. The script only adds the nomploy registry and runs this pack.
Source ↗ Project ↗ ★ 8k ⚑ Report an issue
Save as values.hcl, edit, then run:
# The name of the Nomad job.
job_name = "cryptpad"
# The Nomad namespace to deploy into.
namespace = "default"
# The datacenters to deploy to.
datacenters = ["*"]
# The CryptPad container image. Pin a tag in production.
image = "cryptpad/cryptpad:latest"
# Host port for the CryptPad main application.
port = 3000
# Host port for the CryptPad sandbox (must be a different origin from the main port).
sandbox_port = 3001
# Public URL of the main app (e.g. https://cryptpad.example.com). Must differ from the sandbox domain.
main_domain = "http://localhost:3000"
# Public URL of the sandbox (e.g. https://sandbox.example.com). Must be a DIFFERENT origin from main_domain.
sandbox_domain = "http://localhost:3001"
# Named volume for encrypted document data (/cryptpad/data).
data_volume = "cryptpad_data"
# Named volume for uploaded encrypted blobs (/cryptpad/blob).
blob_volume = "cryptpad_blob"
# Named volume for login blocks (/cryptpad/block).
block_volume = "cryptpad_block"
# Named volume for the channel datastore (/cryptpad/datastore).
datastore_volume = "cryptpad_datastore"
# Named volume for customization/theming (/cryptpad/customize).
customize_volume = "cryptpad_customize"
# Placement constraints. On a nomploy cluster: attribute = "$${meta.nomploy_control_plane}", operator = "=", value = "true".
constraints = []
# The task resources.
resources = {
cpu = 1000
memory = 1024
}
| Name | Type | Default | Description |
|---|---|---|---|
| job_name | string | "cryptpad" | The name of the Nomad job. |
| namespace | string | "default" | The Nomad namespace to deploy into. |
| datacenters | list | ["*"] | The datacenters to deploy to. |
| image | string | "cryptpad/cryptpad:latest" | The CryptPad container image. Pin a tag in production. |
| port | number | 3000 | Host port for the CryptPad main application. |
| sandbox_port | number | 3001 | Host port for the CryptPad sandbox (must be a different origin from the main port). |
| main_domain | string | "http://localhost:3000" | Public URL of the main app (e.g. https://cryptpad.example.com). Must differ from the sandbox domain. |
| sandbox_domain | string | "http://localhost:3001" | Public URL of the sandbox (e.g. https://sandbox.example.com). Must be a DIFFERENT origin from main_domain. |
| data_volume | string | "cryptpad_data" | Named volume for encrypted document data (/cryptpad/data). |
| blob_volume | string | "cryptpad_blob" | Named volume for uploaded encrypted blobs (/cryptpad/blob). |
| block_volume | string | "cryptpad_block" | Named volume for login blocks (/cryptpad/block). |
| datastore_volume | string | "cryptpad_datastore" | Named volume for the channel datastore (/cryptpad/datastore). |
| customize_volume | string | "cryptpad_customize" | Named volume for customization/theming (/cryptpad/customize). |
| constraints | list | [] | Placement constraints. On a nomploy cluster: attribute = "$${meta.nomploy_control_plane}", operator = "=", value = "true". |
| resources | object | {
cpu = 1000
memory = 1024
} | The task resources. |
No variables match.
This pack stores data in 5 Docker named volumes:
cryptpad_datacryptpad_blobcryptpad_blockcryptpad_datastorecryptpad_customize
restic
# Run on the node hosting this pack. Point restic at your repo first: # export RESTIC_REPOSITORY="s3:https://<account>.r2.cloudflarestorage.com/<bucket>" # export RESTIC_PASSWORD="<repo-password>" # export AWS_ACCESS_KEY_ID=<key> AWS_SECRET_ACCESS_KEY=<secret> restic backup \ /var/lib/docker/volumes/cryptpad_data/_data \ /var/lib/docker/volumes/cryptpad_blob/_data \ /var/lib/docker/volumes/cryptpad_block/_data \ /var/lib/docker/volumes/cryptpad_datastore/_data \ /var/lib/docker/volumes/cryptpad_customize/_data
rclone (sync to S3/R2)
rclone sync /var/lib/docker/volumes/cryptpad_data/_data backup:<bucket>/cryptpad_data rclone sync /var/lib/docker/volumes/cryptpad_blob/_data backup:<bucket>/cryptpad_blob rclone sync /var/lib/docker/volumes/cryptpad_block/_data backup:<bucket>/cryptpad_block rclone sync /var/lib/docker/volumes/cryptpad_datastore/_data backup:<bucket>/cryptpad_datastore rclone sync /var/lib/docker/volumes/cryptpad_customize/_data backup:<bucket>/cryptpad_customize
Paths assume the default Docker volume location (/var/lib/docker/volumes). Restore by stopping the job, restoring files into the same volume, and re-running the pack.
CryptPad is a privacy-first, end-to-end encrypted collaborative office suite. It offers real-time collaborative rich text documents, spreadsheets, presentations, forms, kanban boards, whiteboards, code and markdown — all encrypted in the browser so the server has zero knowledge of your content. A self-hosted alternative to Google Workspace / Office 365.
This pack runs CryptPad as a single host-networked Nomad service.
nomad-pack run cryptpad --registry=nomploy \
--var main_domain=https://cryptpad.example.com \
--var sandbox_domain=https://cryptpad-sandbox.example.com
Open the main app and register an account.
| Variable | Default | Description |
|---|---|---|
image |
cryptpad/cryptpad:latest |
Container image (pin a tag in production). |
port |
3000 |
Host port for the main app. |
sandbox_port |
3001 |
Host port for the sandbox (different origin). |
main_domain |
http://localhost:3000 |
Public URL of the main app. |
sandbox_domain |
http://localhost:3001 |
Public URL of the sandbox — must differ from main. |
data_volume … |
cryptpad_* |
Volumes for data, blobs, blocks, datastore, customize. |
resources |
1000 MHz / 1024 MB | CPU and memory for the task. |
Important: CryptPad's security model requires the sandbox to be served from a different origin than the main application. Use two distinct domains/subdomains (or at least different ports) and route both through your reverse proxy. To become admin, register, then add your account's public key to the admin list in CryptPad's settings.
All content is end-to-end encrypted; the server stores only ciphertext, persisted across the mounted volumes.