Adiciona configuração inicial da stack Docker para projetos Laravel, incluindo Dockerfile, docker-compose, scripts de gerenciamento e configuração do Nginx.

This commit is contained in:
juancjc
2026-05-11 12:44:24 -05:00
commit 87261e0b07
14 changed files with 1091 additions and 0 deletions

284
scripts/deploy.sh Normal file
View File

@@ -0,0 +1,284 @@
#!/bin/bash
set -e
PROJECTS_DIR="${PROJECTS_DIR:-/home/deploy/projects}"
DOMAIN="${DOMAIN:-localhost}"
PUBLIC_BASE_URL="${PUBLIC_BASE_URL:-http://${DOMAIN}}"
TARGET=""
NGINX_ONLY=false
for arg in "$@"; do
case "$arg" in
--nginx-only) NGINX_ONLY=true ;;
*) TARGET="$arg" ;;
esac
done
safe_name() {
echo "$1" | sed 's/[^A-Za-z0-9._-]/-/g'
}
env_get() {
local file="$1"
local key="$2"
if [ -f "$file" ]; then
grep -E "^${key}=" "$file" | tail -n1 | cut -d '=' -f2- | sed -e 's/^"//' -e 's/"$//' -e "s/^'//" -e "s/'$//"
fi
}
env_set() {
local file="$1"
local key="$2"
local value="$3"
touch "$file"
if grep -qE "^${key}=" "$file"; then
sed -i "s|^${key}=.*|${key}=${value}|g" "$file"
else
echo "${key}=${value}" >> "$file"
fi
}
detect_type() {
local project_dir="$1"
if [ ! -f "$project_dir/artisan" ]; then
echo "nao-laravel"
return
fi
if [ -f "$project_dir/package.json" ]; then
if grep -qiE '"(@inertiajs/vue3|vue|@vitejs/plugin-vue)"' "$project_dir/package.json"; then
echo "laravel-vue"
elif grep -qiE '"vite"|'"'@laravel/vite-plugin'" "$project_dir/package.json"; then
echo "laravel-blade-vite"
else
echo "laravel-node"
fi
else
echo "laravel-blade"
fi
}
has_npm_build() {
node -e "const p=require('./package.json'); process.exit(p.scripts && p.scripts.build ? 0 : 1)" >/dev/null 2>&1
}
reload_nginx_if_running() {
if pgrep nginx >/dev/null 2>&1; then
nginx -t && nginx -s reload
fi
}
generate_nginx_config() {
local project="$1"
local project_dir="$2"
local safe_project
safe_project="$(safe_name "$project")"
cat > "/etc/nginx/sites-dynamic/${safe_project}.conf" <<EOF
# Gerado automaticamente pela Laravel Stack
# Projeto: ${project}
# Pasta: ${project_dir}
location = /${project} {
return 301 /${project}/;
}
location ^~ /${project}/ {
alias ${project_dir}/public/;
index index.php index.html;
try_files \$uri \$uri/ /${project}/index.php?\$query_string;
}
location ~ ^/${project}/index\.php(/|$) {
internal;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME ${project_dir}/public/index.php;
fastcgi_param DOCUMENT_ROOT ${project_dir}/public;
# Importante para Laravel funcionar em subpasta /${project}
fastcgi_param SCRIPT_NAME /${project}/index.php;
fastcgi_param PHP_SELF /${project}/index.php;
fastcgi_param REQUEST_URI \$request_uri;
fastcgi_param HTTPS \$fastcgi_https;
fastcgi_read_timeout 300;
fastcgi_buffer_size 32k;
fastcgi_buffers 16 16k;
}
location ~ ^/${project}/.*\.php$ {
return 404;
}
EOF
}
deploy_project() {
local project="$1"
local project_dir="$PROJECTS_DIR/$project"
local safe_project
local type
local env_file
local project_url
local run_migrations
safe_project="$(safe_name "$project")"
env_file="$project_dir/.env"
project_url="${PUBLIC_BASE_URL%/}/${project}"
echo ""
echo "================================================"
echo " Deployando: $project"
echo " URL: $project_url"
echo "================================================"
if [ ! -d "$project_dir" ]; then
echo "✗ Pasta $project_dir não encontrada"
return 1
fi
if [ ! -f "$project_dir/artisan" ]; then
echo "$project ignorado: não encontrei artisan. Não parece Laravel."
return 0
fi
if [ ! -f "$project_dir/public/index.php" ]; then
echo "$project sem public/index.php"
return 1
fi
type="$(detect_type "$project_dir")"
echo "$type" > "$project_dir/.project-type"
echo "→ Tipo identificado: $type"
generate_nginx_config "$project" "$project_dir"
echo "✓ Nginx criado: /${project}"
if [ "$NGINX_ONLY" = "true" ]; then
return 0
fi
cd "$project_dir"
if [ ! -f "$env_file" ] && [ -f "$project_dir/.env.example" ]; then
echo "→ .env não encontrado, copiando .env.example"
cp "$project_dir/.env.example" "$env_file"
fi
if [ -f "$env_file" ]; then
env_set "$env_file" "APP_URL" "$project_url"
env_set "$env_file" "ASSET_URL" "/${project}"
else
echo "⚠ Sem .env. Crie $env_file antes de usar banco/cache em produção."
fi
echo "→ composer install..."
composer install \
--no-dev \
--prefer-dist \
--no-interaction \
--optimize-autoloader
if [ -f "$env_file" ]; then
app_key="$(env_get "$env_file" "APP_KEY")"
if [ -z "$app_key" ] || [ "$app_key" = "null" ]; then
echo "→ Gerando APP_KEY..."
php artisan key:generate --force
fi
fi
echo "→ Limpando caches Laravel..."
php artisan optimize:clear || true
if [ -f "package.json" ]; then
echo "→ Dependências front-end encontradas."
if [ -f "package-lock.json" ]; then
echo "→ npm ci..."
npm ci --no-audit --no-fund
else
echo "→ npm install..."
npm install --no-audit --no-fund
fi
if has_npm_build; then
echo "→ npm run build..."
ASSET_URL="/${project}" VITE_BASE="/${project}/build/" npm run build
else
echo "⚠ package.json sem script build. Pulando build."
fi
else
echo "→ Sem package.json. Projeto identificado como Blade/PHP puro."
fi
echo "→ storage:link..."
php artisan storage:link || true
run_migrations="$(env_get "$env_file" "RUN_MIGRATIONS")"
if [ "$run_migrations" = "true" ]; then
echo "→ RUN_MIGRATIONS=true, rodando migrations..."
php artisan migrate --force
fi
echo "→ Otimizando Laravel..."
php artisan config:cache || true
php artisan route:cache || {
echo "⚠ route:cache falhou, limpando cache de rotas."
php artisan route:clear || true
}
php artisan view:cache || true
php artisan event:cache || true
echo "→ Ajustando permissões..."
mkdir -p storage bootstrap/cache
chown -R www-data:www-data storage bootstrap/cache public || true
chmod -R ug+rwX storage bootstrap/cache || true
echo "$project deployado em /$project"
}
deploy_all() {
local found=0
for project_dir in "$PROJECTS_DIR"/*/; do
[ -d "$project_dir" ] || continue
project="$(basename "$project_dir")"
found=$((found + 1))
deploy_project "$project" || true
done
if [ "$found" -eq 0 ]; then
echo "Nenhum projeto encontrado em $PROJECTS_DIR"
fi
}
mkdir -p "$PROJECTS_DIR" /etc/nginx/sites-dynamic
if [ -n "$TARGET" ]; then
deploy_project "$TARGET"
else
deploy_all
fi
echo ""
echo "→ Recarregando Nginx se estiver em execução..."
reload_nginx_if_running || true
echo ""
echo "================================================"
echo " Deploy concluído!"
for project_dir in "$PROJECTS_DIR"/*/; do
[ -d "$project_dir" ] || continue
project="$(basename "$project_dir")"
type="$(cat "$project_dir/.project-type" 2>/dev/null || echo '?')"
echo " ✓ /$project$type"
done
echo "================================================"