Matriz dev / CI / Docker único / Compose: environments-matrix.md.
Este runbook cobre duas formas de deploy no Dokploy:
composer.json/Vite.pgsql/redis/reverb juntos.Nota importante: o builder Nixpacks do Dokploy atualmente cai para PHP 8.3 e Node 18 (pelos logs), o que é incompatível com este projeto (requer php ^8.5.1 e Vite exige Node >= 20.19).
A @ → IP da VPSA www → IP da VPSA ws → IP da VPSmain/On PushUse o arquivo de produção:
compose.dokploy.yamlapp na porta 80Se o Dokploy permitir expor múltiplos serviços, exponha também:
reverb na porta 8080 em ws.seu-dominio.comAPP_ENV=productionAPP_DEBUG=falseAPP_URL=https://seu-dominio.comAPP_KEY=base64:... (gerar uma vez com php artisan key:generate --show)Se você não conseguir rodar o artisan no container, gere localmente e cole no Dokploy:
php -r "echo 'base64:'.base64_encode(random_bytes(32)).PHP_EOL;"DB_CONNECTION=pgsqlDB_HOST=pgsqlDB_PORT=5432DB_DATABASE=kolos (ou o que você definir)DB_USERNAME=kolosDB_PASSWORD=...REDIS_HOST=redisREDIS_PORT=6379CACHE_STORE=redisQUEUE_CONNECTION=redisBROADCAST_CONNECTION=reverbREVERB_SERVER_HOST=0.0.0.0REVERB_SERVER_PORT=8080Para o cliente (browser), use o domínio com TLS do proxy (porta 443):
REVERB_HOST=ws.seu-dominio.comREVERB_PORT=443REVERB_SCHEME=httpsE para o Vite:
VITE_REVERB_APP_KEY=${REVERB_APP_KEY}VITE_REVERB_HOST=${REVERB_HOST}VITE_REVERB_PORT=${REVERB_PORT}VITE_REVERB_SCHEME=${REVERB_SCHEME}Este projeto depende de livewire/flux-pro (repositório privado do Composer).
Pode autenticar o Flux Pro de três formas (o Dockerfile usa esta ordem):
composer_auth — valor = JSON numa linha (o mesmo que usarias em COMPOSER_AUTH local).COMPOSER_AUTH_JSON — o mesmo JSON (http-basic → composer.fluxui.dev). Não uses o nome COMPOSER_AUTH como build-arg: o Docker injeta o ARG vazio e o Composer pode falhar antes de aplicar o JSON real.USERNAME + KEY — e-mail e license key; o Dockerfile corre composer config http-basic.composer.fluxui.dev … (cria auth.json na imagem).username / USERNAME: e-mail da conta Flux.
password / KEY: a license key completa (UUID) — tem de ir inteira no build; se estiver truncada, o Composer devolve 401.
Se o Build Type estiver como Dockerfile, configure uma das opções acima (secret primeiro, depois COMPOSER_AUTH_JSON, depois USERNAME+KEY).
Environment ≠ Build: variáveis na secção Environment do Dokploy são para o contentor em runtime. O composer install corre no build da imagem — aí precisa de Build-time Arguments ou build secret. Colocar só USERNAME/KEY em Environment não alimenta o Docker build.
Segurança: build secret não entra no docker history da imagem; ARG pode ficar visível no histórico — prefira secret em produção. Evite expor a license key em logs de CI/deploy.
Se você estiver usando Docker Compose e rodando composer install pós-deploy, aí sim a credencial precisa existir como env var runtime (COMPOSER_AUTH).
bootstrap/cache must be present and writableO .dockerignore não copia bootstrap/cache nem storage. O Dockerfile cria essas pastas antes do composer install para o script package:discover conseguir escrever ficheiros de cache.
Não versione
auth.jsonno git e rotacione tokens expostos.
Rode estes comandos após subir os containers (via “Deploy Commands / Post Deploy” do Dokploy):
composer install --no-dev --optimize-autoloader --no-interactionnpm ci && npm run buildphp artisan migrate --forcephp artisan storage:link || truephp artisan config:cachephp artisan route:cache || truephp artisan view:cacheDockerfile na raiz (este projeto tem).composer_authCOMPOSER_AUTH em CI/localDockerfileDockerfile80APP_ENV=productionAPP_DEBUG=falseAPP_URL=https://seu-dominio.com (sem barra final; deve coincidir com o domínio público)APP_KEY=base64:...Mensagens como Failed to resolve user 'systemd-network' ou systemd-journal durante a instalação de pacotes são ruído habitual em imagens minimalistas e não indicam falha do deploy.
npm audit (vulnerabilidades no build)O passo npm ci pode reportar vulnerabilidades; o build continua. Tratar em desenvolvimento com npm audit / npm audit fix (sempre com testes), não é bloqueio do Docker em si.
https://seu-dominio/ com build OKO projeto define rota / (página inicial Livewire). Se o browser mostra 404 mas o contentor está saudável:
curl -sI http://127.0.0.1/ e curl -sI http://127.0.0.1/up
kolos.com.br) está associado a esta aplicação e que o target do proxy usa a porta 80 do serviço que corre esta imagem.APP_URL igual ao URL público (HTTPS, sem path extra)./ falhar mas /up funcionar: limpar caches de rota no pós-deploy (php artisan route:clear, depois php artisan route:cache se usares cache de rotas).APP_KEY aparece no printenv mas o log diz No application encryption key (/ 500, /up 200)O PHP-FPM (por defeito) usa clear_env = yes: os workers não herdam as variáveis do contentor. O teu docker exec … bash vê o ambiente; o PHP através do Nginx não.
A imagem deste repo inclui docker/prod/php-fpm-pool-zz-kolos.conf → /etc/php/8.5/fpm/pool.d/zz-kolos-env.conf com clear_env = no para o pool www.
php -r "var_export(getenv('APP_KEY'));" (CLI costuma ver o env) vs. um script .php servido pelo FPM — o sintoma desaparece após redeploy com a imagem corrigida.env[APP_KEY] = … no www.conf do FPM.http://…/build/…)O browser carrega https:// mas os tags apontam para http:// quando o Laravel acha que o pedido é HTTP (ligação interna contentor ↔ proxy TLS).
APP_URL tem de ser https://seu-dominio.com (nunca http:// em produção pública).bootstrap/app.php) e, se APP_URL for https://, força esquema HTTPS nas URLs geradas (AppServiceProvider).X-Forwarded-Proto ao PHP (docker/prod/nginx-default.conf). Após mudar Nginx, rebuild da imagem.php artisan config:clear (ou redeploy sem config:cache obsoleto com URL errada).seu-dominio.com no Dokploy e habilite Let’s Encrypt.ws.seu-dominio.com e habilite Let’s Encrypt.80 e 443 (e 22 para SSH)