Instalação com Docker
Este é o caminho completo, do diretório vazio ao primeiro acesso. Confira antes os requisitos.
1. Estrutura de diretórios
Seção intitulada “1. Estrutura de diretórios”mkdir -p ~/openscale && cd ~/openscaleVocê vai criar dois arquivos: .env com a configuração e os segredos, e docker-compose.yml com os
serviços.
2. .env
Seção intitulada “2. .env”cat > .env <<'FIM'# ── Núcleo ────────────────────────────────────────────────────────────PORT=80TZ=America/Sao_PauloNODE_ENV=production
# ── PostgreSQL ────────────────────────────────────────────────────────POSTGRES_HOST=postgresPOSTGRES_PORT=5432POSTGRES_DATABASE=openscalePOSTGRES_USER=openscalePOSTGRES_PASSWORD=TROQUE-esta-senha
# ── HTTP e sessão ─────────────────────────────────────────────────────# Precisa ser maior que o tempo máximo da consulta longa (600 s).HTTP_REQUEST_TIMEOUT_MS=660000# true quando o acesso for por HTTPS. Em HTTP puro, o navegador descarta o cookie e o login não conclui.SESSION_COOKIE_SECURE=false
# ── Armazenamento de objetos ──────────────────────────────────────────MINIO_ENDPOINT=http://minio:9000MINIO_ACCESS_KEY=TROQUE-a-chaveMINIO_SECRET_KEY=TROQUE-o-segredoMINIO_REGION=us-east-1
# ── Agentes de endpoint ───────────────────────────────────────────────# Endereço pelo qual as máquinas alcançam o servidor. Vazio = derivado do cabeçalho Host,# o que falha atrás de proxy que não repassa o host original.AGENT_PUBLIC_API_BASE_URL=http://openscale.suaempresa.localAGENT_HEARTBEAT_INTERVAL_SECONDS=60AGENT_JOBS_POLL_SECONDS=30
# ── Cifra dos segredos do cofre ───────────────────────────────────────# openssl rand -hex 32# Defina ANTES de cadastrar o primeiro segredo. Trocar depois torna ilegível o que já foi cifrado.MANAGER_SECRET_ENC_KEY=
# ── Poda de dados (0 desliga — não deixe em zero com frota) ────────────MANAGER_TELEMETRY_RETENTION_DAYS=30MANAGER_HEARTBEATS_RETENTION_DAYS=7FIMchmod 600 .envchmod 600 não é zelo excessivo: o arquivo tem a senha do banco e as chaves do armazenamento.
3. docker-compose.yml
Seção intitulada “3. docker-compose.yml”services: openscale: image: ghcr.io/imais-dti/openscale:1.0.2-hotfix3 container_name: openscale restart: unless-stopped env_file: .env # A aplicação NÃO tem volume: todo o estado está no Postgres e no armazenamento de objetos. # Recriar este contêiner nunca perde dado — é assim que a atualização acontece. depends_on: postgres: condition: service_healthy minio: condition: service_healthy ports: - "8080:80" networks: [openscale]
postgres: image: postgres:16-alpine container_name: openscale-postgres restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DATABASE} POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - postgres-dados:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 10s timeout: 5s retries: 10 networks: [openscale]
minio: image: minio/minio:latest container_name: openscale-minio restart: unless-stopped command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: ${MINIO_ACCESS_KEY} MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY} volumes: - minio-dados:/data healthcheck: test: ["CMD", "mc", "ready", "local"] interval: 15s timeout: 5s retries: 10 networks: [openscale]
volumes: postgres-dados: minio-dados:
networks: openscale:Note a diferença de nome no serviço do banco: a imagem oficial do PostgreSQL usa POSTGRES_DB para criar o
banco, e o OpenScale lê POSTGRES_DATABASE para se conectar a ele. O .env define
POSTGRES_DATABASE, e o compose acima o repassa ao Postgres com o nome que a imagem espera.
4. Subir
Seção intitulada “4. Subir”docker compose up -ddocker compose logs -f openscaleA aplicação migra o esquema do banco na primeira subida. Aguarde a mensagem de servidor pronto — o
healthcheck da imagem consulta /healthz, que responde 503 enquanto o Postgres não estiver acessível.
# Estado real dos contêineresdocker compose ps
# A aplicação está saudável?curl -fsS http://localhost:8080/healthz && echo " ok"5. Criar os buckets
Seção intitulada “5. Criar os buckets”O File Server, os anexos e as evidências de auditoria precisam de bucket. Crie pelo console do MinIO em
http://localhost:9001, ou pela linha de comando:
docker compose exec minio sh -c ' mc alias set local http://localhost:9000 "$MINIO_ROOT_USER" "$MINIO_ROOT_PASSWORD" && mc mb -p local/openscale-evidencias && mc mb -p local/openscale-arquivos && mc mb -p local/openscale-backups'Depois aponte o bucket de evidências de agente no .env:
AGENT_TENANT_BUCKET_MAP=default:openscale-evidenciasAGENT_DEFAULT_TENANT=defaultE recrie a aplicação para ler a mudança: docker compose up -d openscale.
6. Proxy reverso
Seção intitulada “6. Proxy reverso”Publicar a porta 8080 direto funciona para avaliar, mas não para uso real: sem TLS o cookie de sessão trafega em claro, e sem o tempo de leitura ampliado a interface se comporta de forma errática.
O exemplo abaixo usa Traefik por rótulos. Adapte ao seu proxy — o que não é opcional é o tempo de leitura de no mínimo 600 segundos.
openscale: # … # Sem `ports:` — quem publica é o proxy. networks: [openscale, traefik-network] labels: - "traefik.enable=true" - "traefik.http.routers.openscale.rule=Host(`openscale.suaempresa.com.br`)" - "traefik.http.routers.openscale.entrypoints=websecure" - "traefik.http.routers.openscale.tls.certresolver=le" - "traefik.http.services.openscale.loadbalancer.server.port=80"
networks: openscale: traefik-network: external: trueCom HTTPS no lugar, volte ao .env e ajuste:
SESSION_COOKIE_SECURE=trueAGENT_PUBLIC_API_BASE_URL=https://openscale.suaempresa.com.br7. Atualizar
Seção intitulada “7. Atualizar”docker compose pull openscaledocker compose up -d openscaleAs migrações de esquema rodam na subida. Como a aplicação não tem estado, a atualização é substituição de contêiner — e a reversão é subir a etiqueta anterior. Faça backup do banco antes de subir versão maior: migração aplicada não volta atrás sozinha.
