WordPress · app custom · GitHub Actions

Deploy di WordPress con Cipi: app custom e auto-deploy da GitHub

Di · Ultimo aggiornamento: · lettura gratuita, nessun paywall

Cipi è Laravel-first, ma ospita anche WordPress come app custom: utente Linux isolato, pool PHP-FPM, vhost Nginx, pull Git in htdocs. Questa guida va da un VPS Ubuntu vuoto a un sito che si deploya da solo a ogni push su main.

In questa guida
  1. Perché un'app custom (non Laravel)
  2. Come strutturare il repo WordPress
  3. Crea l'app custom
  4. Database, DNS e SSL
  5. Primo deploy e wp-config.php
  6. Pipeline GitHub Actions (consigliata)
  7. Percorso più semplice: Git auto-setup
  8. Cron, backup e operazioni di tutti i giorni
  9. FAQ

Perché un'app custom (non Laravel)

Cipi supporta due tipi di app. Il default è Laravel: utente di sistema proprio, PHP-FPM o Octane, MariaDB, .env, worker Supervisor, crontab e release Deployer zero-downtime sotto current/shared. WordPress non è niente di tutto questo.

Un'app custom (cipi app create --custom) è la forma giusta:

I deploy custom non sono zero-downtime. Tieni i diff di tema e plugin piccoli, fai backup del database prima delle release rischiose e lascia che GitHub Actions sia il gate così un check rosso non arriva mai in produzione. Per i pattern zero-downtime Laravel, usa la guida CI/CD per Laravel.

Come strutturare il repo WordPress

Tratta Git come fonte di verità per il codice, non per i segreti o i media. Un repo che sopravvive all'auto-deploy è fatto così:

wordpress-site/
  .gitignore
  .github/workflows/deploy.yml
  wp-admin/
  wp-includes/
  wp-content/themes/your-theme/
  wp-content/plugins/your-plugin/
  wp-config-sample.php
  index.php
  …

Metti questo in .gitignore così un pull non sovrascrive mai lo stato del sito live:

wp-config.php
wp-content/uploads/
wp-content/cache/
wp-content/upgrade/
wp-content/backup-db/
.htaccess

Siccome le app custom fanno pull in htdocs invece di scambiare una directory di release, i file untracked restano sul disco. È così che upload e wp-config.php sopravvivono a ogni deploy.

Crea l'app custom

Cipi deve già essere installato su un VPS Ubuntu fresco:

wget -O - https://cipi.sh/setup.sh | bash

Entra via SSH come cipi, poi sudo -s. Crea l'app WordPress in modo non interattivo (PHP 8.3 è un match sicuro per WordPress attuale; lo cambi dopo con cipi app edit):

$ cipi app create --custom --user=blog \
    --domain=blog.example.com \
    --repository=git@github.com:you/wordpress-site.git \
    --branch=main \
    --php=8.3

Questo provvede:

Se hai già salvato un Personal Access Token GitHub, Cipi aggiunge anche la deploy key e un webhook sul provider in automatico:

$ cipi git github-token ghp_xxxxxxxxxxxxxxxxxxxx
$ cipi git status

I token fine-grained servono Administration e Webhooks impostati su Read and write sul repo target; i token classici servono lo scope repo. I dettagli sono nella documentazione del Git auto-setup.

Solo SFTP (niente Git per ora) — ometti il repository e carica i file in ~/htdocs come utente dell'app:

$ cipi app create --custom --user=blog --domain=blog.example.com --php=8.3

Database, DNS e SSL

Le app custom non ricevono un database. Crealo dopo che l'app esiste — MariaDB è il default e quello che WordPress si aspetta:

$ cipi db create --name=blog

Cipi stampa nome database, utente, password e un URL mariadb+ssh:// per TablePlus o DBeaver. Copia quei valori; vanno in wp-config.php sul server, non in Git.

Punta i record DNS A di blog.example.com e www.blog.example.com al VPS, poi:

$ cipi alias add blog www.blog.example.com
$ cipi www add blog
$ cipi ssl install blog

cipi ssl install emette un certificato Let’s Encrypt che copre tutti gli alias (SAN) e attiva il redirect HTTPS. cipi www tiene apex e www canonici. Vedi SSL e redirect www.

Primo deploy e wp-config.php

Fai pull del repository una volta, poi scrivi la config come utente dell'app così la ownership dei file resta corretta:

$ cipi deploy blog
$ su - blog
blog@server:~$ cd ~/htdocs
blog@server:~/htdocs$ cp wp-config-sample.php wp-config.php
blog@server:~/htdocs$ nano wp-config.php

Valori minimi di produzione (usa le credenziali di cipi db create):

define('DB_NAME', 'blog');
define('DB_USER', 'blog');
define('DB_PASSWORD', 'the-password-cipi-printed');
define('DB_HOST', '127.0.0.1');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');

define('DISALLOW_FILE_EDIT', true);
define('DISABLE_WP_CRON', true);
define('WP_MEMORY_LIMIT', '256M');

Genera salt nuovi da api.wordpress.org/secret-key e incollali al posto dei placeholder. Apri https://blog.example.com e completa l'installer WordPress nel browser.

wp-config.php è untracked. Un cipi deploy successivo non lo cancella. Se ricloni tutta la home, ricrea il file con le stesse credenziali database (cipi db password blog se le hai perse).

Pipeline GitHub Actions (consigliata)

Il webhook Cipi Agent (https://your-app.com/cipi/webhook) è una route dentro un'app Laravel. Su WordPress non esiste. Per l'auto-deploy, fai in modo che GitHub entri via SSH sul server ed esegua cipi deploy — lo stesso pipeline SSH deploy che Cipi documenta per le release Laravel con gate.

Scegli un solo trigger. Se il Git auto-setup ha già creato un webhook sul provider, disabilitalo (o non crearlo mai) prima di aggiungere Actions. Due deploy sulla stessa push litigano sul lock file.

1. Chiave SSH dedicata per la CI

Genera una chiave ed25519 sul portatile. Aggiungi la chiave pubblica sul server; salva quella privata come secret GitHub. Non riusare le deploy key Git né la tua chiave SSH personale.

# sul portatile
$ ssh-keygen -t ed25519 -C "ci-deploy-blog" -f ~/.ssh/ci_deploy_blog -N ""
$ ssh-copy-id -i ~/.ssh/ci_deploy_blog.pub cipi@your-server-ip
$ cat ~/.ssh/ci_deploy_blog

Nel repository GitHub: Settings → Secrets and variables → Actions. Crea:

2. File del workflow

Mettilo in .github/workflows/deploy.yml:

name: Deploy WordPress

on:
  push:
    branches: [main]
  workflow_dispatch:

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Guard tracked secrets
        run: |
          if git ls-files --error-unmatch wp-config.php >/dev/null 2>&1; then
            echo "wp-config.php must not be committed"
            exit 1
          fi

      - name: PHP syntax
        uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
          coverage: none
      - name: Lint theme and plugins
        run: |
          find wp-content/themes wp-content/plugins -name '*.php' -print0 \
            | xargs -0 -n1 php -l

  deploy:
    runs-on: ubuntu-latest
    needs: check
    steps:
      - name: Deploy via Cipi
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: cipi
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: sudo cipi deploy blog

Cosa ci guadagni:

Proteggi main: niente push dirette, status check obbligatori, branch di breve vita. Le stesse abitudini trunk-based della guida CI/CD Laravel, senza fingere che WordPress abbia Pest e Pint.

Osserva il deploy dal server:

$ cipi app logs blog --type=deploy

3. Opzionale: backup prima della release

I cambi di schema WordPress sono spesso irreversibili. Snapshot di MariaDB prima, poi deploy:

          script: |
            sudo cipi db backup blog
            sudo cipi deploy blog

Ripristina con cipi db restore blog backup.sql.gz se una release va male. Le app custom non hanno un symlink di release a cui tornare — senza dump del database non c'è undo. Vedi cipi db.

Percorso più semplice: Git auto-setup

Se non ti servono gate CI (sito da solo, commit fidati), salta Actions e lascia che Cipi colleghi GitHub per te:

$ cipi git github-token ghp_xxxxxxxxxxxxxxxxxxxx
$ cipi app create --custom --user=blog --domain=blog.example.com \
    --repository=git@github.com:you/wordpress-site.git --branch=main --php=8.3

Su app create, Cipi aggiunge la deploy key SSH e un webhook sul repository. Il riepilogo mostra auto-configured ✓. Una push su main esegue la stessa pipeline cipi deploy senza un file YAML.

Se hai creato l'app prima di salvare un token, stampa i valori e aggiungili a mano:

$ cipi deploy blog --key       # Settings → Deploy keys
$ cipi deploy blog --webhook   # Settings → Webhooks

Non puntare un sito WordPress all'URL Laravel Agent /cipi/webhook. Quella route esiste solo dopo composer require cipi/agent dentro un'app Laravel. WordPress usa il webhook del provider che Cipi stampa, oppure GitHub Actions via SSH — non entrambi.

Cron, backup e operazioni di tutti i giorni

Sostituisci WP-Cron con il cron di sistema

Le app custom non ricevono un crontab. Con DISABLE_WP_CRON impostato, chiama wp-cron.php dal crontab dell'utente dell'app:

$ su - blog
blog@server:~$ crontab -e
*/5 * * * * /usr/bin/php8.3 /home/blog/htdocs/wp-cron.php >/dev/null 2>&1

Allinea il binario PHP alla versione passata ad app create. Dopo cipi app edit blog --php=8.4, aggiorna il path nel crontab.

Backup

Comandi utili

Comando Cosa fa
cipi deploy blog Pull di main in htdocs
cipi app logs blog --type=deploy Storico deploy
cipi app logs blog --type=php Errori PHP-FPM
cipi app edit blog --php=8.4 Hot-swap PHP
cipi app edit blog --branch=staging Cambia il branch di deploy
cipi db backup blog Dump MariaDB
cipi ssl install blog Rinnova Let’s Encrypt (SAN)

Mettilo in pratica con Cipi

Cipi è la CLI di deploy gratuita e open source usata in questa guida: un comando trasforma un VPS Ubuntu fresco in un server hardened per Laravel e per app PHP custom come WordPress — Nginx, PHP-FPM, MariaDB, SSL e deploy Git inclusi.

wget -O - https://cipi.sh/setup.sh | bash

Domande frequenti

Devo creare WordPress come app Laravel o come app custom in Cipi?

Sempre come app custom. Le app Laravel si aspettano artisan, Composer, un file .env e il layout releases/current. WordPress è un sito PHP classico: cipi app create --custom deploya in htdocs con Nginx già impostato per index.php.

Cipi crea un database per un'app custom WordPress?

No. Le app custom arrivano senza database, .env, cron o queue worker. Dopo aver creato l'app, esegui cipi db create --name=<app> (MariaDB di default) e metti quelle credenziali in wp-config.php sul server.

Un deploy Git cancella gli upload di WordPress?

No, se sono untracked. Le app custom fanno pull in htdocs invece di scambiare un symlink releases. Tieni wp-content/uploads e wp-config.php fuori da Git così media e segreti sopravvivono a ogni cipi deploy.

Posso usare il webhook Cipi Agent per WordPress?

No. La route /cipi/webhook vive dentro un'app Laravel tramite il pacchetto cipi/agent. Per WordPress, lancia i deploy da GitHub Actions via SSH con sudo cipi deploy, oppure usa il Git auto-setup di Cipi (deploy key più webhook del provider) se non ti servono gate CI.

Il deploy di WordPress su Cipi è zero-downtime?

No. Le app custom usano il deploy classico in htdocs — non c'è swap del symlink current/shared. Tieni i diff di tema e plugin piccoli, fai un cipi db backup prima delle release rischiose e usa GitHub Actions così un check rosso non arriva mai sul server.

Continua a leggere