Infraestrutura
cipi php
PHP 8.5 é pré-instalado durante a configuração. Versões adicionais podem ser adicionadas a qualquer momento; desde v4.5.12 Cipi investiga APT fontes por codinome Ubuntu — normalmente o ondrej/php PPA em 24.04, pacotes.sury.orgem 26.04 quando o Launchpad não tem suíte, ou Ubuntu main como um último recurso (co-instalável 8.3–8.5 onde o repositório escolhido o suporta).
cipi php install, cipi php switch,
cipi app create e cipi app edit portanto, aceite apenas
8,3, 8,4 e 8,5. As versões legadas (7.4–8.2) permanecem detectáveis e removíveis, portanto
você ainda pode limpar um servidor anterior à 4.5.4 com cipi php remove <old-version>.$ 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
Atualizações de patches de segurança
Desde v4.7.13, PHP pacotes estão excluídos
unattended-upgrades e gerenciado por Cipi.cipi php upgrade corre
apt-get update e --only-upgrade em cada instalado php* e
libphp* pacote e, em seguida, reinicia os pools PHP-FPM afetados. Quando o SMTP está configurado e
pacotes foram atualizados, Cipi envia um e-mail (php_upgrade gatilho; desabilitar com
cipi notifications disable php_upgrade).
Uma verificação semanal é executada automaticamente em Domingo às 03h30 via root crontab (envolvido por
cipi-cron-notify). Registro:
/var/log/cipi/php-upgrade.log. Os servidores existentes recebem o cron em
cipi self-update (migração 4.7.13).
Padrão do sistema vs específico do aplicativo PHP
O padrão do sistema é a versão PHP usada pelo root e
cipi
usuários, o pool Cipi API FPM e o trabalhador da fila API. Usar cipi php switch <ver>
para
mude isso. O comando migra o pool API (e o pool GUI FPM quando instalado), recria
soquetes do painel e reinicia o trabalhador API. Desde 5.0.9+,
PUT /api/php/default envolve isso através do painel API (php-manage habilidade).
Desde 5.0.10–5.0.12, o switch tolera parcial
update-alternatives sucesso, remonta raízes somente leitura quando necessário e mantém API/GUI
Pools FPM na versão de destino para evitar nginx 502.
DESCANSO: 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 (desde 5.0.6).
Cada aplicativo tem seu próprio Versão PHP (definida em app create ou através
cipi app edit --php=). Deployer, Composer, gatilhos de implantação crontab e
cipi sync import sempre execute com o PHP configurado do aplicativo — nunca o padrão do sistema.
Para mudar um aplicativo existente para uma versão diferente:
$ cipi app edit myapp --php=8.5
Isso troca a quente a versão PHP com tempo de inatividade zero: atualiza o pool FPM, soquete Nginx, Supervisor
trabalhadores, crontab, configuração do Deployer e .env em uma operação atômica.
cipi ini
Disponível desde v5.1.0. Uma maneira guiada de alterar as configurações PHP sem procurar o
certo php.ini. Cada mudança em todo o servidor atinge ambos os SAPIs — PHP-FPM
e CLI — então o que suas solicitações da web veem também é o que os trabalhadores da fila, artisan
e cron veja.
$ 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
O que isso faz por você
- Ele aumenta as configurações que limitariam silenciosamente as suas. Configuração
upload_max_filesizetambém aumentapost_max_sizeememory_limitquando de outra forma eles o limitariam, e Nginx'sclient_max_body_sizeé sinalizado quando deveria. - Recusa o que não deveria ser definido desta forma. As teclas configuráveis são explícitas
lista de permissões - veja
cipi ini keys.open_basedir,auto_prepend_file,extensione amigos são recusados pelo nome, com a razão, porque Cipi os gerencia como parte do isolamento do aplicativo. - As substituições por aplicativo vencem.
--app=<app>escreve no aplicativo Pool FPM, que supera o arquivo de todo o servidor — apenas para esse aplicativo.
Por que isso precisava de conserto
Antes da versão 5.1.0, todos os pools FPM eram codificados upload_max_filesize, post_max_size
e max_execution_timee os valores do pool superam conf.d - portanto, em todo o servidor
php.ini a mudança não pôde atingir um único aplicativo. Além disso, Cipi escreveu
99-cipi.ini somente para FPM, restando os CLI SAPI (trabalhadores de fila, artisan,
cron) nos padrões do pacote PHP.
Na versão 5.1.0, os pools carregam apenas o que é genuinamente por aplicativo (open_basedir, o log de erros,
substituições explícitas) e herdar todo o resto; ambos os SAPIs obtêm seus arquivos; e migração
5.1.0 preenche o CLI 99-cipi.ini e reescreve os pools existentes em
atualizar.
ini_set gatilho de notificação, então uma configuração PHP nunca muda
em um servidor compartilhado sem deixar rastros. Um aplicativo também pode ter sua versão PHP e configurações por aplicativo
em seu repositório - vejacipi.yml.cipi db
Cipi cria um banco de dados dedicado para cada Laravel aplicativo automaticamente durante
app create. MariaDB (porto 3306) é o padrão nativo;
desde v4.8.0 você também pode instalar opcional PostgreSQL (porto
5432) e escolha um mecanismo por banco de dados ou aplicativo. Aplicativos personalizados não obtêm um banco de dados —
usar cipi db create --name=<app> se você precisar de um (por exemplo, para WordPress ou outro
CMS). Após a configuração, um URL de conexão pronto para uso é exibido (MariaDB:
mariadb+ssh://), combinando credenciais SSH, IP do servidor e informações de banco de dados para
GUI clientes como TablePlus, DBeaver ou Sequel Pro.
Motores (v4.8.0+)
$ 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 de vida do banco de dados
$ 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 aplicativos armazenam o mecanismo escolhido nos metadados do aplicativo; backup, sincronização e
cipi app reset-db-password siga-o. Usar
cipi app create --engine=pgsql (ou o prompt interativo) para provisionar um aplicativo Laravel
em PostgreSQL — .env e o URL de conexão correspondem ao mecanismo. Redefinição de senha raiz:
cipi reset db-password [--engine=].
cipi alias
Adicione vários domínios ou subdomínios a qualquer aplicativo. Depois de adicionar aliases, execute
cipi ssl install para provisionar ou renovar o certificado com cobertura SAN para todos
domínios. Desde v4.8.0, cipi alias add|remove regenera o vhost
e reaplica SSL com certbot install --redirect então HTTPS não é descartado.
$ cipi alias add myapp www.myapp.com $ cipi alias add myapp myapp.it $ cipi alias add myapp '*.myapp.com' # wildcard (v5.1.0+) — quote it $ cipi alias list myapp $ cipi alias remove myapp myapp.it
Desde v5.1.0, aliases curinga como
*.example.com são aceitos — Nginx corresponde a um curinga server_name
nativamente, e os aplicativos multilocatários precisam disso. Cite o padrão para que o shell não o expanda e
emitir o certificado com
cipi ssl install myapp --dns=cloudflare --wildcard: HTTP-01 não pode validar um
curinga.
Para redirecionamentos canônicos www ↔ apex, prefira cipi www
em vez de gerenciar o host homólogo manualmente.
cipi www
Disponível desde v4.8.0. Gerencie aliases www/apex e redirecionamentos 301 canônicos para um
aplicativo. Estado vive em apps.json (www_redirect); Nginx emite um sinal dedicado
bloco de servidor de redirecionamento (caminho ACME mantido público) que sobrevive à regeneração do vhost. SSL é reaplicado
através de certbot install --redirect.
$ 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 adicione automaticamente o alias ausente quando necessário.
cipi domains
Disponível desde v4.5.5. Um comando de nível superior que lista cada
domínio e alias em tudo aplicativos em uma única tabela — a contrapartida global de
o por aplicativo cipi alias list <app>. Ideal para auditar o todo
mapeamento de domínio para aplicativo ou detecção de um domínio que ainda não possui um certificado.
$ cipi domains # list all domains and aliases across every app
Cada linha mostra as seguintes colunas:
| Coluna | Descrição |
|---|---|
| DOMÍNIO | O domínio ou nome alternativo. As linhas são classificadas em ordem alfabética por domínio. |
| APLICATIVO | O aplicativo que possui o domínio. |
| TIPO | primary ou alias. |
| TIPO | Laravel ou Custom. |
| PHP | A versão PHP do aplicativo. |
| DOCROOT | public para Laravel aplicativos, /<docroot> para aplicativos personalizados. |
| FILIAL | A ramificação do Git implantada para o aplicativo. |
| ÚLTIMA IMPLEMENTAÇÃO | Idade relativa ao ser humano (just now, 10m ago, 2h ago,
3d ago, 2w ago, 2mo ago, 2y ago) -
derivado do mtime do aplicativo current link simbólico, que o Deployer
reposiciona atomicamente em cada implantação bem-sucedida. Programas - quando o aplicativo foi
nunca implantado. |
| SSL | Status do certificado por nome (✓/✗), detectado de
/etc/letsencrypt/live/<domain>. |
| REPOSITÓRIO | O repositório Git, ou (SFTP only) para aplicativos personalizados sem repositório. |
| (sufixo) | Quando o aplicativo proprietário é suspenso, cada linha termina com ⏸ suspended (amarelo).
O rodapé também informa quantos aplicativos estão suspensos. |
Um rodapé resume os totais — número de domínios, aplicativos, certificados e aplicativos suspensos — fazendo é fácil auditar todo o mapeamento rapidamente.
cipi ssl
Certbot gerencia Let's Encrypt certificados. Os certificados são renovados automaticamente por meio de um cron semanal.
cipi ssl status mostra datas de validade com avisos codificados por cores: verde (>30 dias), amarelo
(14–30 dias), vermelho (<14 dias).
$ 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
Desde v4.8.0, cipi ssl force <app> reaplica o HTTP → HTTPS
redirecionar para um aplicativo que já possui um certificado Let's Encrypt — sem emitir um novo.
cipi ssl install também define force_https em apps.jsonautomaticamente.
Desde v5.0, opcional DNS-01 desafios via Cloudflare substituem o
fluxo padrão HTTP-01 quando você precisar de certificados curinga ou não puder expor a porta 80. Configure uma vez
com cipi ssl dns set, então passe --dns=cloudflare (e opcionalmente
--wildcard) para cipi ssl install.
cipi alias add, sempre corra
cipi ssl installnovamente para provisionar um novo certificado SAN cobrindo todos os domínios.
Se o redirecionamento HTTPS foi perdido após uma alteração no vhost, use cipi ssl force em vez de
reemissão.
cipi nginx default-server
Disponível desde v5.1.0. Reivindica qualquer um dos:80 / :443
não tem servidor padrão e fecha solicitações sem correspondência com uma resposta vazia (444).
$ cipi nginx default-server status $ cipi nginx default-server on $ cipi nginx default-server off
Cipi sempre teve um servidor padrão ligado :80, mas nunca ligado :443. Um HTTPS
solicitação carregando um desconhecido Host portanto, caiu para qualquer vhost Nginx que tivesse
carregado primeiro – para um aplicativo multilocatário curinga, diretamente em um resolvedor de locatário que não pode analisar
isso.
Ele é ativado em novas instalações e migração 5.1.0 reivindica isso em servidores existentes onde nada mais já faz. Se outro vhost possuir legitimamente o servidor padrão, o comando diz isso e não muda nada.
cipi backup
Faça backup de arquivos de aplicativos e bancos de dados no disco local, no Amazon S3 ou em qualquer dispositivo compatível com S3 provedor (Cloudflare R2, Hetzner Object Storage, DigitalOcean Spaces, Backblaze B2, Scaleway, MinIO, …).
Desde v5.1.0 backups são conduzidos por perfis em vez de um trabalho noturno codificado. Um perfil responde a quatro perguntas - o que é preciso, com que frequência ele corre, onde vai e quanto tempo isso é mantido - e os perfis são independentes, portanto, uma cópia de 30 minutos apenas do banco de dados mantida em disco permanece perfeitamente ao lado de uma cópia completa noturna criptografada em S3.
default, transferindo o seu existente --weeks retenção,
e assume o cronograma com um bloco crontab gerenciado. Nada fora desse bloco é tocado,
e cipi backup prune <app> --weeks=N ainda remove o layout pré-5.1.1 – Destinos
cipi backup configure armazena as credenciais S3 compartilhadas por cada perfil. Desde
v5.1.0 você pode deixar o balde vazio para backups somente locais,
que pousa sob /var/backups/cipi.
$ 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
Terminais compatíveis com S3
| Provedor | URL do terminal |
|---|---|
| AWS S3 | deixe vazio |
| Cloudflare R2 | https://<account-id>.r2.cloudflarestorage.com |
| Hetzner | https://<datacenter>.your-objectstorage.com |
| Espaços DigitalOcean | https://<region>.digitaloceanspaces.com |
| Contra-chama B2 | https://s3.<region>.backblazeb2.com |
| Escalada | https://s3.<region>.scw.cloud |
| MinIO | https://your-minio-host |
2 — Perfis de backup
Crie um perfil uma vez; ele então é executado de acordo com sua própria programação. Dois típicos:
# Every 30 minutes — databases only, kept on the server, last 48 runs $ cipi backup profile add hourly-db --scope=db \ --databases='loja, inquilino_*' --exclude-tables='*.jobs,*.telescópio_*' \ --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
$ 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
Bandeiras para profile add / profile edit
tenant_1,
tenant_2,… nunca foram salvos. Os bancos de dados agora vêm do mecanismo (menos
esquemas de sistema) e são selecionados com padrões glob.3 – Criptografia
Com --encrypt o arquivo é criptografado com AES-256 no servidor,
antes de ser carregado, portanto, o operador do bucket nunca retém dados legíveis. O manifesto permanece legível
então uma corrida ainda pode ser identificada.
$ cipi backup key show # print the key — store it off-server $ cipi backup key rotate # new key for future runs
--encrypte lembre-se de que as corridas realizadas
antes de um key rotate ainda preciso da chave antiga.4 — Executando, verificando e restaurando
$ 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
Desde v5.1.0 estes comandos dizem a verdade em vez de tranquilizá-lo:
- Todo arquivo é integridade verificada antes de ser enviada. Um despejo interrompido por um completo o disco ainda é um arquivo não vazio, então a verificação de tamanho antigo foi aprovada; agora um arquivo corrompido é descartado e relatado em vez de substituir silenciosamente um bom backup.
cipi backup fetchnão relata mais sucesso em um prefixo que não contém objetos, então um carimbo de data/hora digitado incorretamente é um erro e não um diretório vazio.cipi backup verifydiz claramente que não há nada a verificar quando nenhuma corrida foi aconteceu ainda, em vez de “aprovado”.taravisos - “arquivo alterado conforme o lemos”, constante em um aplicativo ativo escrevendo seu logs - não falha mais em um arquivo perfeitamente bom. Apenas o código de saída 2 e superior conta.- A desativado profile realmente para de funcionar e
Encryptedé exibido corretamente.
Para restaurar, busque a corrida e alimente as peças de volta:
$ 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 — Layout de armazenamento
Arquivos de aplicativos e bancos de dados são armazenados separadamente, com um manifesto por execução — então um perfil somente de banco de dados não custa nada e um banco de dados pode ser restaurado sem descompactar um aplicativo.
<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>/
O teste de backup é padronizado como /var/tmp (disco) em vez de /tmp (muitas vezes um pequeno
tmpfs com suporte de RAM), para que aplicativos grandes não falhem no meio do backup quando o tmpfs ficar cheio. Substituir por
tmpdir em backup.json (definido através cipi backup configure) ou o
CIPI_BACKUP_TMPDIR variável de ambiente.
6 – Cronograma e o vigilante do envelhecimento
Você não escreve mais cron linhas à mão.cipi backup configure e cada mudança de perfil
reescrever um bloco marcado no crontab do root; qualquer coisa fora desse bloco é deixada
sozinho, e as linhas escritas à mão pré-5.1 são absorvidas na migração.
Um cão de guarda de hora em hora levanta o backup_stale notificação quando um perfil não foi bem-sucedido
dentro do dobro do seu próprio intervalo - porque um backup que parou de funcionar silenciosamente é pior do que nenhum
backup: ainda parece configurado. Um perfil recém-criado não é relatado como vencido
antes que sua primeira execução programada pudesse ter acontecido.
Poda legada
cipi backup prune <app> --weeks=N continua trabalhando no layout pré-5.1
(s3://<bucket>/cipi/<app>/<timestamp>/ além de dumps pré-implantados em
/var/log/cipi/backups), então os arquivos existentes e qualquer linha cron manuscrita ainda
ameixa seca. Novos perfis usados --keep, --keep-days ou --keep-weeks
em vez disso.
cipi.yml. Os perfis pertencentes a um aplicativo devem ser
nomeado <app> ou <app>-*; perfis de todo o servidor permanecem sob
apenas seu controle.Crontab do usuário
Cipi adiciona automaticamente uma entrada crontab para o agendador Laravel quando um aplicativo é criado:
# installed automatically by cipi app create
* * * * * /usr/bin/php8.5 /home/myapp/current/artisan schedule:run >> /dev/null 2>&1
Esta entrada é executada como o myapp usuário Linux a cada minuto, usando a versão PHP selecionada para
o aplicativo. Ele é atualizado automaticamente quando você altera a versão PHP via
cipi app edit myapp --php=X.
Visualizando o crontab atual
# 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
Adicionando cron jobs personalizados
Você pode adicionar cron jobs extras ao crontab do usuário do aplicativo. Mude primeiro para o usuário do aplicativo para garantir empregos execute com o contexto de usuário e permissões de arquivo corretos:
$ su - myapp
myapp@server:~$ crontab -e
Entradas de exemplo que você pode adicionar:
# 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
cipi app edit myapp --php=<current-version> para restaurá-lo. Mantenha sempre o
schedule:run linha como a primeira entrada para que seja fácil de identificar.
/home/myapp/. Jobs que requerem acesso root devem ser adicionados ao crontab root
em vez disso, com crontab -e como raiz.
Verificando se cron está funcionando
# 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
Desde v5.0, gerencie a entrada crontab do agendador Laravel que é executada
schedule:run (o próprio crontab já existia; agora é alternável e rastreado em
apps.json).
$ cipi schedule on myapp $ cipi schedule off myapp $ cipi schedule status myapp
cipi worker & Laravel Horizon
Cada aplicativo recebe um trabalhador padrão Supervisor para o default fila. Você pode adicionar adicionais
filas com contagens e tempos limite de processos personalizados.
$ 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
Com Horizon ativado, a implantação é executadahorizon:terminate e reinicia
trabalhadores através cipi-worker. Você não pode executar o clássico queue:work trabalhadores e
Horizon no mesmo aplicativo de uma só vez.
cipi worker horizon enable poderia sair Horizon metade
habilitado: o comando não imprimiu nada depois de “Ativando Horizon…” e
status ainda disse disabled. v5.1.0 corrige ambas as causas,
sempre escreve o estado, relata o que Supervisor realmente fez e faz status
revelar qualquer desvio entre os dois. Se você acertar isso, corra cipi self-update e habilitar
de novo.Os trabalhadores da fila também podem ser declarados no repositório do aplicativo — consulte
cipi.yml.
| Bandeira | Descrição |
|---|---|
| --queue=<nome> | Nome da fila a consumir (por exemplo default, emails,
exports)
|
| --processos=<n> | Número de processos de trabalho paralelos |
| --timeout=<segundos> | Tempo limite do trabalho em segundos. O padrão é 60. |
Os trabalhadores são parados antes da troca do link simbólico e reiniciados após cada implantação, evitando
Supervisor de pegar obsoleto artisan caminhos. Supervisor está configurado comautorestart=unexpected então os trabalhadores só reiniciam em saídas inesperadas, não em saídas normais
para.
Ajudante do usuário do aplicativo: cipi-worker
Cada usuário do aplicativo pode reiniciar, parar ou verificar trabalhadores sem root – por meio de um auxiliar sudo restrito
instalado em /usr/local/bin/cipi-worker:
# 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
Como root, use cipi worker list|restart|stop <app> em vez disso. Não há
cipi worker status comando de administração - usar cipi worker list ou o usuário do aplicativo
ajudante acima.
cipi health
Desde v5.0, configure HTTP verificações de integridade por aplicativo. Cipi então assiste o aplicativo em dois maneiras diferentes, porque “o site está ativo?” e “o empurrão que acabei de fazer interrompeu a produção?” não são a mesma pergunta.
| Verifique | Quando é executado | Quando alerta |
|---|---|---|
| Sonda periódica | A cada 5 minutos | Depois 3 consecutivos falhas → health_fail |
| Verificação pós-implantação | Logo após cada lançamento ir ao ar | Imediatamente na primeira falha → deploy_health_fail
|
$ 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
Verificação pós-implantação (v5.1.0+)
Depois que um aplicativo tiver um URL de verificação de integridade, a versão que acabou de ser lançada será verificada logo após cada
implantar - de cipi deploy e do Git webhook igualmente. A sonda espera um breve intervalo
período (8 segundos para aplicativos Octane, 3 caso contrário, ou qualquer outro --grace=N diz) e tenta novamente cinco vezes, então um
o aplicativo que precisa de um momento para aparecer não é relatado como quebrado.
O veredicto nunca altera o código de saída da implantação — o lançamento está ativo de qualquer maneira — mas o alerta diz isso e entrega a você o comando de reversão. O email de sucesso é enviado depois verificação, portanto, ele nunca poderá anunciar uma implantação bem-sucedida enquanto o site retornar 500.
$ 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
Reversão automática de uma versão não íntegra (opt-in)
Cipi pode desfazer uma versão que falhou na verificação de integridade pós-implantação: o current link simbólico
volta para a versão anterior, o aplicativo é testado novamente e um e-mail
descreve toda a sequência - o que foi publicado, o que foi respondido, para onde foi revertido e
se isso resolveu o problema.
$ cipi health set myapp --rollback-on-unhealthy # permanent, per app $ cipi deploy myapp --rollback-on-unhealthy # just this deploy
Quatro resultados são relatados distintamente: recuperado; revertido, mas ainda assim insalubre (então a causa provavelmente não é o código); a reversão em si falhou (o lançamento ruim ainda está ativo); e não há lançamento anterior para voltar.
DESCANSO: GET /api/health, GET|PUT|DELETE /api/apps/{name}/health,
POST /api/apps/{name}/health/check (API 1.15.0+ / Cipi
5.0.6+). Um aplicativo também pode declarar sua verificação de integridade em seu repositório — consulte
cipi.yml.
cipi firewall
Cipi instala o UFW com as portas 22, 80 e 443 abertas por padrão. Use os comandos do firewall para gerenciar regras adicionais sem tocar diretamente no UFW.
$ 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
Inspecione e gerencie banimentos do Fail2ban diretamente do CLI. Cipi configura Fail2ban com progressivo
banimento: um banimento básico de 24 horas que dobra a cada reincidência até um limite de 7 dias, com máximo de tentativas
reduzido para 3. Um dedicado recidive prisão proíbe reincidentes por 7 dias após 3 proibições
dentro de 24 horas.
$ 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
Lista todos os IP atualmente banidos pelo Fail2ban, agrupados por prisão (por exemplo, sshd,
recidive). Útil para uma rápida verificação de segurança ou antes de cancelar o banimento.
cipi ban unban <IP>
Remove o IP fornecido de tudoFail2ban prende imediatamente. Útil quando um usuário legítimo ou o CI runner é bloqueado por engano.
cipi self-update. Nenhuma configuração manual é necessária.
cipi service
Verifique e controle os serviços do sistema que alimentam Cipi diretamente do CLI. Nginx usa um gracioso recarregar (zero tempo de inatividade) em vez de uma reinicialização completa.
$ 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
DESCANSO: GET /api/services, POST /api/services/{name}/restart (API
1.15.0+ / Cipi 5.0.6+; habilidades
services-view / services-manage).
Nomes de serviços suportados: nginx, mariadb, postgresql
(apelidos: pgsql, postgres — quando instalado via
cipi db install pgsql), valkey-server,
supervisor, fail2ban, php<ver>-fpm (por exemplo
php8.5-fpm). A palavra-chave
php tem como alvo todas as versões PHP-FPM instaladas de uma só vez. Para o back-end do cache,
redis-server, redise valkey são aceitos como apelidos de
valkey-server.
Valkey — o fork licenciado pelo BSD e compatível com Redis — está incluído na pilha padrão e substitui
redis-server desde Cipi 4.5.6. É instalado com uma senha, vinculada a
localhost apenas, e suas credenciais (usuário, senha) são salvas em
/etc/cipi/server.json e mostrado no final da instalação.
valkey-server é adicionado à lista negra de atualizações autônomas — Cipi gerencia isso, então é
não é atualizado automaticamente. Veja o Valkey seção para detalhes
e a migração automática Redis → Valkey.
cipi ssh — Gerenciamento de chaves SSH
Gerencie as chaves SSH autorizadas para o cipi user — o ponto de entrada SSH do administrador. O
cipi usuário (grupo cipi-ssh) usa apenas chave pública; o login root está desabilitado.
Usuários do aplicativo (grupo cipi-apps) conecte-se com senha — consulte SSH como
o usuário do aplicativo.
Comandos
$ 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
DESCANSO: GET|POST /api/ssh/keys, DELETE /api/ssh/keys/{n} (API
1.15.0+ / Cipi 5.0.6+).
Mecanismos de segurança
cipi ssh remove inclui duas salvaguardas para evitar bloqueio:
- Proteção da sessão atual — você não pode remover a chave usada pelo seu SSH ativo sessão.
- Proteção de última chave — você não pode remover a última chave autorizada restante.
Comentários principais
As chaves SSH são armazenadas com seus comentários originais intactos, facilitando a identificação de quem é cada chave.
pertence. Usar cipi ssh rename para alterar o nome de exibição de qualquer tecla:
# list keys to find the number $ cipi ssh list # rename key #2 $ cipi ssh rename 2 "john-macbook"
Notificações por e-mail
Quando o SMTP é configurado, Cipi envia um alerta por e-mail sempre que uma chave é adicionada, removida ou renomeada. A notificação inclui o nome do host do servidor, endereço IP, impressão digital da chave, comentário da chave, carimbo de data/hora, e contagem de chaves restantes. As notificações de renomeação também incluem o nome da chave antiga e a nova.
cipi — Servidor e autoatualização
Comandos de nível superior para status do servidor e autogerenciamento Cipi.
$ 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
Redefinição de senha e credencial
Cipi fornece comandos para regenerar senhas no nível do servidor. Novas senhas são armazenadas em
/etc/cipi/server.json (criptografado via Vault) e exibido na tela.
Salve-os imediatamente - eles são mostrados apenas uma vez.
$ 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)
reinicia o serviço Valkey. Os clientes conectados serão temporariamente desconectados. Se seus aplicativos
use Valkey para cache ou sessões, espere uma breve interrupção.