cipi php

PHP 8.5 est préinstallé lors de l'installation. Des versions supplémentaires peuvent être ajoutées à tout moment ; depuis v4.5.12 Cipi sonde APT sources par Ubuntu nom de code — généralement le ondrej/php PPA le 24.04, packages.sury.org le 26.04 lorsque Launchpad n'a pas de suite, ou Ubuntu main comme dernier recours (co-installable 8.3-8.5 là où le dépôt choisi le prend en charge).

Depuis v4.5.4 Cipi lots Déployeur 8, ce qui nécessite PHP ≥ 8,3. cipi php install, cipi php switch, cipi app create et cipi app edit donc n'acceptez que 8.3, 8.4 et 8.5. Les anciennes versions (7.4 à 8.2) restent détectables et amovibles. vous pouvez toujours nettoyer un serveur antérieur à 4.5.4 aveccipi php remove <old-version>.
coup
$ 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

Mises à niveau des correctifs de sécurité

Depuis v4.7.13, PHP forfaits sont exclus du unattended-upgrades et géré par Cipi à la place. cipi php upgrade court apt-get update et --only-upgrade sur chaque installé php* et libphp* package, puis redémarre les pools PHP-FPM concernés. Lorsque SMTP est configuré et les packages ont été mis à niveau, Cipi envoie un e-mail (php_upgrade déclencheur ; désactiver avec cipi notifications disable php_upgrade).

Un contrôle hebdomadaire s'exécute automatiquement sur dimanche à 03h30 via la crontab racine (encapsulé par cipi-cron-notify). Journal : /var/log/cipi/php-upgrade.log. Les serveurs existants reçoivent le cron sur cipi self-update (migration 4.7.13).

Système par défaut ou spécifique à l'application PHP

Le défaut du système est la version PHP utilisée par le root et cipi utilisateurs, le pool FPM Cipi API et le gestionnaire de file d'attente API. Utiliser cipi php switch <ver> à changez-le. La commande migre le pool API (et le pool GUI FPM une fois installé), recrée prises du panneau et redémarre le travailleur API. Depuis 5.0.9+, PUT /api/php/default enveloppe cela via le panneau API (php-manage capacité). Depuis 5.0.10–5.0.12, le commutateur tolère les partiels update-alternatives succès, remonte les racines en lecture seule lorsque cela est nécessaire et conserve API/GUI Pools FPM sur la version cible pour éviter nginx 502.

REPOS : GET /api/php, POST /api/php/install, DELETE /api/php/{version}, PUT /api/php/default (API 1.15.0+ / Cipi 5.0.6+). CLI JSON : cipi php list --json (depuis 5.0.6).

Chaque application a son posséder version PHP (réglée à app create ou via cipi app edit --php=). Déployeur, Composer, déclencheurs de déploiement crontab et cipi sync import exécutez toujours avec le PHP configuré de l'application — jamais avec la valeur par défaut du système.

Pour basculer une application existante vers une version différente :

coup
$ cipi app edit myapp --php=8.5

Cela remplace à chaud la version PHP sans temps d'arrêt : met à jour le pool FPM, le socket Nginx, Supervisor Workers, crontab, configuration du déployeur et .env en une seule opération atomique.

cipi ini

Disponible depuis v5.1.0. Une manière guidée de modifier les paramètres PHP sans chercher le à droite php.ini. Chaque changement à l'échelle du serveur atteint les deux SAPI — PHP-FPM et CLI — donc ce que voient vos requêtes Web est également ce que voient les gestionnaires de file d'attente, artisan et cron voyez.

coup
$ cipi ini list                                # effective values and which layer set them
$ cipi ini list --app=shop                     # as seen by one app
$ cipi ini get memory_limit                    # one setting
$ cipi ini set upload_max_filesize=50M         # server-wide (FPM + CLI)
$ cipi ini set memory_limit=512M --app=shop    # for one app only
$ cipi ini unset memory_limit --app=shop       # fall back to the wider value
$ cipi ini reset [--app=shop]                  # back to Cipi defaults
$ cipi ini keys                                # what can be set, and what cannot

Ce que ça fait pour vous

  • Il augmente les paramètres qui limiteraient silencieusement les vôtres. Paramètre upload_max_filesize soulève également post_max_size et memory_limit alors qu'ils le limiteraient autrement, et les Nginx client_max_body_size est signalé quand il le serait.
  • Il refuse ce qui ne devrait pas être ainsi réglé.Les touches réglables sont explicites liste blanche - voir cipi ini keys. open_basedir, auto_prepend_file, extension et les amis sont refusés par son nom, avec la raison, car Cipi les gère dans le cadre de l'isolation des applications.
  • Les remplacements par application sont gagnants. --app=<app> écrit dans cette application Pool FPM, qui surpasse le fichier à l’échelle du serveur – pour cette application uniquement.

Pourquoi cela devait être réparé

Avant la version 5.1.0, chaque pool FPM était codé en dur upload_max_filesize, post_max_size et max_execution_time, et les valeurs du pool surpassent conf.d - donc à l'échelle du serveur php.ini le changement n’a pas pu atteindre une seule application. En plus de cela, Cipi a écrit 99-cipi.ini pour FPM uniquement, en laissant les CLI SAPI (queue Workers, artisan, cron) sur les valeurs par défaut du package PHP.

Dans la version 5.1.0, les pools ne contiennent que ce qui est véritablement par application (open_basedir, le journal des erreurs, remplacements explicites) et hérite de tout le reste ; les deux SAPI récupèrent leur fichier ; et migration 5.1.0 remplit le CLI 99-cipi.ini et réécrit les pools existants sur mise à jour.

Chaque changement déclenche le ini_set déclencheur de notification, donc un paramètre PHP ne change jamais sur un serveur partagé sans laisser de trace. Une application peut également transporter sa version PHP et ses paramètres par application dans son référentiel - voircipi.yml.

cipi db

Cipi crée une base de données dédiée pour chaqueLaravel l'application automatiquement pendant app create. MariaDB (port 3306) est la valeur native par défaut ; depuis v4.8.0 vous pouvez également installer en option PostgreSQL (port 5432) et choisissez un moteur par base de données ou application. Les applications personnalisées ne disposent pas de base de données – utiliser cipi db create --name=<app>si vous en avez besoin (par exemple pour WordPress ou un autre CMS). Après la configuration, une URL de connexion prête à l'emploi s'affiche (MariaDB : mariadb+ssh://), combinant les informations d'identification SSH, l'adresse IP du serveur et les informations de base de données pour GUI clients comme TablePlus, DBeaver ou Sequel Pro.

Moteurs (v4.8.0+)

coup
$ 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

Cycle de vie de la base de données

coup
$ 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=…]

Laravel les applications stockent le moteur choisi dans les métadonnées de l'application ; sauvegarde, synchronisation et cipi app reset-db-password suivez-le. Utiliser cipi app create --engine=pgsql (ou l'invite interactive) pour provisionner une application Laravel le PostgreSQL — .env et l'URL de connexion correspond au moteur. Réinitialisation du mot de passe root : cipi reset db-password [--engine=].

cipi alias

Ajoutez plusieurs domaines ou sous-domaines à n'importe quelle application. Après avoir ajouté des alias, exécutez cipi ssl installpour fournir ou renouveler le certificat avec une couverture SAN pour tous domaines. Depuis v4.8.0, cipi alias add|remove régénère le vhost et réapplique SSL avec certbot install --redirect donc HTTPS n'est pas supprimé.

coup
$ cipi alias add myapp www.myapp.com
$ cipi alias add myapp myapp.it
$ cipi alias add myapp '*.monapp.com'   # wildcard (v5.1.0+) — quote it
$ cipi alias list myapp
$ cipi alias remove myapp myapp.it

Depuis v5.1.0, alias génériques comme *.example.com sont acceptés — Nginx correspond à un caractère générique server_name de manière native, et les applications multi-locataires en ont besoin. Citez le motif pour que le shell ne le développe pas, et délivrer le certificat avec cipi ssl install myapp --dns=cloudflare --wildcard: HTTP-01 ne peut pas valider un caractère générique.

Pour les redirections canoniques www ↔ apex, préférez cipi www au lieu de gérer manuellement l'hôte homologue.

cipi www

Disponible depuis v4.8.0. Gérez les alias www/apex et les redirections canoniques 301 pour un application. L'État vit dans apps.json (www_redirect); Nginx émet un signal dédié bloc de serveur de redirection (chemin ACME maintenu public) qui survit à la régénération du vhost. SSL est réappliqué viacertbot install --redirect.

coup
$ 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 ajoutez automatiquement l'alias manquant si nécessaire.

cipi domains

Disponible depuis v4.5.5. Une commande de niveau supérieur qui répertorie chaque domaine et alias à travers tout applications dans une seule table - l'équivalent mondial de le par application cipi alias list <app>. Idéal pour auditer l’ensemble mappage domaine-application ou détection d'un domaine pour lequel il manque toujours un certificat.

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

Chaque ligne affiche les colonnes suivantes :

Colonne Descriptif
DOMAINE Le nom de domaine ou alias. Les lignes sont triées par ordre alphabétique par domaine.
APPLICATION L'application propriétaire du domaine.
GENRE primary ou alias.
TYPE Laravel ou Custom.
PHP La version PHP de l'application.
DOCROOT public pour Laravel applications, /<docroot> pour les applications personnalisées.
BRANCHE La branche Git déployée pour l'application.
DERNIER DÉPLOIEMENT Âge relatif à l'homme (just now, 10m ago, 2h ago, 3d ago, 2w ago, 2mo ago, 2y ago) — dérivé de l'heure mtime de l'application current lien symbolique, quel déployeur repointe atomiquement chaque déploiement réussi. Spectacles - quand l'application était jamais déployé.
SSL Statut du certificat par nom (/), détecté à partir de /etc/letsencrypt/live/<domain>.
DÉPÔT Le dépôt Git, ou (SFTP only) pour les applications personnalisées sans dépôt.
(suffixe) Lorsque l'application propriétaire est suspendue, chaque ligne se termine par ⏸ suspended (jaune). Le pied de page indique également le nombre d'applications suspendues.

Un pied de page résume les totaux (nombre de domaines, d'applications, de certificats et d'applications suspendues), ce qui rend il est facile de vérifier l'ensemble de la cartographie en un coup d'œil.

cipi ssl

Certbot gère Let's Encrypt certificats. Les certificats se renouvellent automatiquement via un cron hebdomadaire. cipi ssl status affiche les dates d'expiration avec des avertissements de couleur : vert (> 30 jours), jaune (14 à 30 jours), rouge (<14 jours).

coup
$ 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

Depuis v4.8.0, cipi ssl force <app> réapplique le HTTP → HTTPS rediriger vers une application qui possède déjà un certificat Let's Encrypt — sans en émettre un nouveau. cipi ssl install définit également force_https dans apps.json automatiquement.

Depuis v5.0, facultatif DNS-01 les défis via Cloudflare remplacent les flux par défaut HTTP-01 lorsque vous avez besoin de certificats génériques ou que vous ne pouvez pas exposer le port 80. Configurez une fois avec cipi ssl dns set, puis passe --dns=cloudflare (et éventuellement --wildcard) à cipi ssl install.

Après avoir ajouté des alias de domaine avec cipi alias add, cours toujours cipi ssl install à nouveau pour fournir un nouveau certificat SAN couvrant tous les domaines. Si la redirection HTTPS a été perdue après un changement de vhost, utilisez cipi ssl force au lieu de réédition.

cipi nginx default-server

Disponible depuis v5.1.0. Réclamations, quel que soit le cas :80 / :443 n'a pas de serveur par défaut et ferme les requêtes sans correspondance avec une réponse vide (444).

coup
$ cipi nginx default-server status
$ cipi nginx default-server on
$ cipi nginx default-server off

Cipi a toujours eu un serveur par défaut sur :80, mais jamais sur :443. Un HTTPS demande portant un inconnu Host est donc passé à l'hôte vhost Nginx qui avait chargé en premier - pour une application multi-tenant générique, directement dans un résolveur de locataire qui ne peut pas analyser ça.

Il est activé sur les nouvelles installations, et migration 5.1.0 le réclame sur les serveurs existants là où rien d'autre ne le fait déjà. Si un autre vhost possède légitimement le serveur par défaut, la commande le dit et ne change rien.

cipi backup

Sauvegardez les fichiers d'application et les bases de données sur le disque local, sur Amazon S3 ou sur tout support compatible S3. fournisseur (Cloudflare R2, Hetzner Object Storage, DigitalOcean Spaces, Backblaze B2, Scaleway, MinIO,…).

Depuis v5.1.0 les sauvegardes sont pilotées par profils au lieu d'un travail de nuit codé en dur. Un profil répond à quatre questions : quoi ça prend, à quelle fréquence ça roule, ça va et combien de temps il est conservé - et les profils sont indépendants, donc une copie de 30 minutes de la base de données uniquement conservée sur le disque est heureuse à côté d'une copie complète nocturne cryptée sur S3.

Vous effectuez une mise à niveau à partir de 5.0.x ? Migration 5.1.0 convertit l'ancien travail de nuit en un profil nommé default, reprenant son existant --weeks rétention, et reprend le planning avec un bloc crontab géré. Rien en dehors de ce bloc n'est touché, et cipi backup prune <app> --weeks=N élague toujours la mise en page pré-5.1.

1 — Destinations

cipi backup configure stocke les S3 informations d’identification partagées par chaque profil. Depuis v5.1.0 tu peux quitter le seau vide pour les sauvegardes locales uniquement, sous quelle terre /var/backups/cipi.

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

$ cipi backup status                 # destinations, profiles, last run, overdue

Points de terminaison compatibles S3

Fournisseur URL du point de terminaison
AWS S3 laisser vide
Cloudflare R2 https://<account-id>.r2.cloudflarestorage.com
Hetzner https://<datacenter>.your-objectstorage.com
Espaces DigitalOcean https://<region>.digitaloceanspaces.com
Backblaze B2 https://s3.<region>.backblazeb2.com
Échelle https://s3.<region>.scw.cloud
MinIO https://your-minio-host

2 — Profils de sauvegarde

Créez un profil une fois ; il fonctionne ensuite selon son propre horaire. Deux typiques :

coup
# Every 30 minutes — databases only, kept on the server, last 48 runs
$ cipi backup profile add hourly-db --scope=db \
      --databases='boutique,locataire_*' --exclude-tables='*.jobs,*.télescope_*' \
      --every=30m --keep=48 --dest=local

# Every night at 02:00 — files + databases, encrypted to S3, kept 14 days
$ cipi backup profile add nightly --scope=all \
      --cron='0 2 * * *' --keep-days=14 --dest=s3 --encrypt
coup
$ cipi backup profile list                 # all profiles
$ cipi backup profile show nightly         # one profile in detail
$ cipi backup profile edit nightly --keep-days=30
$ cipi backup profile disable hourly-db    # pause it without deleting it
$ cipi backup profile enable hourly-db
$ cipi backup profile remove hourly-db     # deletes the profile, keeps its archives

Drapeaux pour profile add / profile edit

--scope=all|files|dbCe que requiert le profil : candidature fichiers, bases de données ou les deux.
--apps='shop,blog'Quelles applications couvrent ses archives de fichiers. Modèles Glob autorisés.
--databases='main,tenant_*'Quelles bases de données il couvre. Ils sont découverts à partir du moteur lui-même, de sorte que les bases de données de locataires qu'une application crée au moment de l'exécution sont également assortis.
--exclude-databases='<glob,…>'Bases de données à quitter parmi une sélection par ailleurs large.
--exclude-tables='*.jobs,*.telescope_*'Tableaux à ignorer — développé par rapport à la liste des tables en direct le MariaDB, transmis directement àpg_dump sur PostgreSQL.
--every=30m|6h|1d ou --cron='0 2 * * *'À quelle fréquence il fonctionne.
--dest=local|s3|local,s3Où va la course.
--keep=N / --keep-days=N / --keep-weeks=NRétention — au moins un est obligatoire. Un le profil qui grandirait sans limite est refusé.
--encrypt / --no-encryptCôté client AES-256 cryptage avant que quoi que ce soit ne quitte le serveur.
Les applications multi-locataires sont désormais couvertes. Avant la version 5.1.0, une exécution en vidait exactement un base de données par application - celle nommée d'après l'application - donc tenant_1, tenant_2, … n’ont jamais été sauvés du tout. Les bases de données proviennent désormais du moteur (moins schémas système) et sont sélectionnés avec des modèles globaux.

3 — Chiffrement

Avec --encrypt l'archive est cryptée avec AES-256 sur le serveur, avant qu'il ne soit téléchargé, de sorte que l'opérateur du compartiment ne conserve jamais de données lisibles. Le manifeste reste lisible donc une course peut toujours être identifiée.

coup
$ cipi backup key show      # print the key — store it off-server
$ cipi backup key rotate    # new key for future runs
Sans la clé, une sauvegarde chiffrée ne peut pas être restaurée — ni par vous, ni par Cipi. Enregistrez-le dans un gestionnaire de mots de passe au moment où vous activez--encrypt, et rappelez-vous que les courses effectuées avant un key rotate j'ai encore besoin de l'ancienne clé.

4 — Exécuter, vérifier et restaurer

coup
$ cipi backup run                          # run every enabled profile now
$ cipi backup run --profile=nightly        # run one profile now
$ cipi backup run --dry-run                # show what it would take, take nothing
$ cipi backup list [--profile=nightly]     # runs held on each destination
$ cipi backup verify                       # does the newest run of each profile open?
$ cipi backup verify --deep                # same, downloading from S3 to check
$ cipi backup prune [--profile=nightly]    # apply retention now
$ cipi backup fetch nightly 2026-09-02_020000   # download and decrypt one run

Depuis v5.1.0 ces commandes vous disent la vérité plutôt que de vous rassurer :

  • Chaque archive est intégrité vérifiée avant expédition. Un dépotoir écourté par un plein le disque est toujours un fichier non vide, donc la vérification de l'ancienne taille l'a réussi ; maintenant une archive corrompue est jeté et signalé au lieu de remplacer discrètement une bonne sauvegarde.
  • cipi backup fetch ne signale plus le succès sur un préfixe qui ne contient aucun objet, donc un un horodatage mal saisi est une erreur plutôt qu'un répertoire vide.
  • cipi backup verify dit clairement qu'il n'y a rien à vérifier lorsqu'aucune exécution n'a été effectuée. arrivé, au lieu de « passé ».
  • tar avertissements - "fichier modifié au fur et à mesure que nous le lisons", constante sur une application en direct écrivant son logs - n'échoue plus une archive parfaitement bonne. Seul le code de sortie 2 et supérieur compte.
  • A désactivé le profil s'arrête réellement de fonctionner, et Encrypted est affiché correctement.

Pour restaurer, récupérez le run et réinjectez les pièces :

coup
$ cipi backup fetch nightly 2026-09-02_020000 --dest=/root/restore
$ cipi db restore myapp /root/restore/databases/mariadb/myapp.sql.gz
$ tar -tzf /root/restore/apps/myapp/files.tar.gz

5 — Agencement des rangements

Les fichiers d'application et les bases de données sont stockés séparément, avec un manifeste par exécution - donc un profil de base de données uniquement ne coûte rien et une base de données peut être restaurée sans décompresser un fichier. application.

texte
<root>/<profile>/<YYYY-MM-DD_HHMMSS>/
├── manifest.json
├── apps/
│   └── myapp/
│       ├── files.tar.gz
│       └── meta.json
└── databases/
    └── mariadb/
        └── myapp.sql.gz

# local  → /var/backups/cipi/<profile>/<timestamp>/
# s3     → s3://<bucket>/cipi/<profile>/<timestamp>/

La préparation de sauvegarde est par défaut /var/tmp (disque) plutôt que /tmp (souvent un petit tmpfs sauvegardé par RAM), afin que les applications volumineuses n'échouent pas à mi-sauvegarde lorsque tmpfs se remplit. Remplacer par tmpdir dans backup.json (réglé via cipi backup configure) ou le CIPI_BACKUP_TMPDIR variable d'environnement.

6 — Calendrier et chien de garde de l'obsolescence

Vous n’écrivez plus cron lignes à la main. cipi backup configure et à chaque changement de profil réécrire un bloc marqué dans la crontab de root ; tout ce qui se trouve en dehors de ce bloc est laissé seuls, et les lignes manuscrites antérieures à la version 5.1 sont absorbées lors de la migration.

Un chien de garde horaire relève lebackup_stale notification lorsqu'un profil n'a pas réussi dans un délai de deux fois son propre intervalle, car une sauvegarde qui s'est arrêtée silencieusement est pire que rien sauvegarde du tout : il semble toujours configuré. Un profil fraîchement créé n'est pas signalé comme en retard avant que sa première exécution programmée ait pu avoir lieu.

Taille héritée

cipi backup prune <app> --weeks=N continue de travailler contre la mise en page pré-5.1 (s3://<bucket>/cipi/<app>/<timestamp>/ plus des dumps de pré-déploiement dans /var/log/cipi/backups), donc les archives existantes et toute ligne cron manuscrite sont toujours tailler. Utilisation de nouveaux profils --keep, --keep-days ou --keep-weeks plutôt.

Une application peut déclarer ses propres profils de sauvegarde dans son référentiel — voir cipi.yml. Les profils appartenant à une application doivent être nommé <app> ou <app>-*; les profils à l'échelle du serveur restent sous votre contrôle seulement.

Crontab utilisateur

Cipi ajoute automatiquement une entrée crontab pour le planificateur Laravel lorsqu'une application est créée :

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

Cette entrée fonctionne comme le myapp utilisateur Linux chaque minute, en utilisant la version PHP sélectionnée pour l'application. Elle est mise à jour automatiquement lorsque vous changez de version PHP via cipi app edit myapp --php=X.

Affichage de la crontab actuelle

coup
# 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

Ajout de cron tâches personnalisées

Vous pouvez ajouter cron tâches supplémentaires à la crontab de l'utilisateur de l'application. Basculez d'abord vers l'utilisateur de l'application pour garantir les emplois exécuter avec le contexte utilisateur et les autorisations de fichier corrects :

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

Exemples d'entrées que vous pourriez ajouter :

coup
# 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
Ne supprimez pas l’entrée du planificateur Laravel. Cipi ne le rajoute pas automatiquement s'il est supprimé - vous devrez exécuter cipi app edit myapp --php=<current-version> pour le restaurer. Gardez toujours le schedule:run ligne comme première entrée afin qu’elle soit facile à identifier.
Cron tâches s'exécutent en tant qu'utilisateur de l'application. Ils respectent les mêmes restrictions du système de fichiers comme l'application elle-même. Si une tâche cron doit écrire des fichiers, assurez-vous que le chemin cible se trouve à l'intérieur /home/myapp/. Les tâches nécessitant un accès root doivent être ajoutées à la crontab racine à la place, avec crontab -e comme racine.

Vérifier si cron fonctionne

coup
# 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

Depuis v5.0, gérez l'entrée crontab du planificateur Laravel qui exécute schedule:run (la crontab elle-même existait déjà ; elle est désormais basculable et suivie dans apps.json).

coup
$ cipi schedule on myapp
$ cipi schedule off myapp
$ cipi schedule status myapp

cipi worker & Laravel Horizon

Chaque application reçoit un travailleur Supervisor par défaut pour le default file d'attente. Vous pouvez ajouter des files d'attente avec des décomptes de processus et des délais d'attente personnalisés.

coup
$ 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

Avec Horizon activé, déploiement d'exécutions horizon:terminate et redémarre les travailleurs via cipi-worker. Vous ne pouvez pas exécuter Classic queue:work les travailleurs et Horizon sur la même application en même temps.

Sur 5.0.x, cipi worker horizon enable pourrait quitter Horizon la moitié activé: la commande n'imprimait rien après « Activation Horizon… » et status dit encore disabled. v5.1.0 corrige les deux causes, écrit toujours l'état, rapporte ce que Supervisor a réellement fait et rend status faire apparaître toute dérive entre les deux. Si tu frappes ça, cours cipi self-update et activer encore une fois.

Les travailleurs de file d'attente peuvent également être déclarés dans le référentiel de l'application — voir cipi.yml.

Drapeau Descriptif
--queue=<nom> Nom de la file d'attente à consommer (par ex. default, emails, exports)
--processes=<n> Nombre de processus de travail parallèles
--timeout=<secondes> Délai d'expiration de la tâche en secondes. La valeur par défaut est 60.

Les travailleurs sont arrêtés avant l'échange de lien symbolique et redémarrés après chaque déploiement, empêchant ainsi Supervisor provenant du ramassage des artisan chemins. Supervisor est configuré avec autorestart=unexpected afin que les travailleurs redémarrent uniquement lors de sorties inattendues, et non lors de sorties gracieuses. s'arrête.

Assistant utilisateur de l'application : cipi-worker

Chaque utilisateur de l'application peut redémarrer, arrêter ou vérifier les travailleurs sans root - via un assistant sudo restreint installé à /usr/local/bin/cipi-worker:

coup
# 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

En tant que root, utilisez cipi worker list|restart|stop <app> à la place. Il n'y a pas cipi worker status commande admin - utiliser cipi worker list ou l'utilisateur de l'application aide ci-dessus.

cipi health

Depuis v5.0, configurez HTTP contrôles de santé par application. Cipi regarde ensuite l'application en deux de différentes manières, car « le site est-il opérationnel ? » et « est-ce que la poussée que je viens de faire a interrompu la production ? ne sont pas la même question.

Vérifier Quand il court Quand il alerte
Sonde périodique Toutes les 5 minutes Après 3 consécutives échecs → health_fail
Vérification post-déploiement Juste après la mise en ligne de chaque version Immédiatement au premier échec → deploy_health_fail
coup
$ cipi health set myapp --url=https://myapp.com/up --expect=200
$ cipi health check myapp
$ cipi health list
$ cipi health unset myapp

# Structured output (v5.0.6+) — panel API / scripts
$ cipi health list --json
$ cipi health check myapp --json

Vérification post-déploiement (v5.1.0+)

Une fois qu'une application dispose d'une URL de contrôle de santé, la version qui vient d'être mise en ligne est vérifiée juste après chaque déployer — à partir de cipi deploy et depuis Git webhook également. La sonde attend une courte grâce période (8 secondes pour Octane applications, 3 sinon, ou autre--grace=N dit) et réessaye cinq fois, donc un l'application qui a besoin d'un moment pour apparaître n'est pas signalée comme étant en panne.

Le verdict ne modifie jamais le code de sortie du déploiement — la version est en ligne dans les deux cas — mais l'alerte le dit et vous remet la commande de restauration. L'e-mail de réussite est envoyé après vérification, il ne peut donc jamais annoncer un déploiement réussi alors que le site renvoie 500.

coup
$ cipi health postdeploy myapp             # run the post-deploy verification now
$ cipi health set myapp --grace=15         # give the release longer to warm up (max 120)
$ cipi health set myapp --no-postdeploy    # turn the post-deploy check off for this app

Restauration automatique d'une version défectueuse (opt-in)

Cipi peut annuler une version qui échoue à son contrôle de santé post-déploiement : le current lien symbolique revient à la version précédente, l'application est à nouveau testée et un email décrit toute la séquence : ce qui a été publié, ce à quoi elle a répondu, ce à quoi elle a été annulée et si cela a résolu le problème.

coup
$ cipi health set myapp --rollback-on-unhealthy   # permanent, per app
$ cipi deploy myapp --rollback-on-unhealthy       # just this deploy

Quatre résultats sont rapportés distinctement : récupéré; reculé mais quand même malsain (donc la cause n'est probablement pas le code) ; la restauration elle-même échoué (la mauvaise version est toujours en ligne) ; et il n'y a pas de version antérieure revenir à.

La restauration automatique est désactivé par défaut et délibérément : les migrations de bases de données ne sont pas défait. Une version qui a migré le schéma puis a échoué peut être dans une situation pire après le code est annulé. Activez-le uniquement pour les applications dont les déploiements ne migrent pas ou pour lesquelles vous savez les migrations sont rétrocompatibles.

REPOS : GET /api/health, GET|PUT|DELETE /api/apps/{name}/health, POST /api/apps/{name}/health/check (API 1.15.0+ / Cipi 5.0.6+). Une application peut également déclarer son bilan de santé dans son référentiel — voir cipi.yml.

cipi firewall

Cipi installe UFW avec les ports 22, 80 et 443 ouverts par défaut. Utilisez les commandes du pare-feu pour gérer règles supplémentaires sans toucher directement à UFW.

coup
$ 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

Inspectez et gérez les bannissements Fail2ban directement depuis le CLI. Cipi configure Fail2ban avec progressif interdiction : une interdiction de base de 24 heures qui double à chaque récidive jusqu'à un plafond de 7 jours, avec un maximum de tentatives réduit à 3. Un dédiérecidive la prison interdit les récidivistes pendant 7 jours après 3 interdictions dans les 24 heures.

coup
$ 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

Répertorie toutes les adresses IP actuellement interdites par Fail2ban, regroupées par prison (par ex. sshd, recidive). Utile pour un contrôle de sécurité rapide ou avant d'exécuter un bannissement.

cipi ban unban <IP>

Supprime l'adresse IP donnée de toutFail2ban emprisonne immédiatement. Pratique lorsqu'un utilisateur légitime ou le coureur CI est exclu par erreur.

Les installations existantes sont automatiquement mises à niveau par le script de migration 4.3.0 lorsque vous exécutez cipi self-update. Aucune configuration manuelle n'est nécessaire.

cipi service

Vérifiez et contrôlez les services système qui alimentent le Cipi directement à partir du CLI. Nginx utilise un gracieux recharger (zéro temps d'arrêt) au lieu d'un redémarrage complet.

coup
$ 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

# Structured output (v5.0.6+) — panel API
$ cipi service list --json

REPOS : GET /api/services, POST /api/services/{name}/restart (API 1.15.0+ / Cipi 5.0.6+; capacités services-view / services-manage).

Noms de services pris en charge : nginx, mariadb, postgresql (alias : pgsql, postgres — lorsqu'il est installé via cipi db install pgsql), valkey-server, supervisor, fail2ban, php<ver>-fpm (par ex. php8.5-fpm). Le mot clé php cible toutes les versions PHP-FPM installées à la fois. Pour le backend du cache, redis-server, redis, et valkeysont acceptés comme pseudonymes de valkey-server.

Valkey — le fork sous licence BSD et compatible Redis — est inclus dans la pile par défaut et remplace redis-server depuis Cipi 4.5.6. Il est installé avec un mot de passe, lié à localhost uniquement, et ses informations d'identification (utilisateur, mot de passe) sont enregistrées dans /etc/cipi/server.json et montré à la fin de l'installation. valkey-server est ajouté à la liste noire des mises à niveau sans surveillance — Cipi le gère, il est donc pas de mise à niveau automatique. Voir le Valkey section pour plus de détails et la migration automatique Redis → Valkey.

cipi ssh — Gestion des clés SSH

Gérer les clés SSH autorisées pour le cipi user - le point d'entrée SSH de l'administrateur. Le cipi utilisateur (groupe cipi-ssh) utilise uniquement la clé publique ; la connexion root est désactivée. Utilisateurs de l'application (groupe cipi-apps) connectez-vous avec un mot de passe — voir SSH en tant que l'utilisateur de l'application.

Commandes

coup
$ 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

# Structured output (v5.0.6+) — panel API
$ cipi ssh list --json

REPOS : GET|POST /api/ssh/keys, DELETE /api/ssh/keys/{n} (API 1.15.0+ / Cipi 5.0.6+).

Mécanismes de sécurité

cipi ssh remove comprend deux mesures de protection pour éviter le verrouillage :

  • Protection de la session en cours — vous ne pouvez pas supprimer la clé utilisée par votre SSH actif séance.
  • Protection de la dernière clé — vous ne pouvez pas supprimer la dernière clé autorisée restante.

Commentaires clés

Les clés SSH sont stockées avec leurs commentaires d'origine intacts, ce qui facilite l'identification de l'identité de chaque clé. appartient à. Utiliser cipi ssh rename pour modifier le nom d'affichage d'une touche :

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

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

Notifications par courrier électronique

Lorsque SMTP est configuré, Cipi envoie une alerte par e-mail chaque fois qu'une clé est ajoutée, supprimée ou renommée. La notification comprend le nom d'hôte du serveur, l'adresse IP, l'empreinte digitale de la clé, le commentaire clé, l'horodatage, et le nombre de clés restantes. Les notifications de renommage incluent également l’ancien et le nouveau nom de clé.

cipi — Serveur et mise à jour automatique

Commandes de niveau supérieur pour l'état du serveur et l'autogestion Cipi.

coup
$ 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

Réinitialisation du mot de passe et des informations d'identification

Cipi fournit des commandes pour régénérer les mots de passe au niveau du serveur. Les nouveaux mots de passe sont stockés dans /etc/cipi/server.json (crypté via Vault) et affiché à l'écran. Enregistrez-les immédiatement — ils ne sont affichés qu'une seule fois.

coup
$ 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) redémarre le service Valkey. Les clients connectés seront temporairement déconnectés. Si vos applications utilisez Valkey pour le cache ou les sessions, attendez-vous à une brève interruption.