Tutoriais de VPS
Hospedar o NocoDB, banco de dados no-code, em uma VPS (2026): guia completo de Docker Compose, PostgreSQL, Redis e Caddy HTTPS
Este tutorial explica com clareza como auto-hospedar o NocoDB em uma VPS e transformar o banco de dados em uma interface de planilha parecida com o Airtable. O conteúdo cobre escolha da configuração da VPS, implantação de quatro contêineres com Docker Compose, PostgreSQL e Redis, HTTPS automático com Caddy, variáveis de ambiente, backup, atualização, reforço de segurança e solução de erros comuns.

Hospedar o NocoDB, banco de dados no-code, em uma VPS (2026): guia completo de Docker Compose, PostgreSQL, Redis e Caddy HTTPS
A primeira vez que olhei o NocoDB com atenção foi porque um amigo tinha a tabela de clientes da empresa, o andamento dos projetos e os registros de compras tudo dentro do Excel. O nome do arquivo foi de 客户表_final.xlsx para 客户表_final_真的最终版.xlsx, e no fim ninguém sabia qual era o mais recente.
O Airtable resolve esse problema, mas quando o time cresce, o preço não é barato. O mais complicado é que muitos times pequenos já têm os dados no MySQL ou no PostgreSQL; só falta uma interface de planilha que operações, vendas e atendimento possam usar diretamente.
A proposta do NocoDB é direta: transformar o banco de dados em uma planilha visual parecida com o Airtable. Você pode filtrar, ordenar, criar visualizações, importar CSV e gerar APIs no navegador, e colegas que não sabem escrever SQL podem manter os dados diretamente.
Este artigo trata de como rodar o NocoDB na sua própria VPS. Não vamos usar um script de instalação caixa-preta, mas escrever à mão uma configuração de Docker Compose que você consiga entender, fazer backup e migrar.
Serve para estes cenários:
- Um time pequeno quer uma alternativa open source ao Airtable.
- Você tem um monte de Excel / CSV e quer migrar para um banco de dados para gerenciar tudo de forma unificada.
- Operações, atendimento e vendas precisam editar dados, mas não deveriam entrar diretamente no banco de dados.
- Você quer colocar uma interface de gestão low-code sobre PostgreSQL / MySQL.
- Você já tem uma VPS e não quer pagar por usuário por mais uma ferramenta de colaboração em planilhas.
Não é tão indicado para estes cenários:
- Você é só uma pessoa anotando algumas tarefas; Notion ou Feishu Sheets é mais prático.
- Você não quer de jeito nenhum manter servidor, banco de dados e backups.
- Você precisa de permissões empresariais, auditoria e fluxos de aprovação extremamente complexos.
- Você pretende ter centenas de pessoas editando online ao mesmo tempo; uma VPS pequena pode não aguentar.
Minha recomendação: projetos pessoais, times pequenos, ferramentas internas, CRM leve, planilhas de estoque e cronograma de conteúdo são todos bons encaixes. Se for realmente um backend empresarial grande, o NocoDB pode servir como interface auxiliar, mas não o trate como um ERP que faz tudo.
O quickstart oficial do NocoDB roda quatro contêineres:
| Contêiner | Função |
|---|---|
nocodb | Interface web e API |
worker | Tarefas em segundo plano como importação, exportação e automação |
db | PostgreSQL, guarda metadados e dados de negócio |
redis | Cache e fila de tarefas |
Dá para começar com 1 núcleo e 1 GB, mas não recomendo ser tão econômico em produção.
| Uso | Configuração recomendada |
|---|---|
| Teste pessoal, poucas planilhas | 1 vCPU / 1 GB RAM / 20 GB SSD |
| Uso diário de time pequeno | 2 vCPU / 2 GB RAM / 40 GB SSD |
| Muitos anexos, colaboração de várias pessoas | 2-4 vCPU / 4 GB RAM / 80 GB+ SSD |
O que realmente importa é o disco e o backup. O NocoDB em si não é pesado; o problema é que, quando você coloca dados de clientes, pedidos e anexos nele, ele vira o centro de dados do negócio. Uma VPS barata serve, mas o backup não pode faltar.
Este artigo assume:
- Ubuntu 22.04 / 24.04 ou Debian 12.
- Docker e Docker Compose V2 já instalados.
- Você tem um domínio, por exemplo
nocodb.example.com. - O registro A do domínio aponta para o IP público da VPS.
- As portas 80 e 443 podem ser abertas para o Caddy obter HTTPS automaticamente.
Confirme o Docker:
docker version
docker compose version
Se ainda não instalou o Docker, pode ler primeiro o artigo deste site sobre Docker Compose em produção. Aqui não vou repetir a instalação básica.
O NocoDB oferece oficialmente scripts de quickstart e instalação de servidor único, que de fato são práticos:
curl -fsSL https://install.nocodb.com/noco.sh | bash
Ele gera uma stack de Compose para você, e o modo de servidor único ainda consegue lidar com Traefik e Let's Encrypt.
Mas não recomendo muito que iniciantes rodem o script direto na primeira vez. O motivo é simples: quando dá problema, você não sabe o que ele gerou, onde estão os dados, como fazer backup nem como migrar.
Este artigo adota a abordagem de escrever o Compose à mão. A configuração fica um pouco mais longa, mas você vê cada contêiner, cada volume e cada senha. A manutenção depois também fica mais segura.
Crie o diretório de implantação:
sudo mkdir -p /opt/nocodb
sudo chown -R "$USER":"$USER" /opt/nocodb
cd /opt/nocodb
mkdir -p postgres-data redis-data nocodb-data backups caddy-data caddy-config
Gere algumas chaves aleatórias:
openssl rand -base64 32
openssl rand -base64 32
openssl rand -hex 32
Elas são usadas respectivamente para:
- Senha do PostgreSQL
- NocoDB JWT Secret
- Chave de criptografia da conexão com o banco de dados
Não use password123 e não copie as senhas do tutorial. O NocoDB pode guardar mais tarde informações de conexão com bancos externos, então uma senha fraca é cavar um buraco para você mesmo.
Crie o .env:
nano .env
Escreva o conteúdo abaixo, trocando o domínio e as senhas pelos seus:
NOCODB_DOMAIN=nocodb.example.com
POSTGRES_PASSWORD=replace_with_a_long_postgres_password
NC_AUTH_JWT_SECRET=replace_with_a_long_random_secret
NC_CONNECTION_ENCRYPT_KEY=replace_with_64_hex_chars
Algumas variáveis explicadas:
POSTGRES_PASSWORD: senha do banco de dados PostgreSQL.NC_AUTH_JWT_SECRET: chave relacionada às sessões de login; precisa ser fixa em produção.NC_CONNECTION_ENCRYPT_KEY: usada para criptografar informações de conexão com bancos externos; recomendo configurar desde o início.NOCODB_DOMAIN: o domínio usado pelo proxy reverso do Caddy.
Não envie o arquivo .env para um repositório Git. Ele é o seu segredo de produção.
Crie o docker-compose.yml:
nano docker-compose.yml
Escreva:
services:
nocodb:
image: nocodb/nocodb:latest
container_name: nocodb
restart: unless-stopped
env_file:
- .env
environment:
NC_DB: "pg://db:5432?u=nocodb&p=${POSTGRES_PASSWORD}&d=nocodb"
NC_REDIS_URL: "redis://redis:6379"
NC_SITE_URL: "https://${NOCODB_DOMAIN}"
NC_AUTH_JWT_SECRET: "${NC_AUTH_JWT_SECRET}"
NC_CONNECTION_ENCRYPT_KEY: "${NC_CONNECTION_ENCRYPT_KEY}"
NC_DISABLE_MUX: "true"
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
volumes:
- ./nocodb-data:/usr/app/data
ports:
- "127.0.0.1:8080:8080"
healthcheck:
test: ["CMD-SHELL", "wget -q --tries=1 --spider http://localhost:8080/api/v1/health || exit 1"]
interval: 30s
timeout: 5s
retries: 5
start_period: 30s
worker:
image: nocodb/nocodb:latest
container_name: nocodb-worker
restart: unless-stopped
env_file:
- .env
environment:
NC_DB: "pg://db:5432?u=nocodb&p=${POSTGRES_PASSWORD}&d=nocodb"
NC_REDIS_URL: "redis://redis:6379"
NC_SITE_URL: "https://${NOCODB_DOMAIN}"
NC_AUTH_JWT_SECRET: "${NC_AUTH_JWT_SECRET}"
NC_CONNECTION_ENCRYPT_KEY: "${NC_CONNECTION_ENCRYPT_KEY}"
NC_WORKER_CONTAINER: "true"
depends_on:
nocodb:
condition: service_healthy
volumes:
- ./nocodb-data:/usr/app/data
db:
image: postgres:17-alpine
container_name: nocodb-db
restart: unless-stopped
environment:
POSTGRES_USER: nocodb
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
POSTGRES_DB: nocodb
volumes:
- ./postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U nocodb -d nocodb"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: nocodb-redis
restart: unless-stopped
volumes:
- ./redis-data:/data
command: redis-server --appendonly yes
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
caddy:
image: caddy:2-alpine
container_name: nocodb-caddy
restart: unless-stopped
env_file:
- .env
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./caddy-data:/data
- ./caddy-config:/config
depends_on:
- nocodb
Há alguns pontos escritos assim de propósito:
- O
nocodbsó se liga a127.0.0.1:8080, então a porta 8080 não pode ser acessada diretamente pela internet. - O que realmente fica exposto para fora são as portas 80/443 do Caddy.
- O PostgreSQL não mapeia a 5432, então varreduras na internet não encontram o banco de dados.
- O Redis também não mapeia a 6379.
nocodb-data,postgres-dataeredis-datasão diretórios do host, então você os encontra de imediato na hora do backup.
Uma prática mais estável em produção é fixar o nocodb/nocodb:latest na tag da versão estável atual. Na primeira implantação você pode usar latest para fazer funcionar; antes de colocar em produção, consulte a versão atual no NocoDB GitHub Releases ou no Docker Hub e fixe manualmente.
Crie o Caddyfile:
nano Caddyfile
Escreva:
{$NOCODB_DOMAIN} {
encode zstd gzip
reverse_proxy 127.0.0.1:8080
}
Garanta que o domínio já resolve para a VPS e então abra o firewall:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload
Se o seu provedor de nuvem também tiver security groups, libere 80 e 443 lá também. Muita gente libera no sistema mas não no painel da nuvem, e no fim o Caddy não consegue obter o certificado.
Execute:
cd /opt/nocodb
docker compose up -d
Ver o status dos contêineres:
docker compose ps
Ver os logs:
docker compose logs -f --tail=100 nocodb
A primeira inicialização vai baixar imagens e inicializar o banco de dados, então esperar alguns minutos é normal. Quando o nocodb ficar healthy, abra no navegador:
https://nocodb.example.com
O primeiro usuário registrado se torna superadministrador. Logo após o registro, vá às configurações e verifique e-mail, URL do site, idioma e permissões; não saia passando o link para a empresa toda.
O NocoDB tem várias formas de uso:
- Criar um projeto vazio e depois criar tabelas na interface.
- Importar CSV / Excel.
- Conectar a um banco de dados PostgreSQL / MySQL existente.
- Gerar uma API REST para uma tabela.
Se você está migrando do Excel, recomendo importar primeiro uma cópia; não conecte os dados de produção de cara.
Por exemplo, uma tabela de clientes pode ser organizada primeiro assim:
| Campo | Exemplo |
|---|---|
| Nome do cliente | Acme Inc |
| Contato | Zhang San |
| [email protected] | |
| Status | Em acompanhamento / Fechado / Pausado |
| Responsável | Alice |
| Próximo acompanhamento | 2026-07-15 |
Deixe o time testar por 1-2 semanas antes de decidir se conecta o banco de dados real do negócio. A maior armadilha das ferramentas low-code não é a implantação, mas o fato de todos desenharem os campos de forma bagunçada logo no começo.
O NocoDB pode se conectar a bancos de dados externos, e esse é também o seu recurso mais valioso. Mas aqui é preciso ter cautela.
Recomendações:
- Crie primeiro uma conta somente leitura para o NocoDB.
- Não use diretamente o usuário root do banco de dados.
- Não exponha a 5432 / 3306 do banco de produção para a internet.
- O ideal é que o NocoDB e o banco de dados se comuniquem na mesma rede interna ou rede Docker.
- Valide primeiro campos, relacionamentos e permissões em um banco de teste.
Por exemplo, um usuário somente leitura do PostgreSQL fica mais ou menos assim:
CREATE USER nocodb_readonly WITH PASSWORD 'change_this_password';
GRANT CONNECT ON DATABASE appdb TO nocodb_readonly;
GRANT USAGE ON SCHEMA public TO nocodb_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO nocodb_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO nocodb_readonly;
Se você realmente quer que operações edite dados no NocoDB, crie uma conta separada com permissões controladas e abra apenas as tabelas que precisam de edição. Não entregue todas as permissões do banco de dados só para facilitar.
O NocoDB exige backup de dois tipos de coisas:
- Banco de dados PostgreSQL: projetos, estruturas de tabelas, metadados do NocoDB, dados de negócio.
/usr/app/data: anexos, arquivos locais e outros dados.
Primeiro crie um script de backup:
nano backup-nocodb.sh
Escreva:
#!/usr/bin/env bash
set -euo pipefail
APP_DIR="/opt/nocodb"
BACKUP_DIR="$APP_DIR/backups"
DATE="$(date +%F-%H%M)"
mkdir -p "$BACKUP_DIR/$DATE"
cd "$APP_DIR"
docker exec nocodb-db pg_dump -U nocodb nocodb | gzip > "$BACKUP_DIR/$DATE/nocodb.sql.gz"
tar czf "$BACKUP_DIR/$DATE/nocodb-data.tar.gz" nocodb-data Caddyfile docker-compose.yml .env
find "$BACKUP_DIR" -mindepth 1 -maxdepth 1 -type d -mtime +14 -exec rm -rf {} \;
echo "Backup saved to $BACKUP_DIR/$DATE"
Adicione permissão de execução e teste:
chmod +x backup-nocodb.sh
./backup-nocodb.sh
ls -lh backups
Depois de confirmar que o arquivo de backup é gerado, adicione uma tarefa agendada:
crontab -e
Backup todos os dias às 3 da manhã:
0 3 * * * /opt/nocodb/backup-nocodb.sh >> /opt/nocodb/backups/backup.log 2>&1
Isso é só um backup local. Uma prática mais segura é usar também o rclone para sincronizar com armazenamento de objetos, outra VPS ou um NAS. Se você só faz backup na mesma máquina, quando o disco falha tudo se perde junto.
Se um backup nunca foi restaurado, não dá para considerá-lo realmente utilizável.
Encontre uma VPS de teste e copie os arquivos de backup para lá:
mkdir -p /opt/nocodb-restore
cd /opt/nocodb-restore
Extraia a configuração e os anexos:
tar xzf nocodb-data.tar.gz
Inicie o banco de dados e depois restaure o SQL:
docker compose up -d db redis
sleep 20
gunzip -c nocodb.sql.gz | docker exec -i nocodb-db psql -U nocodb nocodb
docker compose up -d
Em uma restauração real, pode ser preciso alterar o domínio, o certificado e o domínio no .env. Não espere o dia de um incidente em produção para praticar esse processo pela primeira vez.
Faça backup antes de atualizar:
cd /opt/nocodb
./backup-nocodb.sh
Se você ainda usa latest:
docker compose pull
docker compose up -d
Se você já fixou uma tag de versão, primeiro altere a versão da imagem no docker-compose.yml e depois execute o mesmo comando.
Após atualizar, verifique:
docker compose ps
docker compose logs --tail=100 nocodb
Depois abra a página web e confira pelo menos três coisas:
- Se consegue fazer login.
- Se as tabelas abrem.
- Se importação, exportação e anexos funcionam normalmente.
Quando uma ferramenta como o NocoDB entra no fluxo de trabalho do time, não atualize de qualquer jeito. Recomendo fazer em horário de baixo movimento, avisar o time antes de atualizar e manter um backup para rollback.
Primeiro veja os contêineres:
docker compose ps
Depois veja os logs do Caddy:
docker compose logs --tail=100 caddy
Se o Caddy falhar ao obter o certificado, verifique principalmente:
- Se o registro A do domínio aponta para a VPS atual.
- Se 80/443 estão bloqueadas pelo UFW ou por um security group.
- Se o modo proxy da Cloudflare interfere na validação.
No começo, recomendo deixar o registro DNS da Cloudflare em "somente DNS" e ativar o proxy conforme a necessidade depois que funcionar.
Veja os logs da aplicação:
docker compose logs -f nocodb
Causas comuns:
- Senha do PostgreSQL diferente.
- O
.envfoi alterado mas o contêiner não foi reiniciado. - O banco de dados ainda não está pronto e a aplicação falhou ao iniciar antes da hora.
- A string de conexão
NC_DBestá escrita errada.
Você pode verificar o banco de dados separadamente:
docker compose logs --tail=100 db
docker exec -it nocodb-db pg_isready -U nocodb -d nocodb
Se você só esqueceu a senha, use primeiro o recurso de recuperação do NocoDB. Se o e-mail não estiver bem configurado, vai ser bem mais complicado.
Por isso, logo ao colocar em produção, recomendo:
- Usar um e-mail disponível a longo prazo para a conta de administrador.
- Configurar o SMTP.
- Manter pelo menos duas contas de administrador.
- Registrar as informações da implantação inicial na documentação interna.
Não deixe só um administrador para a empresa toda, e ainda registrado com e-mail pessoal.
O problema mais comum com CSV em chinês é a codificação. Arquivos exportados do Excel muitas vezes não estão em UTF-8.
Soluções:
- Tente exportar como CSV UTF-8.
- Se for GBK, você pode converter primeiro:
iconv -f gbk -t utf-8 old.csv > new.csv
Além disso, dados como campos de data, números de telefone e números de pedido é melhor importar primeiro como texto. Muitas ferramentas de planilha se acham espertas e comem os zeros à esquerda.
Verifique principalmente:
- Se o endereço de escuta do banco de dados está ligado apenas a
127.0.0.1. - Se o firewall libera a conexão.
- Se as permissões do usuário permitem conexões remotas.
- Se o contêiner do NocoDB consegue resolver o hostname do banco de dados.
- Se os requisitos de TLS do banco de dados batem.
Mas repito: se puder usar a rede interna, use a rede interna; não exponha o banco de dados de produção diretamente à internet.
O NocoDB é uma ferramenta interna, mas, uma vez exposto à internet, precisa ser tratado como um sistema formal.
No mínimo, faça o seguinte:
- Abra apenas 80/443, não 8080, 5432 ou 6379.
- Use senhas fortes para os administradores.
- Desative o registro público que você não precisa.
- Dê o mínimo de privilégios a cada time.
- Use contas de baixo privilégio para conexões com bancos externos.
- Não coloque o
.envnem os arquivos de backup em diretórios acessíveis pela web. - Atualize periodicamente as imagens e os patches de segurança do sistema.
- Sincronize os backups fora do local.
- Ative o histórico de alterações nas tabelas importantes ou faça auditoria separada.
Se você vai deixar clientes ou colaboradores externos usarem, o melhor é adicionar uma camada de Cloudflare Access, Tailscale, VPN ou pelo menos HTTP Basic Auth. Não deixe uma interface interna de gestão de dados exposta para toda a internet.
Verifique antes do uso formal:
- O domínio já resolve para a VPS.
- 80/443 estão liberadas no firewall do sistema e no security group da nuvem.
- 8080 só se liga a
127.0.0.1. - PostgreSQL e Redis não expõem portas públicas.
- As senhas e chaves no
.envforam todas substituídas. - O
NC_SITE_URLé um domínio HTTPS real. - A primeira conta de administrador foi criada.
- O script de backup local rodou com sucesso.
- Pelo menos uma restauração de teste foi feita.
- As permissões do time e os campos das tabelas estão organizados.
Se você é só uma pessoa controlando contas e escrevendo tarefas, o NocoDB pode ser um pouco pesado. Notion, Feishu Sheets e Google Sheets são mais práticos.
Mas se você já tem uma VPS e quer transformar Excel, CSV e bancos de dados em uma ferramenta interna colaborativa, com controle de permissões e capaz de gerar APIs, o NocoDB vale muito a pena. Ele não pretende substituir todos os sistemas de backend, mas preencher o espaço entre "o desenvolvimento é lento demais, o Excel é bagunçado demais e o Airtable é caro demais".
Recomendo testar primeiro com dados não críticos, como cronograma de conteúdo, leads de clientes ou registros de estoque. Quando o time estiver confortável, vá conectando dados mais importantes aos poucos. O maior medo das ferramentas low-code é carregar o negócio principal logo de cara; valide em pequena escala primeiro e depois expanda, assim os problemas são mais fáceis de conter.