Files
docker-laravel/README.md

6.2 KiB

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-vue
    • laravel-blade-vite
    • laravel-blade
    • laravel-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:

  1. Stacks
  2. Add Stack
  3. Repository
  4. Cole a URL deste repositório
  5. 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