Tutoriais de VPS
Instalar o Directus, CMS headless, em uma VPS (2026): Docker Compose, PostgreSQL, Redis e HTTPS automático com Caddy
O Directus é uma boa opção para desenvolvedores que querem auto-hospedar um backend de conteúdo, um sistema de gestão interno ou um CMS headless. Este artigo aborda a escolha da configuração da VPS, Docker Compose, PostgreSQL, Redis, HTTPS automático com Caddy, backups e verificações de segurança para ajudar você a implantar o Directus como um ambiente de produção sustentável a longo prazo.
Instalar o Directus, CMS headless, em uma VPS (2026): Docker Compose, PostgreSQL, Redis e HTTPS automático com Caddy
Se você já não quer usar o WordPress para todos os backends de conteúdo e acha que os custos e as limitações do Contentful, do Strapi Cloud e de diversos CMS SaaS não são totalmente controláveis, o Directus auto-hospedado é uma escolha muito adequada para usuários de VPS.
O Directus não se propõe a ser "mais um sistema de blog", mas sim a transformar bancos de dados como PostgreSQL e MySQL em um painel administrativo visual, API REST, API GraphQL e sistema de permissões. Você pode usá-lo para gerenciar artigos, produtos, diretórios de ferramentas, dados internos e formulários operacionais, ou tratá-lo como um Backend-as-a-Service leve.
Este artigo foca em uma solução sustentável em produção: Directus + PostgreSQL + Redis + Caddy + Docker Compose. Ela é mais adequada para uso a longo prazo do que "rodar apenas um contêiner SQLite" e dá menos trabalho do que escrever à mão Nginx + Certbot, porque o Caddy consegue solicitar e renovar certificados HTTPS automaticamente.
É adequado para os seguintes tipos de usuários:
- Quem quer auto-hospedar um CMS headless em uma VPS em vez de pagar uma assinatura SaaS a longo prazo.
- Quem quer oferecer uma API de conteúdo para Next.js, Nuxt, Astro, Hugo ou miniprogramas.
- Quem quer montar um painel administrativo interno, diretório de ferramentas, biblioteca de recursos ou base de dados de clientes.
- Quem já sabe o básico de SSH e Docker, mas não quer manter um Kubernetes complexo.
- Quem quer os dados na própria VPS e no próprio banco de dados, para não ficar preso a uma plataforma na hora de migrar.
Se você só quer montar um blog, o guia para montar um blog pessoal em uma VPS do nosso site é mais direto. Se você está trabalhando com fluxos de trabalho automatizados, veja Montar fluxos de automação com n8n em uma VPS. O Directus é mais adequado para cenários com "estruturas de conteúdo complexas, necessidade de permissões e necessidade de API".
O Directus em si não é pesado; o que realmente consome recursos é o banco de dados, o upload de imagens, o volume de requisições à API e as extensões que você escreve.
| Cenário | Configuração recomendada | Descrição |
|---|---|---|
| Backend de conteúdo pessoal, projetos de teste | 1 núcleo, 2 GB de RAM | Dá para rodar, mas não carregue muitas extensões |
| CMS para equipes pequenas, diretório de ferramentas | 2 núcleos, 4 GB de RAM | Mais estável, nível inicial recomendado |
| API de conteúdo para vários sites, sistemas internos | 4 núcleos, 8 GB de RAM | Mais folga para banco de dados, cache e backups |
| Grande volume de uploads de imagens/arquivos | Adicionar armazenamento de objetos separado | Não acumule arquivos grandes no disco do sistema |
Recomenda-se começar com pelo menos 40 GB de disco. Os dados principais do Directus ficam no banco de dados, os arquivos enviados ficam no diretório uploads e as extensões no diretório extensions. Ao fazer backups mais tarde, essas três partes precisam ser cobertas.
Você precisa de:
- Uma VPS com Ubuntu 22.04 / 24.04.
- Um domínio, por exemplo
cms.example.com. - Um registro DNS A apontando para o IP público da VPS.
- As portas 22, 80 e 443 abertas.
- Docker e o plugin Docker Compose.
Para instalar o Docker, você pode consultar os artigos sobre Docker do nosso site; aqui vai uma verificação mínima:
docker --version
docker compose version
Se o comando não existir, instale primeiro o Docker Engine e o plugin Compose e depois continue.
sudo mkdir -p /opt/directus/{uploads,extensions,database,caddy}
sudo chown -R $USER:$USER /opt/directus
cd /opt/directus
Recomenda-se não colocar o Directus em /root. Assim, backups, migrações e gerenciamento com systemd ficarão mais claros.
O Directus precisa de um SECRET, e o banco de dados também precisa de uma senha forte. Não use valores padrão como directus/directus em produção.
openssl rand -hex 32
openssl rand -base64 32
Salve os resultados gerados em um gerenciador de senhas. Você vai precisar deles ao escrever o .env mais adiante.
Crie o .env:
nano .env
Exemplo:
DIRECTUS_DOMAIN=cms.example.com
DIRECTUS_PUBLIC_URL=https://cms.example.com
POSTGRES_DB=directus
POSTGRES_USER=directus
POSTGRES_PASSWORD=replace-with-strong-db-password
DIRECTUS_SECRET=replace-with-random-secret
[email protected]
DIRECTUS_ADMIN_PASSWORD=replace-with-strong-admin-password
Observações:
- O
DIRECTUS_DOMAINnão deve incluirhttps://. - O
DIRECTUS_PUBLIC_URLdeve corresponder ao endereço de acesso final. - A senha do administrador pode ser alterada no painel após a primeira inicialização, mas o valor inicial não deve ser fraco demais.
Crie o docker-compose.yml:
nano docker-compose.yml
Preencha:
services:
database:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- ./database:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
cache:
image: redis:7-alpine
restart: unless-stopped
command: redis-server --appendonly yes
volumes:
- ./redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
directus:
image: directus/directus:11.17.0
restart: unless-stopped
depends_on:
database:
condition: service_healthy
cache:
condition: service_healthy
environment:
SECRET: ${DIRECTUS_SECRET}
PUBLIC_URL: ${DIRECTUS_PUBLIC_URL}
DB_CLIENT: pg
DB_HOST: database
DB_PORT: 5432
DB_DATABASE: ${POSTGRES_DB}
DB_USER: ${POSTGRES_USER}
DB_PASSWORD: ${POSTGRES_PASSWORD}
CACHE_ENABLED: "true"
CACHE_STORE: redis
CACHE_AUTO_PURGE: "true"
REDIS: redis://cache:6379
ADMIN_EMAIL: ${DIRECTUS_ADMIN_EMAIL}
ADMIN_PASSWORD: ${DIRECTUS_ADMIN_PASSWORD}
WEBSOCKETS_ENABLED: "true"
IP_TRUST_PROXY: "true"
volumes:
- ./uploads:/directus/uploads
- ./extensions:/directus/extensions
expose:
- "8055"
caddy:
image: caddy:2-alpine
restart: unless-stopped
depends_on:
- directus
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
volumes:
caddy_data:
caddy_config:
Aqui há alguns pontos-chave:
- O Directus não mapeia
8055:8055diretamente para a internet pública; ele é exposto apenas ao Caddy dentro da rede Docker. - Os dados do PostgreSQL são montados em
./database, e os arquivos enviados são montados em./uploads. - O Caddy cuida das portas públicas 80/443 e do HTTPS.
directus/directus:11.17.0é uma versão de exemplo; em produção real, recomenda-se fixar uma versão que você já testou e não usarlatesta longo prazo.
Crie o Caddyfile:
nano caddy/Caddyfile
Escreva:
{$DIRECTUS_DOMAIN} {
encode zstd gzip
reverse_proxy directus:8055
}
A lógica do Caddy é simples: se o domínio resolver para esta VPS e as portas 80/443 estiverem acessíveis, o Caddy solicitará e renovará os certificados automaticamente. Em comparação com Nginx + Certbot, a configuração é mais curta e é mais difícil esquecer a renovação.
Se o seu DNS ainda não entrou em vigor, não inicie o Caddy ainda, ou a solicitação do certificado pode falhar. Você pode usar:
dig +short cms.example.com
Confirme que ele retorna o IP público da VPS.
cd /opt/directus
docker compose pull
docker compose up -d
Ver o status:
docker compose ps
docker compose logs -f directus
Acesse:
https://cms.example.com
Faça login com o e-mail e a senha do administrador do .env.
A entrada em produção não termina quando você vê a página de login. No mínimo, verifique isto:
-
https://cms.example.com/server/pingretorna normalmente. - O HTTP redireciona automaticamente para HTTPS.
- Após fazer login no painel, você consegue criar uma Collection de teste.
- Você consegue criar, ler e editar um registro de teste.
- Você consegue enviar uma imagem de teste, e ela continua existindo após reiniciar.
- O Directus se recupera após
docker compose restart. -
docker compose logs directusnão mostra erros repetidos de conexão com o banco de dados.
Se a página retornar 502, verifique primeiro:
docker compose ps
docker compose logs caddy
docker compose logs directus
As causas comuns são DNS não apontando para a VPS, 80/443 não abertas, contêiner do Directus não iniciado, PUBLIC_URL escrito errado ou domínio do Caddyfile escrito errado.
Um ambiente de produção do Directus deve fazer backup de pelo menos três tipos de dados:
- O banco de dados PostgreSQL.
- O diretório de arquivos
uploads. - O diretório de extensões
extensionse a configuraçãodocker-compose.yml/.env.
Exemplo de backup do banco de dados:
cd /opt/directus
docker compose exec -T database pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > directus-$(date +%F).sql
Mas esse comando pode não conseguir ler .env ao usar diretamente as variáveis de ambiente do host. Uma forma mais confiável é escrever um script de backup que leia explicitamente .env ou que especifique as variáveis dentro do contêiner. Nosso site já tem simulações de backup e restauração em VPS; recomenda-se incluir o Directus na mesma simulação de restauração, em vez de apenas fazer arquivos compactados que "parecem ter backup".
O Directus é um sistema de backend, então não o deixe exposto:
- A senha do administrador deve ser suficientemente forte, e é preciso ativar a hierarquia de permissões de contas dentro da equipe.
- Não exponha o PostgreSQL nem o Redis à internet pública.
- Não abra a porta 8055 do Directus diretamente para toda a internet.
- Se você colocar o Cloudflare na frente do Caddy, confirme o modo SSL e a política de acesso à origem real.
- Atualize periodicamente a imagem do Directus, mas faça backup do banco de dados e dos arquivos enviados antes de atualizar.
- Se for usado apenas pela equipe interna, considere adicionar Cloudflare Access ou Tailscale.
Se você não tem certeza de como lidar com o acesso remoto ao banco de dados, leia primeiro Não exponha bancos de dados da VPS diretamente à internet pública. Se você se preocupa com a exposição do IP de origem, pode consultar Ocultar o IP de origem com Cloudflare Tunnel.
Depende do cenário.
| Cenário | Mais adequado |
|---|---|
| Blogs tradicionais, ecossistema de plugins, mercado de temas | WordPress |
| Sites de conteúdo com frontend e backend separados | Directus |
| Diretórios de ferramentas, bibliotecas de recursos, backends internos | Directus |
| Necessidade de permissões e APIs complexas | Directus |
| Não quer escrever frontend, só quer publicar artigos rápido | WordPress |
| O conteúdo precisa ser sincronizado com vários frontends | Directus |
As vantagens do Directus são a liberdade de estrutura, as APIs diretas e o modelo de permissões claro; a desvantagem é que normalmente você ainda precisa de um site frontend, como Next.js, Nuxt, Astro ou um gerador de sites estáticos. Ele não é uma ferramenta tradicional de criação de sites que "já vem com um mercado de temas completo após a instalação".
1. Dá para usar SQLite?
Para testes, sim; para produção, não é recomendado. Os tutoriais oficiais incluem cenários com SQLite, mas para produção a longo prazo recomenda-se mais PostgreSQL ou MySQL, especialmente com backends multiusuário, gravações frequentes e muitos recursos de extensão.
2. Caddy ou Nginx?
Se você já está familiarizado com o Nginx, pode continuar usando o Nginx. Para projetos novos, o Caddy é mais recomendado, por causa do HTTPS automático, da configuração curta e da renovação sem complicação. Este artigo escolhe o Caddy para reduzir o custo de manutenção.
3. Quanta memória a VPS precisa?
Para uso pessoal, 2 GB podem servir de ponto de partida; para equipes pequenas, recomendam-se 4 GB. Quando Directus, PostgreSQL, Redis e Caddy rodam na mesma máquina, uma máquina de 1 GB fica bem apertada.
4. O que fazer se as imagens enviadas forem aumentando cada vez mais?
A médio e longo prazo, recomenda-se conectar um armazenamento de objetos compatível com S3, ou pelo menos fazer backup separado de uploads. Não espere o disco do sistema encher para migrar.
5. Atualizar o Directus pode danificar os dados?
Qualquer atualização de CMS tem riscos. Não faça diretamente latest para puxar a nova versão; primeiro leia o changelog, valide em um ambiente de teste e depois atualize após fazer backup do banco de dados de produção e dos arquivos enviados.
- O registro A do domínio aponta para a VPS.
- A VPS tem 80/443 abertas, e a 8055 não está aberta à internet pública.
-
SECRET, a senha do banco de dados e a senha do administrador em.envsão suficientemente fortes. - O Docker Compose fixa a versão do Directus.
- PostgreSQL, uploads e extensions têm estratégia de backup.
- O HTTPS automático do Caddy funciona normalmente.
- Login, criação de dados, upload de arquivos e recuperação após reiniciar foram testados com sucesso.
O Directus é uma ótima opção para usuários de VPS que pensam: "quero ter o conteúdo e os dados nas minhas próprias mãos, mas não quero escrever um backend do zero". Combinando Directus, PostgreSQL, Redis e Caddy com Docker Compose, você consegue um ambiente de CMS headless sustentável em uma VPS comum.
O que realmente importa não é "se ele consegue iniciar", mas sim: se o banco de dados é persistente, se os arquivos enviados têm backup, se o HTTPS é renovado automaticamente, se a porta do backend não está exposta e se você consegue reverter antes de atualizar. Fazendo isso bem, o Directus pode deixar de ser um contêiner de teste e se tornar um backend de conteúdo realmente utilizável a longo prazo.