Início
NexoPOS

Implantação

Como executar o NexoSaaS: stack Docker, proxy reverso no host, domínio base e TLS.

O que você está implantando

Component Role
app (PHP-FPM) Laravel control plane
nginx (compose) Serves control plane + generated tenant vhosts
horizon Queue workers (provision, backups, mail, etc.)
scheduler schedule:work (billing lifecycle, backup waves, …)
mysql Control plane + per-install tenant databases (Docker)
redis Cache, sessions, queues
Host agent Creates tenant paths, nginx snippets, SSL, DBs

Os sites do cliente NexoPOS não são serviços Compose separados. O agente grava arquivos em HOST_AGENT_HOME_BASE, e o nginx inclui seus vhosts.

1. Instalação do Docker

Pré-requisitos

  • Docker Engine + Docker Compose v2
  • Portas livres (padrão): 8080 (HTTP), 3307 (host do MySQL), 6380 (host do Redis)

Passos

# From the repository root
cp deploy/.env.docker.example .env

# Optional: set a stable public URL early (production example)
# APP_URL=https://app.yourdomain.com
# APP_ENV=production
# APP_DEBUG=false

docker compose -f deploy/docker-compose.yml up -d --build

Os pontos de entrada normalmente geram APP_KEY e executam migrações quando configurados. Semeie o catálogo + admin padrão uma vez:

docker compose -f deploy/docker-compose.yml exec app php artisan db:seed --force

Contas semeadas padrão (apenas para dev):

Role Email Password
Platform admin [email protected] password
Test user [email protected] password

Abra o plano de controle: http://localhost:8080 (ou seu APP_URL).

Prontidão:

docker compose -f deploy/docker-compose.yml exec app php artisan platform:launch-check

Variáveis de ambiente importantes

Segredos do produto (Stripe, SMTP, GitHub PAT, S3, política de domínio) são de Admin → Configurações, não de variáveis de ambiente em tempo de execução.

Variable Typical Docker Notes
APP_URL http://localhost:8080 Must match the URL browsers use (payment return URLs)
APP_ENV / APP_DEBUG local / true Production: production / false
PLATFORM_BASE_DOMAIN localhost Seed-only default for Admin Domain base_domain
HOST_AGENT_DRIVER local Docker/CI. Production VPS isolation: script
HOST_AGENT_HOME_BASE /home Tenant homes + .platform/nginx-enabled
HOST_AGENT_LOCAL_REAL_CLONE false true = real NexoPOS tarball (needs network + GitHub)
HOST_AGENT_TENANT_DB_* MySQL service Per-install DB creation in Docker
QUEUE_CONNECTION redis Required for Horizon

Modos do agente host

Driver Use when
local Docker / evaluation. Same path layout as production, shared FPM, no real useradd.
script Real Linux VPS: OS users, per-user FPM, system nginx, true isolation.

A composição não é, por si só, uma história completa de isolamento de produção multi-tenant. Use scripts em um VPS quando precisar de separação de tenants com nível de produção.

2. Hospede o Nginx na frente da stack

Forma de produção recomendada:

Internet
   │
   ▼
Host Nginx / Caddy  (TLS termination, :443)
   │  proxy_pass → 127.0.0.1:8080
   ▼
Compose nginx       (control plane + tenant includes)
   │
   ▼
Compose app (PHP-FPM) + tenant docroots on volume

Exemplo de host Nginx (plano de controle)

Substitua os nomes de host e a porta upstream pelos seus.

# /etc/nginx/sites-available/nexosaas-control.conf
server {
    listen 80;
    server_name app.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name app.yourdomain.com;

    # ssl_certificate     /etc/letsencrypt/live/app.yourdomain.com/fullchain.pem;
    # ssl_certificate_key /etc/letsencrypt/live/app.yourdomain.com/privkey.pem;

    client_max_body_size 64M;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Host $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;
        proxy_read_timeout 120s;
    }
}

Conjunto:

APP_URL=https://app.yourdomain.com

O Laravel confia nos cabeçalhos encaminhados quando configurado para a configuração do seu proxy; garanta que a aplicação veja o HTTPS corretamente para que URLs assinadas e cookies permaneçam seguros.

Espaço reservado do screenshot: navegador aberto na página de login do painel de controle no seu URL HTTPS público

Nomes de host do inquilino

  • Docker / agente local: as configurações do nginx do tenant são gravadas em {HOST_AGENT_HOME_BASE}/.platform/nginx-enabled/*.conf e incluídas pelo nginx do Compose (deploy/docker/nginx/default.conf).
  • Navegador local:  http://{install-subdomain}.localhost:8080 geralmente funciona sem /etc/hosts.
  • Produção: O DNS para *.base_domain (e domínios personalizados) deve chegar à mesma borda que consegue rotear para o nginx da plataforma (ou o nginx do VPS gerenciado pelo agente script).

Se o proxy reverso do host encaminhar apenas app.yourdomain.com, os subdomínios do tenant precisam de uma destas opções:

  • o mesmo proxy com um server_name com curingas / separe blocos de servidor, ou
  • exposição direta da plataforma nginx / vhosts gerenciados pelo agente.

Planeje DNS e TLS para os tenants junto com o domínio base (próxima seção).

3. Domínio base

As instalações recebem um nome de host de plataforma gratuito:

{slug}.{base_domain}

Exemplo: domínio base saas.example.com → acme-store.saas.example.com.

Configurar em Administração

  1. Entrar como administrador da plataforma (2FA fora do local).
  2. Abra Admin → Configurações → Domínio.
  3. Conjunto:
domains-1

DNS

Record Name Target
A app.yourdomain.com (control plane) VPS public IP
A (or CNAME) *.saas.example.com Same IP (or load balancer)
Optional AAAA same hosts Public IPv6

O PLATFORM_BASE_DOMAIN em .env só define o valor de Admin em configurações vazias; em tempo de execução, usa Admin → Domain.

4. SSL / Let’s Encrypt

Plano de controle (proxy reverso do host)

Usando Certbot (exemplo):

# After DNS for app.yourdomain.com points at the VPS
sudo certbot --nginx -d app.yourdomain.com
# or: certbot certonly --webroot ... then point ssl_certificate paths

Usar Caddy é frequentemente mais simples (HTTPS automático); faça reverse_proxy para 127.0.0.1:8080.

Certificados do inquilino

Na provisão e na verificação de domínio personalizado, o agente host é responsável pelo TLS para os nomes de host do tenant (fluxo no estilo Let’s Encrypt no caminho do VPS/agente).

Os operadores devem:

  1. Garanta que o VPS consiga concluir o HTTP-01 (ou o desafio escolhido pelo agente) para os nomes de host de instalação.
  2. Defina de forma razoável as alterações de domínio verificadas máximas por dia (padrão 3) para que os clientes não esgotem os limites de taxa do LE.
  3. Mantenha o IPv4 público preciso para que as instruções de DNS que os clientes veem estejam corretas.

Nota: O Docker local com *.localhost não precisa de LE público para testes de UI do dia a dia.

Webhooks de pagamento

As portas de produção devem alcançar endpoints HTTPS, por exemplo:

  • https://app.yourdomain.com/webhooks/stripe
  • https://app.yourdomain.com/webhooks/paddle
  • https://app.yourdomain.com/webhooks/mollie

Configure segredos de assinatura em Admin → Settings → Billing Settings.

billingsettings

5. Checklist pós-implantação

Step Command / action
Stack healthy docker compose -f deploy/docker-compose.yml ps
Seed catalog / admin (once) exec app php artisan db:seed --force
Launch check exec app php artisan platform:launch-check
Horizon running Compose horizon service Up
Scheduler running Compose scheduler service Up
First admin usable Verify email + 2FA
Product config SMTP, payments, GitHub, S3, domain
Fake payments Not allowed in production launch-check

Comandos úteis de operações

# Shell into app
docker compose -f deploy/docker-compose.yml exec app bash

# Logs
docker compose -f deploy/docker-compose.yml logs -f app horizon nginx

# Rebuild frontend assets
docker compose -f deploy/docker-compose.yml run --rm -e DOCKER_FORCE_BUILD_ASSETS=true assets

# Wipe evaluation installs (keeps users/catalog/settings)
docker compose -f deploy/docker-compose.yml exec app \
  php artisan platform:reset-evaluation --force