dougkusanagi / laravel-deploy
Simple configurable deployment runner for Laravel applications
Package info
github.com/dougkusanagi/laravel-deploy
Language:Shell
pkg:composer/dougkusanagi/laravel-deploy
Requires
- php: ^8.3
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Executor de deploy simples para aplicações Laravel em servidores Linux.
Instalação
composer require dougkusanagi/laravel-deploy:^0.5
vendor/bin/deploy init
Se o pacote ainda não estiver disponível no Packagist, registre o repositório do GitHub antes de instalar:
composer config repositories.laravel-deploy vcs https://github.com/dougkusanagi/laravel-deploy.git
composer require dougkusanagi/laravel-deploy:^0.5
Edite deploy.config.sh e execute:
vendor/bin/deploy
Use vendor/bin/deploy --force para repetir todas as etapas mesmo quando o
commit atual já tiver sido implantado com sucesso.
O pacote também aceita ./deploy.sh quando o projeto mantém um wrapper na raiz.
Configuração
deploy.config.sh é um arquivo Bash confiável carregado antes da atualização do Git. A configuração mínima é:
DEPLOY_BRANCH="${DEPLOY_BRANCH:-main}"
PHP_FPM_SERVICE="${PHP_FPM_SERVICE-}"
PHP_FPM_ACTION="${PHP_FPM_ACTION:-reload}"
WEB_SERVICE="${WEB_SERVICE-}"
HORIZON="${HORIZON:-false}"
QUEUE_RESTART="${QUEUE_RESTART:-false}"
STORAGE_LINK="${STORAGE_LINK:-true}"
INCREMENTAL_DEPLOY="${INCREMENTAL_DEPLOY:-true}"
CACHE_ROUTES="${CACHE_ROUTES:-true}"
CACHE_VIEWS="${CACHE_VIEWS:-true}"
ALLOW_DIRTY_WORKTREE="${ALLOW_DIRTY_WORKTREE:-false}"
FRONTEND_INSTALL=(npm ci)
FRONTEND_BUILD=(npm run build)
Defina os arrays de frontend como vazios para desativar essas etapas:
FRONTEND_INSTALL=()
FRONTEND_BUILD=()
Para usar Bun:
FRONTEND_INSTALL=(bun install --frozen-lockfile)
FRONTEND_BUILD=(bun run build)
As dependências de desenvolvimento do frontend precisam estar disponíveis no
servidor para compilar os assets. Não use --production na instalação quando
Vite, Tailwind ou outras ferramentas de build estiverem em devDependencies.
PHP_FPM_SERVICE e WEB_SERVICE são opcionais. O executor não tenta detectar
nem recarregar automaticamente Caddy ou Nginx. Quando PHP-FPM estiver
configurado, PHP_FPM_ACTION aceita reload (padrão) ou restart.
Defina HORIZON=true em aplicações que usam Horizon. Isso executa
horizon:terminate depois da reconstrução dos caches para que o gerenciador de
processos inicie o Horizon com o código novo. A instalação e a publicação da
configuração do Horizon devem ser feitas durante a preparação da aplicação, não
em cada deploy.
Para workers Laravel comuns, defina QUEUE_RESTART=true. O executor chamará
queue:restart no mesmo ponto. HORIZON e QUEUE_RESTART são mutuamente
exclusivos e o padrão é não reiniciar nenhum worker. Em ambos os casos, os
processos devem ser mantidos por Supervisor, systemd ou outro gerenciador.
CACHE_ROUTES e CACHE_VIEWS habilitam route:cache e view:cache por padrão.
Defina uma dessas opções como false quando a aplicação não puder gerar o
cache correspondente. Deploys que atualizam o runtime PHP continuam limpando
os caches antigos antes de reconstruir os caches habilitados.
Por segurança, alterações locais em arquivos rastreados bloqueiam o deploy.
Arquivos não rastreados, como .env, continuam permitidos. Defina
ALLOW_DIRTY_WORKTREE=true apenas quando esse comportamento for intencional;
alterações locais rastreadas fazem o executor usar o deploy completo.
Também é possível usar FORCE_DEPLOY=true em automações. DEPLOY_LOCK_FILE e
DEPLOY_STATE_FILE permitem alterar os arquivos internos de lock e estado,
armazenados dentro de .git por padrão. O estado guarda o último SHA implantado
com sucesso; arquivos auxiliares .settings e .in-progress guardam a
assinatura da configuração e o marcador de deploy em andamento.
DEPLOY_SETTINGS_FILE e DEPLOY_IN_PROGRESS_FILE permitem definir outros
caminhos para esses arquivos.
Deploy incremental
O executor impede dois deploys simultâneos, valida a árvore de trabalho, busca o
remoto uma única vez e atualiza a branch apenas por fast-forward. O fetch busca
somente a branch configurada, sem buscar tags. Com INCREMENTAL_DEPLOY=true
(padrão), uma comparação Git entre o último deploy bem-sucedido e o novo commit
seleciona as etapas necessárias, incluindo arquivos removidos e renomeados.
| Alteração detectada | Etapas selecionadas |
|---|---|
| Apenas documentação, testes ou arquivos ignorados pelas regras | Verificação da aplicação e registro do novo commit |
composer.json, composer.lock ou dependências PHP locais |
Composer install, build do frontend e atualização do runtime PHP |
| Código PHP | Composer dump-autoload e atualização do runtime PHP |
| Manifestos, lockfiles ou configuração das dependências do frontend | Instalação das dependências e build do frontend |
| Fontes ou configuração de build do frontend | Build do frontend |
| Templates Blade | Build do frontend, cache de views e atualização dos workers/PHP-FPM configurados |
| Configuração do servidor web | Reload do WEB_SERVICE configurado |
| Arquivo sem regra conhecida | Deploy completo |
As etapas se acumulam quando um commit altera mais de uma categoria. A
atualização do runtime PHP inclui migrations isoladas, limpeza e reconstrução
dos caches, atualização dos workers e do PHP-FPM configurados. O Composer
instala dependências sem dev e com autoload otimizado; mudanças apenas no
código PHP usam dump-autoload --no-dev --optimize --no-interaction.
Scripts pre-install-cmd e post-install-cmd no composer.json da aplicação
preservam a execução de composer install em novos commits, porque
dump-autoload não executa esses hooks. Defina COMPOSER_ALWAYS_INSTALL=true
para exigir a instalação em todos os novos commits mesmo sem esses scripts.
Cada instalação do Composer também seleciona o build do frontend para atualizar
assets que dependem de arquivos em vendor.
O primeiro deploy, --force, INCREMENTAL_DEPLOY=false em novos commits, falha anterior, estado
ausente ou inválido, mudanças na configuração do executor e alterações locais
rastreadas permitidas selecionam o fluxo completo. Isso também acontece quando
o commit de referência não está mais disponível ou não permite uma comparação
segura.
Uma execução do mesmo commit bem-sucedido atualiza o Git e termina sem repetir as etapas, desde que o estado, a configuração e os artefatos necessários estejam íntegros. A ausência de dependências ou de artefatos de build seleciona as etapas necessárias para recriá-los. Cada etapa executada registra sua duração; o plano do deploy informa os motivos para executar ou pular etapas.
Caminhos e artefatos
Os arrays de padrões usam globs do Bash, relativos à raiz da aplicação. Mantenha
os padrões entre aspas para evitar expansão antecipada pelo shell. Um padrão
como 'resources/*' também cobre caminhos dentro de subdiretórios.
| Configuração | Uso e padrões incluídos por padrão |
|---|---|
COMPOSER_DEPENDENCY_PATTERNS |
composer.json, composer.lock, 'packages/*' e 'modules/*' |
PHP_SOURCE_PATTERNS |
'*.php', artisan, 'bootstrap/*', 'config/*', 'database/*', 'routes/*' e 'lang/*' |
FRONTEND_DEPENDENCY_PATTERNS |
Manifestos, lockfiles e configuração do gerenciador de pacotes, incluindo projetos aninhados |
FRONTEND_SOURCE_PATTERNS |
resources, public, componentes Livewire/View/Filament e configuração das ferramentas de build |
VIEW_SOURCE_PATTERNS |
'resources/views/*' e '*.blade.php' |
WEB_SERVICE_PATTERNS |
'nginx/*', 'caddy/*', Caddyfile, 'deploy/nginx/*' e 'deploy/caddy/*' |
DEPLOY_IGNORE_PATTERNS |
Documentação, README, testes e arquivos de CI; tem prioridade sobre as regras de código e build |
Os arrays padrão são definidos antes de carregar deploy.config.sh. Use +=
para acrescentar caminhos ou =(...) para substituir a lista inteira:
FRONTEND_SOURCE_PATTERNS+=('app/*' 'themes/*')
COMPOSER_DEPENDENCY_PATTERNS+=('local-packages/*')
Os padrões ignorados prevalecem sobre as outras listas, exceto pelo próprio
arquivo de configuração do deploy. Se arquivos em docs ou tests forem
entradas reais do build/runtime, substitua DEPLOY_IGNORE_PATTERNS por uma
lista que não ignore esses caminhos. Acrescentar uma fonte em um diretório
ignorado, sem ajustar essa lista, não seleciona o build.
Inclua em FRONTEND_SOURCE_PATTERNS todos os caminhos examinados pelo Tailwind
ou por outras ferramentas que geram assets a partir do código. Por exemplo,
classes CSS em arquivos PHP de app exigem o padrão 'app/*'. Para monorepos,
dependências locais e estruturas diferentes do Laravel convencional, ajuste os
padrões aos arquivos que realmente influenciam o build e o runtime.
As verificações de artefatos também são configuráveis:
COMPOSER_AUTOLOAD_FILE="vendor/autoload.php"
FRONTEND_DEPENDENCY_DIR="node_modules"
FRONTEND_BUILD_ARTIFACTS=(public/build/manifest.json)
STORAGE_LINK_ARTIFACTS=(public/storage)
A ausência do autoload executa Composer install; a ausência do diretório de
dependências instala o frontend; um artefato de build ausente executa o build.
Adapte esses caminhos quando a aplicação usar outro diretório de vendor,
workspaces ou outra saída de compilação. FRONTEND_BUILD_ARTIFACTS=() desativa
a verificação da saída do build; FRONTEND_DEPENDENCY_DIR="" desativa a
verificação do diretório de dependências. As saídas configuradas também são
verificadas depois dos comandos: retornar sucesso sem produzir um artefato
obrigatório interrompe o deploy.
Com STORAGE_LINK=true, o executor recria os links no deploy completo, em
mudanças de configuração/dependências PHP e quando um link configurado estiver
ausente ou inválido. Atualizações comuns de código preservam links saudáveis.
Inclua em STORAGE_LINK_ARTIFACTS os links definidos pela aplicação;
STORAGE_LINK_ARTIFACTS=() desativa a verificação dos links e
STORAGE_LINK=false desativa essa etapa. Os links são atualizados depois dos
caches de configuração, para utilizar os caminhos atuais da aplicação.
Estado, verificação e recuperação
Os deploys que executam etapas verificam a inicialização do Laravel com
artisan about. HEALTHCHECK_URL adiciona uma verificação HTTP, inclusive em
novos commits que alteram somente documentação.
Ao final, o commit é registrado como implantado com sucesso. Execuções seguintes usam esse commit como referência, e não o commit encontrado antes do fetch. Se uma etapa da aplicação do deploy falhar, o marcador em andamento permanece e a próxima execução faz um deploy completo, mesmo que um commit seguinte reverta as mudanças. Isso evita reutilizar dependências ou caches parcialmente atualizados.
Mudanças em deploy.config.sh ou no executor invalidam o estado incremental.
Como a configuração é carregada antes da atualização do Git, uma configuração
trazida pelo fetch passa a ser aplicada na próxima execução, que detecta a
mudança e executa o fluxo completo. Mudanças em .env, outros arquivos não
rastreados ou no ambiente devem ser aplicadas com --force.
O commit implantado precisa existir em origin/DEPLOY_BRANCH. Commits criados
somente no servidor bloqueiam o fluxo para evitar publicar código não revisado.
O deploy altera o diretório atual da aplicação. Falhas não desfazem arquivos ou migrations já aplicados. A recuperação executa o fluxo completo; não há rollback automático nem retomada a partir da etapa que falhou.
Testes
composer test
A suíte rápida usa repositórios Git reais e simula os comandos externos para validar a seleção de etapas, os locks, os artefatos e a recuperação de falhas.
composer test:integration
O teste de integração instala o pacote em uma aplicação Laravel 12 real e usa Composer, Bun/Vite, SQLite e um servidor HTTP PHP sem comandos simulados. Verifica migrations, caches, autoload, respostas HTTP, conteúdo do bundle, renderização Blade, artefatos removidos e recuperação após uma migration que falha depois do build, seguida de reversão do commit. Também valida o healthcheck HTTP com curl, inclusive uma resposta 404 que precisa impedir o registro de sucesso.
Essa suíte precisa de Python 3, PHP com SQLite, Composer, Bun, Node, curl e acesso à rede para instalar as dependências. Os projetos são criados em diretórios temporários. O servidor HTTP do teste usa OPcache desativado; a integração não reinicia serviços PHP-FPM/systemd do servidor nem executa Horizon.
Requisitos
- Linux com Bash 4.4 ou superior, flock e realpath (GNU coreutils);
- Git e um remote chamado origin;
- PHP e Composer;
- Node/npm ou outra ferramenta configurada nos arrays de frontend;
- sudo e systemctl quando serviços forem configurados.