Ir para o conteúdo
Q
QuoteNode

Installation

Instalar com Portainer, QNAP ou NAS

Coloca o QuoteNode num NAS ou num host Docker gerido por Portainer com instruções de configuração completas.

Instalar com Portainer, QNAP ou NAS

Usa este caminho se executares o Docker através do Portainer, QNAP Container Station, Synology ou uma plataforma semelhante. A interface exata difere por fornecedor, mas o stack Docker Compose subjacente é idêntico.

Quando usar

  • Já operas stacks Docker através de uma interface de gestão de containers.
  • Percebes como a plataforma mapeia volumes e portos.
  • Consegues verificar backups fora da interface do NAS.

O que pode não funcionar

  • Links públicos não funcionam fora da LAN a menos que NAT, DNS, proxy e HTTPS estejam configurados.
  • Modos de suspensão do NAS podem interromper o serviço.
  • Algumas UIs Docker de NAS reescrevem ficheiros compose ou variáveis de ambiente; verifica a stack renderizada antes de confiar nela.
  • Backups armazenados apenas no mesmo NAS não protegem contra falha do NAS.

Pré-requisitos

  • Suporte a Docker Compose v2 na tua plataforma.
  • Suporte a volumes persistentes para dados PostgreSQL, uploads, PDFs e backups.
  • Pelo menos 2 GB de RAM disponíveis e 10 GB de espaço livre em disco.
  • Um URL estável: IP de LAN para uso interno, ou domínio público atrás de um proxy reverso para links de clientes.

Passo 1 — Criar o ficheiro de configuração

Cria um ficheiro .env (ou define variáveis através da interface de ambiente da tua plataforma). Substitui o URL pelo teu endereço NAS real ou domínio público:

Para um deployment só NAS interno:

# Database
DB_URL=jdbc:postgresql://postgres:5432/quotenode
DB_USERNAME=quotenode
DB_PASSWORD=change-me-to-something-random-32-chars
DB_NAME=quotenode

# ============================================================
# SECURITY SECRETS — UNIQUE to this installation.
# SAVE THIS FILE and keep a secure backup.
# ============================================================
DB_ENCRYPTION_KEY=0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
TIMING_TOKEN_SECRET=change-me-timing-secret-min-32-chars
PUBLIC_LINK_PASSWORD_SESSION_SECRET=change-me-session-secret-min-32

# Internal NAS URL
CORS_ALLOWED_ORIGINS=http://nas.local
DOMAIN=nas.local

# O IP do cliente é detetado automaticamente atrás de proxies internos e CDNs (incluindo Cloudflare) — deixe vazio.
# Defina apenas para um proxy invulgar cujo par de transporte seja um endereço PÚBLICO a confiar (IP/CIDR ou nome de host).
SECURITY_TRUSTED_PROXIES=

# Application
LOG_LEVEL=INFO
SPRING_PROFILES_ACTIVE=prod

Para um domínio público atrás de um proxy reverso:

CORS_ALLOWED_ORIGINS=https://crm.example.com
DOMAIN=crm.example.com

Guarda o teu .env imediatamente. Se perderes o DB_ENCRYPTION_KEY, os campos cifrados tornam-se permanentemente ilegíveis.

Passo 2 — Criar o stack Docker Compose

Usa o editor de stacks no Portainer ou na tua interface Docker do NAS, ou cria um ficheiro docker-compose.yml:

services:
  postgres:
    image: postgres:18-alpine
    cpus: 4.0
    mem_limit: 512m
    environment:
      POSTGRES_DB: ${DB_NAME}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      PGDATA: /var/lib/postgresql/data   # required for the postgres:18 image
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME}"]
      interval: 10s
      timeout: 5s
      retries: 10
    restart: unless-stopped

  gotenberg:
    image: gotenberg/gotenberg:8
    cpus: 2.0
    mem_limit: 448m
    environment:
      LOG_LEVEL: info
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:3000/health"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  backend:
    image: ghcr.io/lesisty7/quotenode/quotenode-api:latest
    cpus: 4.0
    mem_limit: 1792m
    depends_on:
      postgres: { condition: service_healthy }
      gotenberg: { condition: service_healthy }
    env_file: .env
    environment:
      SPRING_PROFILES_ACTIVE: prod
      JOBS_MODE: web
      PDF_ENABLED: "true"
      PDF_GOTENBERG_URL: http://gotenberg:3000
    volumes:
      - backend_uploads:/app/data/uploads
      - backend_pdfs:/app/data/pdfs
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:8080/health"]
      interval: 15s
      timeout: 10s
      retries: 5
      start_period: 45s
    restart: unless-stopped

  frontend:
    image: ghcr.io/lesisty7/quotenode/quotenode-frontend:latest
    cpus: 2.0
    mem_limit: 192m
    depends_on:
      backend: { condition: service_healthy }
    ports:
      - "80:80"
      - "443:443"
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://localhost:80/"]
      interval: 15s
      timeout: 5s
      retries: 3
    restart: unless-stopped

volumes:
  postgres_data:
  backend_uploads:
  backend_pdfs:

Conflitos de portos: Se o teu NAS já usa o porto 80 ou 443, muda o lado esquerdo do mapping ports (ex. "8080:80") e atualiza CORS_ALLOWED_ORIGINS em conformidade (ex. http://nas.local:8080).

Passo 3 — Fazer deploy e verificar

Inicia o stack através da interface da tua plataforma ou via SSH:

docker compose up -d
docker compose logs -f backend

Aguarda até ver Started QuoteNodeApplication.

Passo 4 — Abrir o QuoteNode

Navega para o URL do teu NAS (ex. http://nas.local ou https://crm.example.com).

Credenciais de acesso predefinidas:

CampoValor
Email[email protected]
PasswordAdmin123!

Altera a password predefinida imediatamente após iniciar sessão.

Checklist de persistência

Verifica que estes elementos estão mapeados a volumes persistentes (não a armazenamento efémero do container):

DadosPorque importa
PostgreSQL dataBase de dados principal da aplicação
UploadsImagens de produtos, logos, anexos
Generated PDFsFicheiros de propostas e documentos
BackupsArquivos locais de backup (se o worker de backup estiver ativo)
GeoIP databaseDados opcionais de controlo de acesso

O que está a correr?

ContainerO que fazUso de RAM
postgresArmazena todos os teus dados~256 MB
backendServidor API Java, lógica de negócio~512 MB – 1,5 GB
gotenbergConverte HTML para PDF (baseado em Chromium)~200 MB
frontendServe a interface web + reverse proxy~20 MB

Total: aproximadamente 1,5 – 2,5 GB de RAM.

Manter os teus segredos seguros

SegredoO que protegeSe perdido
DB_PASSWORDAcesso à base de dadosRecuperável — reiniciar via ferramentas de administração PostgreSQL
DB_ENCRYPTION_KEYCódigos MFA, password SMTP, chave API FX, campos PIIPermanentemente ilegível
TIMING_TOKEN_SECRETTokens anti-timing-attackRegenerar — utilizadores re-autenticam-se
PUBLIC_LINK_PASSWORD_SESSION_SECRETSessões de links públicosRegenerar — as sessões ativas expiram

Guarda backups do .env fora do NAS. Uma falha do NAS que destrua a tua única cópia do DB_ENCRYPTION_KEY torna os dados cifrados irrecuperáveis.

Próximos passos recomendados

  • Configura backups numa localização fora do NAS.
  • Testa a geração de PDF após o primeiro deployment.
  • Se quiseres um caminho de deployment público mais suave, considera o Coolify num VPS.

Last reviewed: Recently