Laravel Multi-Projeto Stack
Stack Docker para hospedar vários projetos Laravel no mesmo container, acessando por rota:
https://laravel.juancjc.com.br/projeto1
https://laravel.juancjc.com.br/projeto2
https://laravel.juancjc.com.br/sistema-alunos
A ideia é parecida com sua stack NestJS, mas para Laravel:
- Nginx na frente.
- PHP-FPM para rodar Laravel.
- Composer dentro do container.
- Node + NPM dentro do container para projetos com Vite/Vue.
- Detecta automaticamente:
laravel-vuelaravel-blade-vitelaravel-bladelaravel-node
- Cria automaticamente a rota
/nome-da-pasta.
Estrutura do repositório
laravel-stack/
├── Dockerfile
├── docker-compose.yml
├── .gitignore
├── nginx/
│ └── nginx.conf
├── php/
│ └── php.ini
├── supervisor/
│ └── supervisord.conf
├── scripts/
│ ├── start.sh
│ ├── deploy.sh
│ ├── remove.sh
│ └── status.sh
├── host-deploy.sh
├── host-remove.sh
└── host-status.sh
Estrutura no servidor
/srv/projects/laravel/
├── projects/
│ ├── projeto1/
│ ├── projeto2/
│ └── sistema-alunos/
├── nginx-dynamic/
├── composer-cache/
└── npm-cache/
Cada pasta dentro de /srv/projects/laravel/projects vira uma rota.
Exemplo:
/srv/projects/laravel/projects/sistema-alunos
vira:
https://laravel.juancjc.com.br/sistema-alunos
Setup inicial no servidor
mkdir -p /srv/projects/laravel/projects
mkdir -p /srv/projects/laravel/nginx-dynamic
mkdir -p /srv/projects/laravel/composer-cache
mkdir -p /srv/projects/laravel/npm-cache
Clone esta stack:
git clone <repo-da-laravel-stack> /srv/projects/laravel/laravel-stack
cd /srv/projects/laravel/laravel-stack
chmod +x host-*.sh
Suba com Docker Compose:
docker compose up -d --build
Ou pelo Portainer:
- Stacks
- Add Stack
- Repository
- Cole a URL deste repositório
- Deploy
Adicionar um projeto Laravel
Entre na pasta de projetos:
cd /srv/projects/laravel/projects
Clone ou coloque o código:
git clone https://github.com/seu-usuario/meu-projeto.git meu-projeto
Crie ou edite o .env:
nano /srv/projects/laravel/projects/meu-projeto/.env
Depois faça o deploy:
/srv/projects/laravel/laravel-stack/host-deploy.sh meu-projeto
Acesse:
https://laravel.juancjc.com.br/meu-projeto
Atualizar um projeto
cd /srv/projects/laravel/projects/meu-projeto
git pull
/srv/projects/laravel/laravel-stack/host-deploy.sh meu-projeto
Ver status
/srv/projects/laravel/laravel-stack/host-status.sh
Remover projeto
Remove rota Nginx e arquivos:
/srv/projects/laravel/laravel-stack/host-remove.sh meu-projeto
Remove só a rota, mantendo os arquivos:
/srv/projects/laravel/laravel-stack/host-remove.sh meu-projeto --keep-files
Como ele identifica Vue ou Blade
O script olha os arquivos do projeto:
Laravel Vue
Se existir package.json com:
"vue"
ou:
"@inertiajs/vue3"
ou:
"@vitejs/plugin-vue"
ele marca como:
laravel-vue
Laravel Blade com Vite
Se existir package.json com Vite, mas sem Vue:
laravel-blade-vite
Laravel Blade simples
Se não tiver package.json:
laravel-blade
O tipo fica salvo em:
.projeto/.project-type
Importante para rodar em /projeto
Como cada sistema roda em subpasta, o deploy ajusta automaticamente no .env do projeto:
APP_URL=https://laravel.juancjc.com.br/meu-projeto
ASSET_URL=/meu-projeto
Isso ajuda CSS, JS, imagens e links gerados pelo Laravel.
Projetos Vue/Inertia com Vite
Se algum projeto Vue tiver problema com assets em /build, ajuste o vite.config.js para respeitar VITE_BASE.
Exemplo:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
base: process.env.VITE_BASE || '/',
plugins: [
laravel({
input: 'resources/js/app.js',
refresh: true,
}),
vue(),
],
});
O deploy já executa:
ASSET_URL="/meu-projeto" VITE_BASE="/meu-projeto/build/" npm run build
Rodar migrations automaticamente
Por padrão, a stack não roda migrations para evitar acidente em produção.
Se quiser que rode no deploy, coloque no .env do projeto:
RUN_MIGRATIONS=true
Aí no deploy ele executa:
php artisan migrate --force
Comandos úteis
Logs do container:
docker logs laravel-stack -f
Entrar no container:
docker exec -it laravel-stack bash
Deploy manual dentro do container:
docker exec laravel-stack /home/deploy/scripts/deploy.sh meu-projeto
Ver Nginx:
docker exec laravel-stack nginx -T
Testar Nginx:
docker exec laravel-stack nginx -t
Variáveis principais no docker-compose
PROJECTS_DIR=/home/deploy/projects
DOMAIN=laravel.juancjc.com.br
PUBLIC_BASE_URL=https://laravel.juancjc.com.br
AUTO_DEPLOY_ON_START=false
PHP_MEMORY_LIMIT=512M
AUTO_DEPLOY_ON_START
Se deixar:
AUTO_DEPLOY_ON_START=false
o container apenas recria as rotas Nginx ao iniciar.
Se trocar para:
AUTO_DEPLOY_ON_START=true
o container roda deploy em todos os projetos sempre que iniciar.
Eu recomendo deixar false e usar:
./host-deploy.sh projeto
quando quiser atualizar.
Banco Postgres
A stack já está ligada na rede externa:
postgres-18_default:
external: true
Então, no .env do Laravel, use o nome do serviço/container do Postgres como host.
Exemplo:
DB_CONNECTION=pgsql
DB_HOST=postgres
DB_PORT=5432
DB_DATABASE=meu_banco
DB_USERNAME=meu_usuario
DB_PASSWORD=minha_senha
Se seu container Postgres tiver outro nome, ajuste o DB_HOST.
Observação
Para produção, prefira colocar o domínio principal no Nginx Proxy Manager apontando para:
laravel-stack:80
ou para a porta publicada:
IP_DO_SERVIDOR:3452