A dependência de armazenamento em nuvem de terceiros traz custos lineares e perda de soberania. Neste deploy, implementamos um Nextcloud corporativo isolado dentro da nossa malha, sem exposição pública e totalmente integrado via SSO, acabando de vez com a necessidade de mensalidades por usuário.
Arquitetura e Compose
A estrutura utiliza três containers orquestrados: a aplicação PHP oficial, um banco MariaDB configurado para isolamento de transações, e o Redis para cache e gerenciamento de travas de arquivos simultâneos. A blindagem fica por conta do bind exclusivo de IP.
version: '3.8'
services:
raem-nextcloud-db:
image: mariadb:11
container_name: raem-nextcloud-db
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
restart: always
volumes:
- ./db-data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=sua_senha_root
- MYSQL_PASSWORD=sua_senha_db
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
networks:
- raem-network
raem-nextcloud-redis:
image: redis:alpine
container_name: raem-nextcloud-redis
restart: always
networks:
- raem-network
raem-nextcloud:
image: nextcloud:latest
container_name: raem-nextcloud
restart: always
ports:
# Acessível apenas através da malha WireGuard/Headscale
- 100.64.0.1:8082:80
volumes:
- ./data:/var/www/html
environment:
- MYSQL_HOST=raem-nextcloud-db
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=sua_senha_db
- REDIS_HOST=raem-nextcloud-redis
# Autorização prévia de domínio evita telas de bloqueio
- NEXTCLOUD_TRUSTED_DOMAINS="nextcloud.raem.io 100.64.0.1"
- TZ=Europe/Dublin
networks:
- raem-network
depends_on:
- raem-nextcloud-db
- raem-nextcloud-redis
networks:
raem-network:
external: true
Execução Limpa em Fases
Para evitar recusas de conexão da aplicação principal, iniciamos o banco de dados e o cache primeiro.
podman-compose up -d db redis
podman-compose up -d nextcloud
Integração SSO e a Trava SSRF
O pulo do gato ocorre na integração OAuth2/OpenID com o Authentik via app user_oidc. Ao tentar salvar o Discovery Endpoint, o Nextcloud lança o erro: “Could not register provider: The discovery endpoint is not reachable.”
Análise de Causa (SSRF): O Nextcloud possui proteção nativa contra Server-Side Request Forgery, bloqueando requisições HTTP para IPs classificados como locais (incluindo a faixa 100.64.0.0/10 usada pelo Headscale). Como nossa arquitetura é intencionalmente fechada e validada, precisamos orientar a aplicação de que se comunicar com a nossa própria infraestrutura é o comportamento correto, não um ataque.
A solução é desativar a trava exclusivamente para servidores remotos validados via OCC:
podman exec -u www-data raem-nextcloud php occ config:system:set allow_local_remote_servers --value=true --type=boolean
Após injetar o comando, o provider é salvo com sucesso e o SSO assume o controle da autenticação de forma limpa.

