cipi php

PHP 8.5 è preinstallato durante il setup. Puoi aggiungere altre versioni in qualsiasi momento; da v4.5.12 Cipi analizza le sorgenti APT per codename Ubuntu — di solito la PPA ondrej/php su 24.04, packages.sury.org su 26.04 quando Launchpad non ha una suite, oppure Ubuntu main come ultima risorsa (co-installabili 8.3–8.5 dove il repository scelto le supporta).

Da v4.5.4 Cipi include Deployer 8, che richiede PHP ≥ 8.3. cipi php install, cipi php switch, cipi app create e cipi app edit accettano quindi solo 8.3, 8.4 e 8.5. Le versioni legacy (7.4–8.2) restano rilevabili e rimovibili, così puoi ancora ripulire un server pre-4.5.4 con cipi php remove <old-version>.
bash
$ cipi php list              # list installed versions, status, and system default
$ cipi php install 8.4       # install an additional PHP version (8.3–8.5)
$ cipi php switch 8.4        # set system default (root/cipi, API pool)
$ cipi php remove 8.1        # remove a version, incl. legacy (blocks if default or apps use it)
$ cipi php upgrade           # apply security patches to all installed PHP packages

Aggiornamenti di sicurezza

Da v4.7.13, i pacchetti PHP sono esclusi da unattended-upgrades e gestiti da Cipi. cipi php upgrade esegue apt-get update e --only-upgrade su ogni pacchetto php* e libphp* installato, poi riavvia i pool PHP-FPM interessati. Quando SMTP è configurato e i pacchetti sono stati aggiornati, Cipi invia un'email (trigger php_upgrade; disabilita con cipi notifications disable php_upgrade).

Un controllo settimanale parte automaticamente la domenica alle 03:30 tramite crontab di root (wrappato da cipi-cron-notify). Log: /var/log/cipi/php-upgrade.log. I server esistenti ricevono il cron con cipi self-update (migrazione 4.7.13).

PHP predefinito di sistema vs PHP specifico per app

Il default di sistema è la versione PHP usata dagli utenti root e cipi, dal pool FPM dell'API Cipi e dal queue worker dell'API. Usa cipi php switch <ver> per cambiarla. Il comando migra il pool API, riavvia il worker API e invia una notifica email se SMTP è configurato.

Ogni app ha la propria versione PHP (impostata a app create o tramite cipi app edit --php=). Deployer, Composer, i trigger di deploy nel crontab e cipi sync import girano sempre con il PHP configurato per l'app — mai con il default di sistema.

Per passare un'app esistente a una versione diversa:

bash
$ cipi app edit myapp --php=8.5

Cambia la versione PHP a caldo con zero downtime: aggiorna il pool FPM, il socket Nginx, i worker Supervisor, il crontab, la config Deployer e .env in un'unica operazione atomica.

cipi db

Cipi crea automaticamente un database dedicato per ogni app Laravel durante app create. MariaDB (porta 3306) è il default nativo; da v4.8.0 puoi anche installare PostgreSQL opzionale (porta 5432) e scegliere un engine per database o app. Le app custom non ricevono un database — usa cipi db create --name=<app> se ti serve (es. per WordPress o un altro CMS). Dopo il setup viene mostrato un URL di connessione pronto all'uso (MariaDB: mariadb+ssh://), che combina credenziali SSH, IP del server e informazioni sul database per client GUI come TablePlus, DBeaver o Sequel Pro.

Engine (v4.8.0+)

bash
$ cipi db install pgsql              # install optional PostgreSQL
$ cipi db uninstall pgsql|mariadb    # remove a non-default engine (destroys data)
$ cipi db default mariadb|pgsql      # server-wide default when --engine is omitted
$ cipi db engines                    # installed engines, ports, and default

Ciclo di vita del database

bash
$ cipi db create                              # interactive
$ cipi db create --name=analytics             # non-interactive (default engine)
$ cipi db create --name=analytics --engine=pgsql
$ cipi db list [--engine=mariadb|pgsql]       # list databases with sizes
$ cipi db backup myapp [--engine=…]
$ cipi db restore myapp backup.sql.gz [--engine=…]
$ cipi db password myapp [--engine=…]         # regenerate password
$ cipi db delete analytics [--engine=…]

Le app Laravel memorizzano l'engine scelto nei metadati dell'app; backup, sync e cipi app reset-db-password lo seguono. Usa cipi app create --engine=pgsql (o il prompt interattivo) per provisionare un'app Laravel su PostgreSQL — .env e l'URL di connessione corrispondono all'engine. Reset password root: cipi reset db-password [--engine=].

cipi alias

Aggiungi più domini o sottodomini a qualsiasi app. Dopo aver aggiunto alias, esegui cipi ssl install per provisionare o rinnovare il certificato con copertura SAN per tutti i domini. Da v4.8.0, cipi alias add|remove rigenera il vhost e riapplica SSL con certbot install --redirect così HTTPS non viene perso.

bash
$ cipi alias add myapp www.myapp.com
$ cipi alias add myapp myapp.it
$ cipi alias list myapp
$ cipi alias remove myapp myapp.it

Per i redirect canonici www ↔ apex, preferisci cipi www invece di gestire a mano l'host counterpart.

cipi www

Disponibile da v4.8.0. Gestisci alias www/apex e redirect canonici 301 per un'app. Lo stato vive in apps.json (www_redirect); Nginx emette un server block dedicato al redirect (percorso ACME lasciato pubblico) che sopravvive alla rigenerazione del vhost. SSL viene riapplicato tramite certbot install --redirect.

bash
$ cipi www add myapp              # add counterpart host (www ↔ apex)
$ cipi www force-to-root myapp    # 301 www.domain → domain
$ cipi www force-from-root myapp  # 301 domain → www.domain
$ cipi www clear myapp            # clear redirect state
$ cipi www status myapp           # inspect redirect state

force-to-root / force-from-root aggiungono automaticamente l'alias mancante quando serve.

cipi domains

Disponibile da v4.5.5. Comando di top level che elenca ogni dominio e alias su tutte le app in un'unica tabella — la controparte globale di cipi alias list <app> per app. Ideale per auditare l'intera mappa dominio→app o individuare un dominio a cui manca ancora un certificato.

bash
$ cipi domains   # list all domains and aliases across every app

Ogni riga mostra le seguenti colonne:

Colonna Descrizione
DOMAIN Il nome del dominio o dell'alias. Le righe sono ordinate alfabeticamente per dominio.
APP L'app proprietaria del dominio.
KIND primary o alias.
TYPE Laravel o Custom.
PHP La versione PHP dell'app.
DOCROOT public per app Laravel, /<docroot> per app custom.
BRANCH Il branch Git deployato per l'app.
LAST DEPLOY Età relativa leggibile (just now, 10m ago, 2h ago, 3d ago, 2w ago, 2mo ago, 2y ago) — derivata dal mtime del symlink current dell'app, che Deployer riallinea atomicamente a ogni deploy riuscito. Mostra - quando l'app non è mai stata deployata.
SSL Stato del certificato per nome (/), rilevato da /etc/letsencrypt/live/<domain>.
REPOSITORY Il repository Git, oppure (SFTP only) per app custom senza repo.
(suffix) Quando l'app proprietaria è sospesa, ogni riga termina con ⏸ suspended (giallo). Il footer riporta anche quante app sono sospese.

Un footer riassume i totali — numero di domini, app, certificati e app sospese — così puoi auditare l'intera mappa a colpo d'occhio.

cipi ssl

Certbot gestisce i certificati Let's Encrypt. I certificati si rinnovano automaticamente tramite un cron settimanale. cipi ssl status mostra le date di scadenza con avvisi a colori: verde (>30 giorni), giallo (14–30 giorni), rosso (<14 giorni).

bash
$ cipi ssl install myapp   # provision / renew — includes all aliases (SAN)
$ cipi ssl force myapp     # re-apply HTTP→HTTPS redirect (no new issuance)
$ cipi ssl renew            # force renewal of all certificates
$ cipi ssl status           # show all certs with expiry dates

# DNS-01 via Cloudflare (v5.0+) — wildcard certs
$ cipi ssl dns set --provider=cloudflare --token=YOUR_CF_TOKEN
$ cipi ssl install myapp --dns=cloudflare
$ cipi ssl install myapp --dns=cloudflare --wildcard

Da v4.8.0, cipi ssl force <app> riapplica il redirect HTTP → HTTPS per un'app che ha già un certificato Let's Encrypt — senza emetterne uno nuovo. cipi ssl install imposta anche force_https in apps.json automaticamente.

Da v5.0, le challenge opzionali DNS-01 via Cloudflare sostituiscono il flusso HTTP-01 predefinito quando ti servono certificati wildcard o non puoi esporre la porta 80. Configura una volta con cipi ssl dns set, poi passa --dns=cloudflare (e opzionalmente --wildcard) a cipi ssl install.

Dopo aver aggiunto alias di dominio con cipi alias add, esegui sempre di nuovo cipi ssl install per provisionare un nuovo certificato SAN che copra tutti i domini. Se il redirect HTTPS è andato perso dopo un cambio vhost, usa cipi ssl force invece di riemettere.

cipi backup

Esegui backup di database e storage su Amazon S3 o qualsiasi provider compatibile S3 (Hetzner Object Storage, DigitalOcean Spaces, Backblaze B2, MinIO, ecc.).

Configurazione

bash
$ cipi backup configure
# → AWS Access Key ID
# → AWS Secret Access Key
# → Bucket name
# → Region
# → Endpoint URL (leave empty for AWS; required for other providers)

Endpoint compatibili S3

Provider URL endpoint
AWS S3 lascia vuoto
Hetzner https://<datacenter>.your-objectstorage.com
DigitalOcean Spaces https://<region>.digitaloceanspaces.com
Backblaze B2 https://s3.<region>.backblazeb2.com
MinIO https://your-minio-host

Esecuzione dei backup

bash
$ cipi backup configure              # configure S3 credentials
$ cipi backup run                    # backup all apps
$ cipi backup run myapp              # backup a single app
$ cipi backup list                   # list all backups
$ cipi backup list myapp             # list backups for one app
$ cipi backup prune myapp --weeks=4  # delete backups older than 4 weeks

Ogni backup viene caricato su s3://your-bucket/cipi/appname/YYYY-MM-DD_HHMMSS/ e contiene:

  • db.sql.gz — dump del database compresso
  • shared.tar.gz — l'intera directory shared/ (.env + storage/)

Da v4.7.14, lo staging dei backup usa di default /var/tmp (disco) invece di /tmp (spesso un tmpfs RAM di dimensioni limitate), così le app grandi non falliscono a metà backup quando il tmpfs si riempie. Override con tmpdir in backup.json (impostato via cipi backup configure) o la variabile d'ambiente CIPI_BACKUP_TMPDIR.

Pianificazione backup automatici

bash
# Add to root crontab (crontab -e)
0 2 * * * /usr/local/bin/cipi backup run >> /var/log/cipi/backup.log 2>&1

Pulizia backup obsoleti da S3

I backup si accumulano nel tempo. Usa cipi backup prune per eliminare da S3 le cartelle di backup più vecchie di N settimane. Eseguilo come job cron insieme al backup stesso.

bash
$ cipi backup prune myapp --weeks=4   # delete backups older than 4 weeks
$ cipi backup prune myapp --weeks=2   # keep only the last 2 weeks

Aggiungi entrambi i comandi al crontab di root per eseguirli automaticamente:

bash
# root crontab — backup at 02:00, prune at 03:00 (keep 4 weeks)
0 2 * * * /usr/local/bin/cipi backup run myapp >> /var/log/cipi/backup.log 2>&1
0 3 * * * /usr/local/bin/cipi backup prune myapp --weeks=4 >> /var/log/cipi/backup-prune.log 2>&1
cipi backup prune legge le credenziali S3 da /etc/cipi/backup.conf, scritto da cipi backup configure. Funziona con qualsiasi provider compatibile S3. Regola --weeks in base alla tua policy di retention (es. --weeks=2 per due settimane, --weeks=8 per due mesi).

Crontab utente

Cipi aggiunge automaticamente una voce crontab per lo scheduler Laravel quando crei un'app:

bash
# installed automatically by cipi app create
* * * * * /usr/bin/php8.5 /home/myapp/current/artisan schedule:run >> /dev/null 2>&1

Questa voce gira come utente Linux myapp ogni minuto, usando la versione PHP selezionata per l'app. Viene aggiornata automaticamente quando cambi versione PHP con cipi app edit myapp --php=X.

Visualizzare il crontab attuale

bash
# as root — view the app user's crontab
$ crontab -u myapp -l

# or after switching to the app user
$ su - myapp
myapp@server:~$ crontab -l

Aggiungere job cron personalizzati

Puoi aggiungere job cron extra al crontab dell'utente app. Passa prima all'utente app per assicurarti che i job girino con il contesto utente e i permessi file corretti:

bash
$ su - myapp
myapp@server:~$ crontab -e

Esempi di voci che potresti aggiungere:

bash
# existing Laravel scheduler (do not remove)
* * * * * /usr/bin/php8.5 /home/myapp/current/artisan schedule:run >> /dev/null 2>&1

# nightly database backup at 2 AM
0 2 * * * /usr/local/bin/cipi db backup myapp >> /home/myapp/logs/backup.log 2>&1

# custom script every 15 minutes
*/15 * * * * /home/myapp/current/scripts/sync.sh >> /home/myapp/logs/sync.log 2>&1
Non rimuovere la voce dello scheduler Laravel. Cipi non la re-inserisce automaticamente se eliminata — dovresti eseguire cipi app edit myapp --php=<current-version> per ripristinarla. Tieni sempre la riga schedule:run come prima voce così è facile identificarla.
I job cron girano come utente app. Rispettano le stesse restrizioni filesystem dell'app. Se un job cron deve scrivere file, assicurati che il percorso di destinazione sia dentro /home/myapp/. I job che richiedono accesso root vanno aggiunti al crontab di root, con crontab -e come root.

Verificare che cron funzioni

bash
# check system cron log
$ grep CRON /var/log/syslog | grep myapp | tail -20

# check Laravel scheduler execution
$ cipi app artisan myapp schedule:list

cipi schedule

Da v5.0, gestisci la voce crontab dello scheduler Laravel che esegue schedule:run (il crontab esisteva già; ora è attivabile/disattivabile e tracciato in apps.json).

bash
$ cipi schedule on myapp
$ cipi schedule off myapp
$ cipi schedule status myapp

cipi worker & Laravel Horizon

Ogni app ottiene un worker Supervisor predefinito per la queue default. Puoi aggiungere queue aggiuntive con conteggi processo e timeout personalizzati.

bash
$ cipi worker add myapp --queue=emails --processes=3
$ cipi worker add myapp --queue=exports --processes=1 --timeout=7200
$ cipi worker list myapp
$ cipi worker edit myapp --queue=default --processes=3
$ cipi worker remove myapp emails
$ cipi worker restart myapp   # restart all workers for the app
$ cipi worker stop myapp      # stop all workers for the app (used during deploys)

# Laravel Horizon (v5.0+) — mutually exclusive with queue:work workers
$ cipi worker horizon enable myapp
$ cipi worker horizon status myapp
$ cipi worker horizon disable myapp

Con Horizon abilitato, il deploy esegue horizon:terminate e riavvia i worker tramite cipi-worker. Non puoi far girare worker classici queue:work e Horizon sulla stessa app contemporaneamente.

Flag Descrizione
--queue=<name> Nome della queue da consumare (es. default, emails, exports)
--processes=<n> Numero di processi worker paralleli
--timeout=<seconds> Timeout del job in secondi. Il default è 60.

I worker vengono fermati prima dello swap del symlink e riavviati dopo ogni deploy, evitando che Supervisor usi percorsi artisan obsoleti. Supervisor è configurato con autorestart=unexpected così i worker si riavviano solo in caso di uscita inattesa, non su stop graceful.

Helper utente app: cipi-worker

Ogni utente app può riavviare, fermare o controllare i worker senza root — tramite un helper sudo ristretto installato in /usr/local/bin/cipi-worker:

bash
# run as the app user (SSH or sudo su - myapp)
$ sudo cipi-worker status myapp
$ sudo cipi-worker stop myapp      # used by Deployer before symlink swap
$ sudo cipi-worker restart myapp

Come root, usa cipi worker list|restart|stop <app>. Non esiste un comando admin cipi worker status — usa cipi worker list o l'helper utente app sopra.

cipi health

Da v5.0, configura healthcheck HTTP per app. Un cron gira ogni 5 minuti; dopo 3 fallimenti consecutivi Cipi notifica tramite il trigger health_fail (SMTP se configurato).

bash
$ cipi health set myapp --url=https://myapp.com/up --expect=200
$ cipi health check myapp
$ cipi health list
$ cipi health unset myapp

cipi firewall

Cipi installa UFW con le porte 22, 80 e 443 aperte di default. Usa i comandi firewall per gestire regole aggiuntive senza toccare UFW direttamente.

bash
$ cipi firewall allow 3306                  # open a port
$ cipi firewall allow 3306 --from=10.0.0.5  # allow from specific IP
$ cipi firewall allow 3306 --from=10.0.0.0/24 # allow from subnet
$ cipi firewall deny 8080                   # block a port
$ cipi firewall list                        # show all rules

cipi ban

Ispeziona e gestisci i ban Fail2ban direttamente dalla CLI. Cipi configura Fail2ban con ban progressivi: ban base di 24 ore che raddoppia a ogni recidiva fino a un tetto di 7 giorni, con tentativi massimi ridotti a 3. Una jail dedicata recidive banna i recidivi per 7 giorni dopo 3 ban entro 24 ore.

bash
$ cipi ban list                        # list all banned IPs, grouped by jail
$ cipi ban unban 203.0.113.42           # unban a specific IP from all jails

cipi ban list

Elenca ogni IP attualmente bannato da Fail2ban, raggruppato per jail (es. sshd, recidive). Utile per un controllo rapido della sicurezza o prima di un unban.

cipi ban unban <IP>

Rimuove l'IP indicato da tutte le jail Fail2ban in un colpo solo. Comodo quando un utente legittimo o un runner CI viene bloccato per errore.

Le installazioni esistenti vengono aggiornate automaticamente dallo script di migrazione 4.3.0 quando esegui cipi self-update. Non serve configurazione manuale.

cipi service

Controlla e gestisci i servizi di sistema che alimentano Cipi direttamente dalla CLI. Nginx usa un reload graceful (zero downtime) invece di un restart completo.

bash
$ cipi service list                    # status of all services
$ cipi service list nginx              # status of a specific service
$ cipi service restart                 # restart all services
$ cipi service restart nginx           # graceful reload (zero downtime)
$ cipi service restart php             # restart all PHP-FPM versions
$ cipi service start fail2ban
$ cipi service stop supervisor         # asks for confirmation

Nomi servizio supportati: nginx, mariadb, postgresql (alias: pgsql, postgres — se installato via cipi db install pgsql), valkey-server, supervisor, fail2ban, php<ver>-fpm (es. php8.5-fpm). La keyword php punta a tutte le versioni PHP-FPM installate in una volta. Per il backend cache, redis-server, redis e valkey sono accettati come alias di valkey-server.

Valkey — il fork compatibile Redis con licenza BSD — è incluso nello stack predefinito e sostituisce redis-server da Cipi 4.5.6. È installato con password, legato solo a localhost, e le credenziali (utente, password) sono salvate in /etc/cipi/server.json e mostrate a fine installazione. valkey-server è aggiunto alla blacklist di unattended-upgrades — Cipi lo gestisce, quindi non viene aggiornato automaticamente. Vedi la sezione Valkey per i dettagli e la migrazione automatica Redis → Valkey.

cipi ssh — Gestione chiavi SSH

Gestisci le chiavi SSH autorizzate per l'utente cipi — il punto di ingresso SSH admin. L'utente cipi (gruppo cipi-ssh) usa solo chiave pubblica; il login root è disabilitato. Gli utenti app (gruppo cipi-apps) si connettono con password — vedi SSH come utente app.

Comandi

bash
$ cipi ssh list                 # list all authorized keys with fingerprint, comment, and current-session marker
$ cipi ssh add [key]             # add a new SSH public key (validates format, prevents duplicates)
$ cipi ssh remove [n]            # remove a key by number
$ cipi ssh rename [n] [name]     # change the display name / comment of a key

Meccanismi di sicurezza

cipi ssh remove include due salvaguardie per evitare il lockout:

  • Protezione sessione corrente — non puoi rimuovere la chiave usata dalla tua sessione SSH attiva.
  • Protezione ultima chiave — non puoi rimuovere l'ultima chiave autorizzata rimasta.

Commenti delle chiavi

Le chiavi SSH sono memorizzate con i commenti originali intatti, così è facile capire a chi appartiene ogni chiave. Usa cipi ssh rename per cambiare il nome visualizzato di una chiave:

bash
# list keys to find the number
$ cipi ssh list

# rename key #2
$ cipi ssh rename 2 "john-macbook"

Notifiche email

Quando SMTP è configurato, Cipi invia un avviso email ogni volta che una chiave viene aggiunta, rimossa o rinominata. La notifica include hostname del server, indirizzo IP, fingerprint della chiave, commento della chiave, timestamp e conteggio chiavi rimanenti. Le notifiche di rename includono anche il vecchio e il nuovo nome della chiave.

cipi — Server e self-update

Comandi di top level per lo stato del server e l'auto-gestione di Cipi.

bash
$ cipi status              # CPU, RAM, disk, services, PHP versions, apps
$ cipi version             # show installed Cipi version
$ cipi self-update         # update Cipi to the latest version
$ cipi self-update --check # check for updates without installing

Reset password e credenziali

Cipi fornisce comandi per rigenerare le password a livello server. Le nuove password sono memorizzate in /etc/cipi/server.json (crittografate via Vault) e mostrate a schermo. Salvale subito — vengono mostrate una sola volta.

bash
$ cipi reset root-password              # regenerate the root Linux user SSH password
$ cipi reset db-password [--engine=…]   # regenerate root password (default or chosen engine)
$ cipi reset valkey-password           # regenerate the Valkey password and restart the service
cipi reset valkey-password (alias cipi reset redis-password) riavvia il servizio Valkey. I client connessi verranno disconnessi temporaneamente. Se le tue app usano Valkey per cache o sessioni, aspettati una breve interruzione.