CryptPad self-hosted su Proxmox
Contents
CryptPad è una suite di collaborazione (documenti, fogli di calcolo, presentazioni, kanban, moduli).
È un alternativa privata, cifrata e self-hosted a Google Docs.
In questa guida creeremo due VM Debian 13 in Proxmox dentro una DMZ/LAN, una con CryptPad e una con nginx come proxy HTTPS, con certificato Let’s Encrypt ottenuto tramite le API DNS di Cloudflare.
Due varianti:
- A: tutte le porte disponibili, CryptPad risponde sulla 443.
- B: solo una porta pubblica alta (negli esempi
49101), come con alcuni provider.
Prima di iniziare
- Proxmox VE con circa 140 GiB liberi per due VM (compreso il disco dati da 100 GiB).
- Firewall con una LAN/DMZ e port forward.
- Dominio con DNS (in questa guida su Cloudflare).
- IP pubblico raggiungibile sulla 443 o su una porta concessa dal provider.
Architettura
CryptPad richiede due domini diversi: il principale (accessi e chiavi) e il sandbox (interfaccia).
La separazione è un requisito di sicurezza: servono un certificato per entrambi e un proxy che li serva con lo stesso backend.
- Proxy (
10.99.0.251): nginx stabile da nginx.org e acme.sh, termina TLS.
È l’unica macchina raggiungibile da internet. - CryptPad (
10.99.0.201): Node.js 24, CryptPad 2026.5.1, editor office.
Porte 3000 (HTTP) e 3003 (websocket), raggiungibili solo dal proxy.
Percorso: internet → port forward → proxy nginx (HTTPS) → CryptPad (HTTP 3000 e 3003).
Valori da preparare
Sostituisci gli esempi con i tuoi in tutti i comandi e i file.
- Domini:
pad.example.comesandbox-pad.example.com(basta un altro sottodominio). - Porta pubblica:
443oppure49101. - IP: CryptPad
10.99.0.201, proxy10.99.0.251, gateway della DMZ10.99.0.1. - Email ACME:
admin@example.com, riceve gli avvisi di Let’s Encrypt. - Disco dati:
/dev/sdb, il disco da 100 GiB senza partizioni (lsblk). - Token API Cloudflare (segreto): My Profile → API Tokens → Create Token → modello Edit zone DNS, Zone Resources: Include → Specific zone → il tuo dominio.
Viene mostrato una sola volta: salvalo nel gestore di password, mai in chat, documenti o cronologia della shell. - Zone ID Cloudflare (32 caratteri): dominio → Overview → colonna destra → API → Zone ID.
Non è l’Account ID, che ha la stessa lunghezza.
Le due varianti
| Variante | A (443) | B (49101) |
|---|---|---|
| Porta pubblica | 443, più la 80 per il redirect | Solo la porta scelta |
Origini in config.js |
Senza porta | Con la porta |
| nginx in ascolto | 443 ssl, più il redirect dalla 80 |
49101 ssl, niente porta 80 |
Host verso CryptPad |
$host |
$http_host |
| Regole del firewall | Port forward | Port forward, a volte anche una regola di forward WAN → DMZ |
Nella variante B la porta compare ovunque: origini, indirizzo (https://pad.example.com:49101/) e prove.
$http_host inoltra anche la porta, $host la perderebbe.
In entrambe il certificato usa il challenge DNS-01 (la HTTP-01 richiederebbe la porta 80).
Il resto è identico.
Rete, firewall e DNS
Internet → LAN: port forward verso il proxy e relativa regola.
DNS: un record per nome verso l’IP pubblico (A o CNAME).
Con Cloudflare: DNS only, nuvola grigia.
Verifica dal PC:
nslookup pad.example.com 1.1.1.1
nslookup sandbox-pad.example.com 1.1.1.1
VM in Proxmox
Dove: interfaccia web di Proxmox e console delle VM.
| Parametro | VM CryptPad | VM proxy |
|---|---|---|
| Nome | cryptpad |
nginx |
| CPU | 2 core, tipo host |
1 core, tipo host |
| RAM | 4096 MiB | 1024 MiB |
| Disco di sistema | 20-30 GiB | 8-10 GiB |
| Disco dati | 100 GiB | Nessuno |
Per entrambe: controller VirtIO SCSI single, Qemu Agent, Discard (storage thin), rete VirtIO sul bridge della DMZ con il suo VLAN Tag, firewall di Proxmox disattivato, Start at boot.
Installazione di Debian:
- Lingua inglese, rete manuale (IP, netmask, gateway e DNS della DMZ), hostname
cryptpadonginx, dominio vuoto. - Password di root vuota: root non accede e il primo utente ottiene
sudo(password robusta). - Partizioni: Guided - use entire disk → All files in one partition.
- Mirror
deb.debian.org, Popularity contest no. - Software: solo SSH server e standard system utilities.
- A fine installazione: Hardware → CD/DVD Drive → Do not use any media.
Poi, su entrambe le VM con il tuo utente:
sudo apt update
sudo apt full-upgrade -y
sudo apt install -y qemu-guest-agent
sudo reboot
CryptPad
Dove: Proxmox (Hardware → Add → Hard Disk, SCSI, 100 GiB), poi la VM con il tuo utente.
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINT
Atteso: un secondo disco da 100 GiB senza partizioni, di solito sdb (altrimenti adatta i comandi).
Attenzione:
mkfscancella tutto il disco indicato. Controlla due volte il nome.
sudo mkfs.ext4 -m 1 -L cryptpad-data /dev/sdb
sudo mkdir -p /var/lib/cryptpad
echo "UUID=$(sudo blkid -s UUID -o value /dev/sdb) /var/lib/cryptpad ext4 defaults,noatime 0 2" | sudo tee -a /etc/fstab
sudo systemctl daemon-reload
sudo mount -a
df -h /var/lib/cryptpad
tail -1 /etc/fstab
Atteso: il disco montato su /var/lib/cryptpad e una riga di fstab con il suo UUID.
-m 1 riserva a root l’1% invece del 5%.
Con il tuo utente:
sudo apt install -y git curl ca-certificates unzip
sudo adduser --disabled-password --gecos "" cryptpad
sudo chown cryptpad:cryptpad /var/lib/cryptpad
L’utente cryptpad non ha password: entra con sudo -iu cryptpad e installa NVM:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.8/install.sh | bash
Esci (exit) e rientra (sudo -iu cryptpad) per caricare NVM, poi:
nvm install 24
node -v
command -v node
Atteso: v24.x.y e un percorso sotto /home/cryptpad/.nvm/.
Con il tuo utente Node dà Permission denied: è normale, /home/cryptpad è privata.
Con utente cryptpad:
Controlla l’ultima release (esclude i tag con prefisso, come opendesk-...):
git ls-remote --tags https://github.com/cryptpad/cryptpad | grep -oE 'refs/tags/[0-9]{4}\.[0-9]+\.[0-9]+$' | sed 's#refs/tags/##' | sort -V | tail -3
Atteso: l’ultima riga è 2026.5.1.
Se ce n’è una più recente, leggi prima le sue note di rilascio: la 2026.9.0 cambia server, configurazione ed editor office.
cd ~
git clone -b 2026.5.1 --depth 1 https://github.com/cryptpad/cryptpad.git cryptpad
cd cryptpad
npm ci
npm run install:components
./install-onlyoffice.sh --accept-license --trust-repository
ls www/common/onlyoffice/dist
L’ultimo script installa l’editor office (accetta la licenza di OnlyOffice) ed è facoltativo.
Atteso: le cartelle v1, v2b, …, x2t.
Gli avvisi su pacchetti deprecati sono normali; fermati se compare does not match expected checksum.
config.js
Imposta le variabili della tua variante (valgono solo nella shell corrente).
Variante A:
MAIN_ORIGIN="https://pad.example.com"
SANDBOX_ORIGIN="https://sandbox-pad.example.com"
CRYPTPAD_IP="10.99.0.201"
Variante B:
MAIN_ORIGIN="https://pad.example.com:49101"
SANDBOX_ORIGIN="https://sandbox-pad.example.com:49101"
CRYPTPAD_IP="10.99.0.201"
Poi crea config.js con domini, indirizzo e percorsi dei dati sul disco dati.
Il blocco riparte sempre dall’esempio, quindi si può rieseguire.
cd ~/cryptpad
cp config/config.example.js config/config.js
sed -i "s#^\(\s*\)httpUnsafeOrigin:.*#\1httpUnsafeOrigin: '${MAIN_ORIGIN}',#" config/config.js
sed -i "s#^\s*//\s*httpSafeOrigin:.*# httpSafeOrigin: '${SANDBOX_ORIGIN}',#" config/config.js
sed -i "s#^\s*//\s*httpAddress:.*# httpAddress: '${CRYPTPAD_IP}',#" config/config.js
sed -i \
-e "s#^\(\s*\)filePath:.*#\1filePath: '/var/lib/cryptpad/datastore/',#" \
-e "s#^\(\s*\)archivePath:.*#\1archivePath: '/var/lib/cryptpad/data/archive',#" \
-e "s#^\(\s*\)pinPath:.*#\1pinPath: '/var/lib/cryptpad/data/pins',#" \
-e "s#^\(\s*\)taskPath:.*#\1taskPath: '/var/lib/cryptpad/data/tasks',#" \
-e "s#^\(\s*\)blockPath:.*#\1blockPath: '/var/lib/cryptpad/block',#" \
-e "s#^\(\s*\)blobPath:.*#\1blobPath: '/var/lib/cryptpad/blob',#" \
-e "s#^\(\s*\)blobStagingPath:.*#\1blobStagingPath: '/var/lib/cryptpad/data/blobstage',#" \
-e "s#^\(\s*\)decreePath:.*#\1decreePath: '/var/lib/cryptpad/data/decrees',#" \
-e "s#^\(\s*\)logPath:.*#\1logPath: '/var/lib/cryptpad/data/logs',#" config/config.js
sed -i "s#^\(\s*\)decreePath:.*#&\n\1base: '/var/lib/cryptpad/data',#" config/config.js
grep -nE "^\s*(httpUnsafeOrigin|httpSafeOrigin|httpAddress|filePath|archivePath|pinPath|taskPath|blockPath|blobPath|blobStagingPath|decreePath|base|logPath):" config/config.js
Atteso: tredici righe senza //, con i tuoi domini e il tuo IP.
httpAddress: '', significa variabili vuote: reimpostale e rifai il blocco.
application_config.js
Attenzione: il blocco genera ogni volta un
loginSaltnuovo.
Eseguilo una sola volta, prima di creare account: dopo, bloccherebbe tutti gli accessi.
mkdir -p customize
cp customize.dist/application_config.js customize/application_config.js
SALT=$(tr -dc 'a-f0-9' </dev/urandom | head -c 64)
sed -i "s|^\(\s*\)return AppConfig;|\1AppConfig.loginSalt = '${SALT}';\n\1AppConfig.minimumPasswordLength = 12;\n\1AppConfig.disableAnonymousPadCreation = true;\n\1AppConfig.disableAnonymousStore = true;\n\1return AppConfig;|" customize/application_config.js
grep -nE "AppConfig\.(loginSalt|minimumPasswordLength|disableAnonymous)|return AppConfig" customize/application_config.js | sed -E "s/'[a-f0-9]{64}'/'(SALT)'/"
Atteso: quattro righe AppConfig sopra un solo return AppConfig; (il salt compare come (SALT)).
- Salva il
loginSalt(grep loginSalt customize/application_config.js) e includicustomize/nei backup: senza, gli account non entrano più. - Le righe
disableAnonymous...impediscono a chi non è registrato di creare e salvare documenti; i link condivisi restano apribili. - Password minima di 12 caratteri.
- Facoltativi:
AppConfig.terms,AppConfig.privacy,AppConfig.imprint.
Infine:
npm run build
Servizio systemd
Con il tuo utente (exit da cryptpad).
NODE_BIN=$(sudo -u cryptpad bash -c 'export NVM_DIR=/home/cryptpad/.nvm; . "$NVM_DIR/nvm.sh" >/dev/null 2>&1; nvm which 24')
echo "$NODE_BIN"
Atteso: /home/cryptpad/.nvm/versions/node/v24.x.y/bin/node.
È il blocco ufficiale con due aggiunte: RequiresMountsFor (non parte senza il disco dati) e il disco dati in ReadWritePaths (necessario con ProtectSystem=strict).
Esegui il blocco da solo:
sudo tee /etc/systemd/system/cryptpad.service > /dev/null <<EOF
[Unit]
Description=CryptPad API server
RequiresMountsFor=/var/lib/cryptpad
[Service]
ExecStart=${NODE_BIN} /home/cryptpad/cryptpad/server.js
WorkingDirectory=/home/cryptpad/cryptpad
Restart=always
RestartSec=2
StandardOutput=journal
StandardError=journal+console
User=cryptpad
Group=cryptpad
Environment='PWD="/home/cryptpad/cryptpad"'
LimitNOFILE=1000000
ProcSubset=all
ProtectProc=invisible
CapabilityBoundingSet=
NoNewPrivileges=true
ProtectSystem=strict
PrivateTmp=true
PrivateDevices=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictAddressFamilies=AF_INET
RestrictAddressFamilies=AF_INET6
RestrictAddressFamilies=AF_NETLINK
RestrictAddressFamilies=AF_UNIX
RestrictNamespaces=true
LockPersonality=true
RestrictRealtime=true
RestrictSUIDSGID=true
RemoveIPC=true
PrivateMounts=true
ProtectClock=true
SystemCallArchitectures=native
SystemCallFilter=~@cpu-emulation @debug @keyring @ipc @mount @obsolete @privileged @setuid
SystemCallFilter=@chown
SystemCallFilter=pipe
SystemCallFilter=pipe2
ReadWritePaths=/home/cryptpad/cryptpad /var/lib/cryptpad
[Install]
WantedBy=multi-user.target
EOF
grep -E "ExecStart|ReadWritePaths|RequiresMountsFor" /etc/systemd/system/cryptpad.service
sudo systemctl daemon-reload
sudo systemctl enable --now cryptpad
sleep 5
systemctl is-active cryptpad
ss -tlnp | grep -E ':3000|:3003'
curl -sI http://10.99.0.201:3000 | head -3
Atteso: ExecStart con il percorso di Node, active, porte 3000 e 3003 in ascolto, HTTP 200.
La 3001 non serve: con httpSafeOrigin la sandbox passa dalla 3000.
URL di installazione dell’amministratore:
sudo journalctl -u cryptpad --no-pager | grep -i install
(forma https://pad.example.com/install/#...).
È monouso e riservato: annotalo senza aprirlo e usalo dalla LAN prima della pubblicazione.
Nginx
Con il tuo utente:
sudo apt install -y curl gnupg2 ca-certificates lsb-release debian-archive-keyring
curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg > /dev/null
gpg --show-keys --with-colons /usr/share/keyrings/nginx-archive-keyring.gpg | grep -c 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62
Atteso: almeno 1 (impronta della chiave); con 0 fermati.
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] https://nginx.org/packages/debian `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" | sudo tee /etc/apt/preferences.d/99nginx
sudo apt update
sudo apt install -y nginx
sudo nginx -v
apt-cache policy nginx | head -4
curl -sI http://10.99.0.201:3000 | head -1
Atteso: nginx 1.30.x o successivo da nginx.org e HTTP 200 da CryptPad.
nginx è in /usr/sbin, quindi serve sudo; il servizio resta inactive finché non è configurato.
Certificato
Come root (sudo -i):
curl https://get.acme.sh | sh -s email=admin@example.com
/root/.acme.sh/acme.sh --version
crontab -l | grep acme
/root/.acme.sh/acme.sh --set-default-ca --server letsencrypt
Atteso: la versione e la riga di cron acme.sh --cron.\
Un comando per volta: incollando più righe,
readprende la riga successiva come risposta.
Se il token finisce in una chat o in un file, revocalo e creane uno nuovo.
1. Token (non compare mentre lo incolli):
read -rsp "Token Cloudflare: " CF_Token; echo
2. Lunghezza del token, atteso più di zero (di solito circa 40):
echo ${#CF_Token}
3. Zone ID:
read -rp "Zone ID: " CF_Zone_ID
4. Lunghezza dello Zone ID, atteso esattamente 32:
echo ${#CF_Zone_ID}
5. Emissione:
export CF_Token CF_Zone_ID
/root/.acme.sh/acme.sh --issue --dns dns_cf -d pad.example.com -d sandbox-pad.example.com
Atteso: Cert success.
invalid domain = Zone ID sbagliato (spesso è l’Account ID); errori di permessi = token senza diritti DNS sulla zona.
acme.sh salva i valori in /root/.acme.sh/account.conf per i rinnovi: poi puoi fare unset CF_Token CF_Zone_ID.
Installa il certificato per nginx, con ricarica automatica a ogni rinnovo:
mkdir -p /etc/ssl/cryptpad
/root/.acme.sh/acme.sh --install-cert -d pad.example.com --ecc \
--fullchain-file /etc/ssl/cryptpad/fullchain.pem \
--key-file /etc/ssl/cryptpad/privkey.pem \
--reloadcmd "systemctl reload-or-restart nginx"
ls -l /etc/ssl/cryptpad
Atteso: fullchain.pem e privkey.pem; il rinnovo è automatico (cron giornaliero di acme.sh).
Parametri Diffie-Hellman:
nohup openssl dhparam -out /etc/nginx/dhparam.pem 4096 >/dev/null 2>&1
Per controllare l’avanzamento:
pgrep -x openssl && echo "ancora in corso" || ls -l /etc/nginx/dhparam.pem
Configurazione nginx
Come root:
È l’esempio ufficiale del tag 2026.5.1 senza il webroot di Let’s Encrypt (si usa DNS-01), con i percorsi del certificato e l’IP di CryptPad al posto di localhost.
La location /cryptpad_websocket verso la 3003 è indispensabile.
rm -f /etc/nginx/conf.d/default.conf
nano /etc/nginx/conf.d/cryptpad.conf
Incolla la tua variante, salva con Ctrl+O, esci con Ctrl+X.
Variante A (443)
server {
listen 80;
server_name pad.example.com sandbox-pad.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
http2 on;
server_name pad.example.com sandbox-pad.example.com;
ssl_certificate /etc/ssl/cryptpad/fullchain.pem;
ssl_certificate_key /etc/ssl/cryptpad/privkey.pem;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
location / {
proxy_pass http://10.99.0.201:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 150m;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
}
location ^~ /cryptpad_websocket {
proxy_pass http://10.99.0.201:3003;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
}
}
Variante B (49101)
Senza il blocco sulla 80, con listen 49101 ssl; e Host $http_host in entrambe le location.
Se usi un’altra porta, cambiala qui e nelle origini di config.js.
server {
listen 49101 ssl;
http2 on;
server_name pad.example.com sandbox-pad.example.com;
ssl_certificate /etc/ssl/cryptpad/fullchain.pem;
ssl_certificate_key /etc/ssl/cryptpad/privkey.pem;
ssl_dhparam /etc/nginx/dhparam.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
location / {
proxy_pass http://10.99.0.201:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 150m;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
}
location ^~ /cryptpad_websocket {
proxy_pass http://10.99.0.201:3003;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
}
}
Avvio e prove
Per il primo comando aspetta la fine di dhparam, senza il quale nginx -t fallisce.
while pgrep -x openssl >/dev/null; do sleep 5; done; ls -l /etc/nginx/dhparam.pem
nginx -t
systemctl enable nginx
systemctl restart nginx
ss -tlnp | grep -E ':443|:49101'
Variante A:
curl -sI --resolve pad.example.com:443:127.0.0.1 https://pad.example.com/ | head -3
curl -sI --resolve sandbox-pad.example.com:443:127.0.0.1 https://sandbox-pad.example.com/ | head -3
Variante B:
curl -sI --resolve pad.example.com:49101:127.0.0.1 https://pad.example.com:49101/ | head -3
curl -sI --resolve sandbox-pad.example.com:49101:127.0.0.1 https://sandbox-pad.example.com:49101/ | head -3
Websocket, direttamente su CryptPad:
curl -s -o /dev/null -w "%{http_code}\n" http://10.99.0.201:3003/
Atteso: syntax is ok, nginx in ascolto, due HTTP/2 200 senza errori di certificato, e dalla 3003 un codice qualsiasi (anche 404) ma non 000.
Poi exit dalla shell di root.
Amministratore e istanza
- Port forward verso il proxy: TCP 443 e 80 (variante A) o la porta scelta (variante B).
Su alcuni firewall serve anche una regola di forward WAN → DMZ con la stessa porta e destinazione solo il proxy: prova prima senza. - Apri
/checkup/e un documento condiviso. - Da entrambe le VM,
curl -m 5verso un servizio della LAN deve fallire (DMZ isolata). - Apri l’URL di installazione e crea l’account amministratore, con una password lunga poi logo, titolo e colore.
- Attiva l’autenticazione a più fattori.
- In
/admin/: Close registration (dalla 4.5.0 non è più inconfig.js. - I nuovi account si creano con i link di invito di
/admin/; CryptPad non invia email.
Manutenzione
Pulizia dell’archivio
VM CryptPad, con il tuo utente:
I documenti cancellati restano in archivio 15 giorni; evict-archived.js li elimina e va eseguito ogni notte.
NODE_BIN=$(sudo -u cryptpad bash -c 'export NVM_DIR=/home/cryptpad/.nvm; . "$NVM_DIR/nvm.sh" >/dev/null 2>&1; nvm which 24')
echo "$NODE_BIN"
sudo -u cryptpad bash -c "cd /home/cryptpad/cryptpad && $NODE_BIN scripts/evict-archived.js"
( sudo -u cryptpad crontab -l 2>/dev/null; echo "15 3 * * * cd /home/cryptpad/cryptpad && $NODE_BIN scripts/evict-archived.js >/dev/null 2>&1" ) | sudo -u cryptpad crontab -
sudo -u cryptpad crontab -l
Atteso: nessun errore e una sola riga di cron con il percorso di Node.
Ogni esecuzione aggiunge una riga: togli i doppioni con sudo -u cryptpad crontab -e.
Quando aggiorni Node, il percorso cambia: aggiornalo qui e in ExecStart.
Aggiornamento di CryptPad
Leggi le Upgrade notes di tutte le release tra la tua e la nuova, e fai un backup.
Con il tuo utente:
sudo systemctl stop cryptpad
Come cryptpad (sudo -iu cryptpad), con il numero della nuova versione:
NUOVA_VERSIONE="2026.x.y"
cd ~/cryptpad
git fetch --depth 1 origin tag "$NUOVA_VERSIONE"
git checkout "$NUOVA_VERSIONE"
npm ci
npm run install:components
./install-onlyoffice.sh --accept-license --trust-repository
npm run build
Lo script dell’editor office serve solo se lo avevi installato.
Poi exit e, con il tuo utente:
sudo systemctl start cryptpad
systemctl is-active cryptpad
Confronta le opzioni nuove con diff config/config.example.js config/config.js in ~/cryptpad.
Fonti
- CryptPad, Administrator Guide e repository cryptpad/documentation.
- CryptPad, file del tag 2026.5.1 (
docs/example.nginx.conf,docs/cryptpad.service,config/config.example.js) e changelog. - nginx.org, Linux packages.
- acme.sh, wiki dnsapi (Cloudflare).
- NVM e calendario di Node.js.