@@ -0,0 +1 @@
|
||||
.env.local
|
||||
@@ -0,0 +1,15 @@
|
||||
# Ambiente de desenvolvimento em Compose
|
||||
|
||||
Reutiliza Laravel Sail 8.5 de `composer.lock`, Node 24, PostgreSQL/PostGIS da configuração CI e Nginx. Cache e filas usam PostgreSQL, conforme a aplicação existente. Não é um perfil de produção: o servidor HTTP é o servidor de desenvolvimento do Sail, ligado apenas a localhost através do proxy.
|
||||
|
||||
Pré-requisitos: Docker Engine com Compose, contentores Linux e `composer install` concluído. Na raiz:
|
||||
|
||||
```powershell
|
||||
./deploy/docker/start.ps1
|
||||
```
|
||||
|
||||
O script gera chaves próprias em `.env.local`, ignorado pelo Git; nunca imprime segredos nem altera a `.env` da aplicação existente. Base de dados e storage têm volumes próprios. Conserva estes volumes e a chave para restauro. Não executar `down -v` para uma actualização. O código e os assets de desenvolvimento são partilhados com o workspace.
|
||||
|
||||
Verificação em 29/09/2026: **não executado em Docker**. `docker version` falhou: `The term 'docker' is not recognized as the name of a cmdlet, function, script file, or operable program.` É necessário disponibilizar Docker Engine/Compose e executar o script e os health checks. A presença destes ficheiros não comprova o gate de reprodutibilidade.
|
||||
|
||||
O disco S3 já tem configuração em `config/filesystems.php`, mas falta instalar e testar o adaptador Flysystem S3 e disponibilizar um endpoint autorizado. O perfil usa storage local isolado até essa validação. TLS, métricas, scheduler, limites de recursos e escalabilidade de produção continuam no backlog; modelos Linux existentes permanecem válidos em `deploy/linux`.
|
||||
@@ -0,0 +1,83 @@
|
||||
name: investmoz-development
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: ../../vendor/laravel/sail/runtimes/8.5
|
||||
args:
|
||||
WWWGROUP: '${WWWGROUP:-1000}'
|
||||
NODE_VERSION: '24'
|
||||
POSTGRES_VERSION: '17'
|
||||
image: investmoz-development-php85
|
||||
environment: &application
|
||||
WWWUSER: '${WWWUSER:-1000}'
|
||||
APP_ENV: local
|
||||
APP_DEBUG: 'false'
|
||||
APP_KEY: '${APP_KEY:?Generate the isolated development key first}'
|
||||
APP_URL: 'http://localhost:${PORTAL_PORT:-8088}'
|
||||
DB_CONNECTION: pgsql
|
||||
DB_HOST: postgres
|
||||
DB_PORT: '5432'
|
||||
DB_DATABASE: investmoz_development
|
||||
DB_USERNAME: investmoz
|
||||
DB_PASSWORD: '${DB_PASSWORD:?Generate a local database password first}'
|
||||
DB_URL: ''
|
||||
CACHE_STORE: database
|
||||
QUEUE_CONNECTION: database
|
||||
SESSION_DRIVER: database
|
||||
SESSION_SECURE_COOKIE: 'false'
|
||||
MAIL_MAILER: array
|
||||
PORTAL_NOTIFICATIONS_ENABLED: 'false'
|
||||
LOG_CHANNEL: stderr
|
||||
FILESYSTEM_DISK: local
|
||||
volumes:
|
||||
- ../..:/var/www/html
|
||||
- ./runtime.env.example:/var/www/html/.env:ro
|
||||
- application-storage:/var/www/html/storage
|
||||
- application-cache:/var/www/html/bootstrap/cache
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ['CMD', 'curl', '--fail', 'http://127.0.0.1/up']
|
||||
interval: 15s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
web:
|
||||
image: nginx:stable-alpine
|
||||
ports:
|
||||
- '127.0.0.1:${PORTAL_PORT:-8088}:80'
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
depends_on:
|
||||
app:
|
||||
condition: service_healthy
|
||||
queue:
|
||||
image: investmoz-development-php85
|
||||
environment:
|
||||
<<: *application
|
||||
SUPERVISOR_PHP_COMMAND: '/usr/bin/php /var/www/html/artisan queue:work --sleep=3 --tries=3 --timeout=90'
|
||||
volumes:
|
||||
- ../..:/var/www/html
|
||||
- ./runtime.env.example:/var/www/html/.env:ro
|
||||
- application-storage:/var/www/html/storage
|
||||
- application-cache:/var/www/html/bootstrap/cache
|
||||
depends_on:
|
||||
app:
|
||||
condition: service_healthy
|
||||
postgres:
|
||||
image: postgis/postgis:17-3.5
|
||||
environment:
|
||||
POSTGRES_DB: investmoz_development
|
||||
POSTGRES_USER: investmoz
|
||||
POSTGRES_PASSWORD: '${DB_PASSWORD:?Generate a local database password first}'
|
||||
volumes:
|
||||
- database:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ['CMD-SHELL', 'pg_isready -U investmoz -d investmoz_development']
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 10
|
||||
volumes:
|
||||
database:
|
||||
application-storage:
|
||||
application-cache:
|
||||
@@ -0,0 +1,13 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
client_max_body_size 10m;
|
||||
location ~ /\. { deny all; }
|
||||
location / {
|
||||
proxy_pass http://app:80;
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
# Non-secret fallback only. Deployment-specific values are supplied by Compose.
|
||||
APP_NAME=InvestMoz
|
||||
APP_ENV=local
|
||||
APP_DEBUG=false
|
||||
LOG_CHANNEL=stderr
|
||||
MAIL_MAILER=array
|
||||
PORTAL_NOTIFICATIONS_ENABLED=false
|
||||
INVESTMOZ_AI_ENABLED=false
|
||||
@@ -0,0 +1,32 @@
|
||||
$ErrorActionPreference = 'Stop'
|
||||
Get-Command docker -ErrorAction Stop | Out-Null
|
||||
$workspace = (Resolve-Path (Join-Path $PSScriptRoot '../..')).Path
|
||||
$settings = Join-Path $PSScriptRoot '.env.local'
|
||||
if (-not (Test-Path -LiteralPath $settings)) {
|
||||
$keyBytes = New-Object byte[] 32
|
||||
$passwordBytes = New-Object byte[] 32
|
||||
$generator = [System.Security.Cryptography.RandomNumberGenerator]::Create()
|
||||
$generator.GetBytes($keyBytes)
|
||||
$generator.GetBytes($passwordBytes)
|
||||
$generator.Dispose()
|
||||
$contents = "APP_KEY=base64:$([Convert]::ToBase64String($keyBytes))`nDB_PASSWORD=$([Convert]::ToBase64String($passwordBytes))`nPORTAL_PORT=8088`n"
|
||||
[IO.File]::WriteAllText($settings, $contents, (New-Object Text.UTF8Encoding($false)))
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath (Join-Path $workspace 'vendor/laravel/sail/runtimes/8.5/Dockerfile'))) {
|
||||
throw 'Run composer install using composer.lock before starting the existing Sail runtime.'
|
||||
}
|
||||
$compose = @('compose', '--env-file', $settings, '-f', (Join-Path $PSScriptRoot 'compose.yaml'))
|
||||
function Invoke-Compose([string[]] $ComposeArguments) {
|
||||
& docker @compose @ComposeArguments
|
||||
if ($LASTEXITCODE -ne 0) { throw "Docker Compose failed with exit code $LASTEXITCODE" }
|
||||
}
|
||||
Invoke-Compose -ComposeArguments @('config', '--quiet')
|
||||
Invoke-Compose -ComposeArguments @('build', 'app')
|
||||
Invoke-Compose -ComposeArguments @('up', '-d', 'postgres')
|
||||
Invoke-Compose -ComposeArguments @('run', '--rm', 'app', 'sh', '-lc', 'mkdir -p storage/framework/cache/data storage/framework/sessions storage/framework/views storage/logs bootstrap/cache && chown -R sail:sail storage bootstrap/cache')
|
||||
Invoke-Compose -ComposeArguments @('run', '--rm', 'app', 'php', 'artisan', 'config:clear')
|
||||
Invoke-Compose -ComposeArguments @('run', '--rm', 'app', 'php', 'artisan', 'migrate', '--force')
|
||||
Invoke-Compose -ComposeArguments @('run', '--rm', 'app', 'npm', 'ci')
|
||||
Invoke-Compose -ComposeArguments @('run', '--rm', 'app', 'npm', 'run', 'build')
|
||||
Invoke-Compose -ComposeArguments @('up', '-d', 'app', 'web', 'queue')
|
||||
Write-Output 'Local development: http://localhost:8088. Inspect docker compose ps and /up before use.'
|
||||
Reference in New Issue
Block a user