Pular para o conteúdo

Instalação com Docker

Este é o caminho completo, do diretório vazio ao primeiro acesso. Confira antes os requisitos.

Terminal window
mkdir -p ~/openscale && cd ~/openscale

Você vai criar dois arquivos: .env com a configuração e os segredos, e docker-compose.yml com os serviços.

Terminal window
cat > .env <<'FIM'
# ── Núcleo ────────────────────────────────────────────────────────────
PORT=80
TZ=America/Sao_Paulo
NODE_ENV=production
# ── PostgreSQL ────────────────────────────────────────────────────────
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_DATABASE=openscale
POSTGRES_USER=openscale
POSTGRES_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:9000
MINIO_ACCESS_KEY=TROQUE-a-chave
MINIO_SECRET_KEY=TROQUE-o-segredo
MINIO_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.local
AGENT_HEARTBEAT_INTERVAL_SECONDS=60
AGENT_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=30
MANAGER_HEARTBEATS_RETENTION_DAYS=7
FIM
chmod 600 .env

chmod 600 não é zelo excessivo: o arquivo tem a senha do banco e as chaves do armazenamento.

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.

Terminal window
docker compose up -d
docker compose logs -f openscale

A 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.

Terminal window
# Estado real dos contêineres
docker compose ps
# A aplicação está saudável?
curl -fsS http://localhost:8080/healthz && echo " ok"

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:

Terminal window
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-evidencias
AGENT_DEFAULT_TENANT=default

E recrie a aplicação para ler a mudança: docker compose up -d openscale.

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: true

Com HTTPS no lugar, volte ao .env e ajuste:

SESSION_COOKIE_SECURE=true
AGENT_PUBLIC_API_BASE_URL=https://openscale.suaempresa.com.br
Terminal window
docker compose pull openscale
docker compose up -d openscale

As 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.

Primeiro acesso