Qdrant: instalando um banco de dados vetorial na VPS
Olá meus Unicórnios! 🦄✨
Toda vez que alguém fala em "IA com memória", "busca semântica" ou "RAG", aparece no meio da conversa um bicho chamado banco de dados vetorial. E aí vem aquela sensação de que falta um pré-requisito que todo mundo tem menos você. 😅
Pois hoje a gente instala um. Do zero, numa VPS, com o terminal aberto. No fim deste artigo você vai ter um Qdrant rodando no seu servidor, protegido por chave, com dados dentro e respondendo consultas por semelhança.
🧠 Antes de tudo: o que esse banco faz de diferente
Um banco comum guarda o que você escreveu e devolve quando bate exatamente. Você pergunta "onde nome = 'maçã'" e ele te dá a maçã. Se você digitar "maca" sem cedilha, ele não acha nada. Ele compara igualdade.
Um banco vetorial guarda listas de números e compara semelhança. Cada item vira uma lista assim:
maça → [0.9, 0.1, 0.1, 0.1]
cereja → [0.85, 0.15, 0.1, 0.1]
banana → [0.1, 0.9, 0.1, 0.1]
Repare que maçã e cereja têm números parecidos, e a banana tem números diferentes. A pergunta que esse banco responde não é "qual é igual a este", é "quais são os mais próximos deste". É essa mudança que permite procurar por sentido em vez de por letra.
Essas listas de números têm nome: embeddings. Quem as produz é um modelo de IA, que lê um texto (ou uma imagem, ou um áudio) e devolve a lista. O banco vetorial não gera nada disso, ele guarda e procura. Neste tutorial os números vão ser escritos à mão, de propósito: assim dá para ver a busca funcionando sem depender de nenhuma chave de API de modelo.
🛒 Um exemplo que mostra por que isso vale a pena
Antes de instalar qualquer coisa, deixa eu te mostrar aonde a gente chega. Imagine uma loja com estes produtos cadastrados:
PC Gamer Ryzen 7 com 32GB DDR5 e RTX 4060 R$ 6500 estoque 4
PC Gamer Ryzen 5 com 16GB DDR5 e RTX 3050 R$ 1950 estoque 7
Computador basico Intel i3 com 8GB DDR4 R$ 1750 estoque 0
Computador escritorio Intel i5 com 16GB DDR5 R$ 1890 estoque 3
Notebook Dell i5 com 16GB DDR5 tela 15" R$ 3400 estoque 2
Notebook Acer Celeron com 4GB DDR4 R$ 1600 estoque 5
Um cliente digita na busca do site: "computador com memória ddr5". Com um banco comum, você escreveria algo assim:
SELECT * FROM produtos WHERE nome LIKE '%computador%'
E o resultado seria pobre por dois motivos. Primeiro, os dois notebooks ficariam de fora, porque nenhum tem a palavra "computador" no nome, mesmo sendo exatamente o que a pessoa quer. Segundo, os dois PCs Gamer também sumiriam, pelo mesmo motivo. Sobraria só o que tem a palavra escrita literalmente.
Com o Qdrant, a mesma busca traz isto (são resultados de verdade, do artigo que continua este):
72% Computador escritorio Intel i5 com 16GB DDR5 | R$ 1890 | estoque 3
66% Computador basico Intel i3 com 8GB DDR4 | R$ 1750 | estoque 0
63% Notebook Acer Celeron com 4GB DDR4 | R$ 1600 | estoque 5
Olhe o notebook na terceira posição. Ele apareceu numa busca por "computador" sem ter essa palavra no nome, porque o banco entendeu que notebook é um computador. Nenhum LIKE faz isso, e nenhuma lista de sinônimos escrita à mão dá conta de todos os casos.
E dá para ir além, misturando com filtros comuns na mesma consulta. O cliente quer até R$ 2.000 e só o que tem em estoque:
72% Computador escritorio Intel i5 com 16GB DDR5 | R$ 1890 | estoque 3
63% Notebook Acer Celeron com 4GB DDR4 | R$ 1600 | estoque 5
57% PC Gamer Ryzen 5 com 16GB DDR5 e RTX 3050 | R$ 1950 | estoque 7
O i3 sem estoque saiu, nada acima de R$ 2.000 entrou, e o PC Gamer subiu para o lugar vago. Semelhança e filtro, no mesmo pedido. 🎯
É para chegar aí que a gente instala o Qdrant hoje. Neste artigo o foco é deixar o servidor de pé, protegido e funcionando; a busca por texto que você acabou de ver tem artigo próprio, linkado no fim.
🖥️ O que você precisa ter em mãos
Uma VPS com Ubuntu e acesso root. Eu usei uma bem modesta, de 4 vCPU e 7,8 GB de RAM, mas você vai ver daqui a pouco que o Qdrant pede bem menos que isso.
Para entrar nela, o comando é o mesmo em qualquer sistema. Abra o terminal (no Windows, o PowerShell serve) e digite:
ssh root@SEU_IP_AQUI
Troque SEU_IP_AQUI pelo IP que o seu provedor te deu. Ele vai pedir a senha, e aqui vem o primeiro susto de quem nunca usou SSH: a senha não aparece enquanto você digita. Nem asterisco, nem pontinho, nada. Parece que o teclado morreu. Não morreu: digite e dê Enter. 🙂
Na primeiríssima conexão ele pergunta se você confia na máquina. Responda yes, por extenso.
🐳 Instalando o Docker
O Qdrant vai rodar dentro de um contêiner, então o Docker precisa estar na máquina. Se a sua VPS ainda não tem, o próprio site oficial dá um script que resolve:
curl -fsSL https://get.docker.com | sh
Aquele | no meio é o "cano": ele pega o que o curl baixou e entrega para o sh executar. Leva um ou dois minutos.
Para conferir se deu certo:
docker --version
docker compose version
Foi o que respondeu aqui:
Docker version 29.7.2, build a7dcaa6
Docker Compose version v5.5.0
As duas linhas precisam aparecer. O compose é o que lê o arquivo de configuração que a gente vai escrever agora, e nas versões atuais ele já vem junto com o Docker, sem instalação separada.
📁 Criando a pasta e o arquivo de configuração
Toda a instalação vai morar numa pasta só. Assim, no dia em que você quiser mexer, apagar ou fazer backup, é um lugar só para olhar:
mkdir -p /opt/qdrant
cd /opt/qdrant
O mkdir cria a pasta e o cd entra nela. O -p só evita reclamação caso ela já exista.
Agora o arquivo que descreve o contêiner. Vamos criá-lo com o nano, que é o editor de texto mais simples do Linux:
nano docker-compose.yml
A tela fica preta e vazia, com um rodapé cheio de atalhos. Cole o conteúdo abaixo e preste atenção em como se cola no terminal, porque este é o ponto em que muita gente trava: o Ctrl+V de sempre não funciona aqui. Use Ctrl+Shift+V, ou clique com o botão direito do mouse.
services:
qdrant:
image: qdrant/qdrant:v1.12.4
container_name: qdrant
restart: always
ports:
- 6333:6333
- 6334:6334
volumes:
- qdrant_dados:/qdrant/storage
environment:
- QDRANT__SERVICE__API_KEY=${QDRANT_API_KEY}
volumes:
qdrant_dados:
Para salvar: Ctrl+O (a letra O, de "output"), Enter para confirmar o nome, e Ctrl+X para sair. Aquele ^ que aparece no rodapé do nano significa a tecla Ctrl, então ^O se lê "Control O".
Vale entender três coisas desse arquivo, porque elas voltam mais para a frente:
A versão fixa na imagem (:v1.12.4) é de propósito. Se você escrever :latest, um docker compose pull feito daqui a seis meses pode trazer uma versão diferente da que você testou, e a surpresa vem sozinha. Versão presa, comportamento previsível.
O volume (qdrant_dados) é onde os dados de verdade ficam. Ele vive fora do contêiner, e é por isso que o contêiner pode ser destruído e recriado sem você perder nada. Daqui a pouco a gente prova isso na prática.
E as duas portas: a 6333 é a API REST, aquela que você chama com curl e onde fica o painel web. A 6334 é a mesma coisa em gRPC, que é o protocolo mais rápido usado pelas bibliotecas oficiais. Para este tutorial, quem interessa é a 6333.
🔑 A chave de API, que não é opcional
Repare que no compose eu não escrevi a chave: escrevi ${QDRANT_API_KEY}. Isso é uma referência a uma variável que vai morar num arquivo separado, o .env. Assim o docker-compose.yml pode ser copiado, mostrado e versionado sem levar o segredo junto.
Gere uma chave aleatória de verdade, em vez de inventar uma:
openssl rand -hex 32
Ele cospe uma sequência de 64 caracteres. Copie a sua e coloque no arquivo:
nano .env
Com uma linha só dentro, usando a sua chave:
QDRANT_API_KEY=SUA_CHAVE_AQUI
Salve do mesmo jeito: Ctrl+O, Enter, Ctrl+X.
Agora um detalhe que confunde: o arquivo some quando você lista a pasta. Digite ls e o .env não aparece. Ele não sumiu, é que no Linux todo nome que começa com ponto é considerado oculto. Para ver, peça o -la:
ls -la
-rw-r--r-- 1 root root 80 Aug 17 20:32 .env
-rw-r--r-- 1 root root 291 Aug 17 20:32 docker-compose.yml
Antes de subir qualquer coisa, peça ao Compose para conferir se ele entendeu o arquivo:
docker compose config
Esse comando mostra a configuração já resolvida, com a variável trocada pelo valor real. Se a indentação do YAML estiver errada, é aqui que você descobre, em vez de descobrir com o contêiner reiniciando sozinho. E ele serve de prova de que o .env está sendo lido: a chave aparece por extenso na saída, no lugar do ${QDRANT_API_KEY}.
🚀 Subindo o Qdrant
Chegou a hora:
docker compose up -d
O -d significa "modo destacado": o contêiner sobe e devolve o terminal para você, em vez de prender a tela com os logs. Na primeira vez ele baixa a imagem, o que leva um minuto:
Image qdrant/qdrant:v1.12.4 Pulled
Network qdrant_default Created
Volume qdrant_qdrant_dados Created
Container qdrant Created
Container qdrant Started
"Started" quer dizer que o contêiner subiu, não necessariamente que a aplicação está pronta. Confira o log:
docker logs qdrant
E aparece o Qdrant se apresentando, em ASCII art, com a versão e as duas portas:
_ _
__ _ __| |_ __ __ _ _ __ | |_
/ _` |/ _` | '__/ _` | '_ \| __|
| (_| | (_| | | | (_| | | | | |_
\__, |\__,_|_| \__,_|_| |_|\__|
|_|
Version: 1.12.4, build: 5b578c4f
INFO qdrant::actix: Qdrant HTTP listening on 6333
INFO qdrant::tonic: Qdrant gRPC listening on 6334
INFO qdrant: Distributed mode disabled
INFO qdrant::actix: TLS disabled for REST API
Duas linhas dessas merecem atenção. O Distributed mode disabled é o esperado: você tem um nó só, e é isso que a gente quer agora. Já o TLS disabled é um aviso de verdade, e eu volto nele no fim do artigo.
🔒 Provando que a chave está sendo exigida
Esse é o teste que eu não pulo em instalação nenhuma. Configurar a chave e acreditar que ela está valendo é diferente de conferir. Ainda de dentro da VPS:
curl http://localhost:6333/collections
Sem cabeçalho nenhum, a resposta é seca:
Invalid API key or JWT
E o código HTTP é 401. Agora a mesma chamada com a chave, no cabeçalho api-key:
curl http://localhost:6333/collections \
-H "api-key: SUA_CHAVE_AQUI"
{
"result": {
"collections": []
},
"status": "ok",
"time": 0.000052648
}
Passou, e a lista está vazia porque ainda não criamos nada. São trinta segundos de teste que respondem a pergunta que importa: a chave está sendo exigida de verdade, e não só decorando o arquivo de configuração.
Isso importa mais no Qdrant do que parece. Sem aquela variável no compose, ele sobe sem autenticação nenhuma, e não reclama disso em lugar nenhum: quem souber o IP e a porta lê, escreve e apaga suas coleções. A proteção não vem ligada por padrão; é você que liga.
🔥 Liberando a porta no firewall
Até agora todos os testes foram de dentro da máquina (localhost). Para acessar do seu computador, o firewall precisa deixar passar:
ufw allow 6333/tcp
ufw status
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
6333/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
6333/tcp (v6) ALLOW Anywhere (v6)
Se o firewall ainda estiver desligado na sua VPS e você for ligá-lo agora, libere o 22 antes de dar o ufw enable. A porta 22 é a do próprio SSH: ligando o firewall sem liberá-la, a sua conexão cai e você se tranca do lado de fora da máquina. É um erro que só se comete uma vez na vida. 😬
ufw allow 22/tcp
ufw allow 6333/tcp
ufw enable
Repare que a 6334 ficou de fora. É proposital: a gRPC só precisa estar aberta se algum sistema de fora for falar por ela. Porta que ninguém usa é porta que não se abre.
Agora, do seu computador, o mesmo teste de antes:
curl http://SEU_IP_AQUI:6333/collections \
-H "api-key: SUA_CHAVE_AQUI"
Respondeu {"result":{"collections":[]},"status":"ok"}? Então o serviço está no ar e alcançável. 🎉
🖱️ O painel web, e o que ele pede primeiro
O Qdrant já vem com uma interface visual, sem instalar nada. Abra no navegador:
http://SEU_IP_AQUI:6333/dashboard
E a primeira coisa que aparece é ela, a chave sendo cobrada:
Essa tela é a mesma prova do 401, só que visual. Cole a chave que você gerou com o openssl e clique em Apply. Se você tivesse esquecido a variável no compose, o painel abriria direto, sem pedir nada, e qualquer pessoa com o link faria o mesmo.
Feito o login, a aba Collections mostra a lista, ainda vazia. Vamos enchê-la.
🍎 Criando a primeira coleção
Coleção, no Qdrant, é o equivalente à tabela: é onde os vetores ficam. Ao criar, você decide duas coisas que não dá para mudar depois: o tamanho do vetor e a forma de medir distância.
curl -X PUT http://SEU_IP_AQUI:6333/collections/frutas \
-H "api-key: SUA_CHAVE_AQUI" \
-H 'Content-Type: application/json' \
-d '{"vectors":{"size":4,"distance":"Cosine"}}'
O size: 4 diz que cada vetor tem quatro números. No mundo real esse número vem do modelo que gera os embeddings (1.536 é comum), e tem que bater exatamente. Aqui usei 4 para caber na tela e você conseguir acompanhar as contas com o olho.
O distance: Cosine é a régua da comparação. A distância por cosseno olha para a direção dos números, não para o tamanho deles, e é a escolha padrão para busca por texto. As outras opções são Euclid e Dot.
Resposta: {"result":true,"status":"ok"}. Coleção criada.
➕ Inserindo os dados
Agora as quatro frutas. Cada ponto tem um id, o vector (os números) e o payload, que são os dados normais que você quer guardar junto:
curl -X PUT "http://SEU_IP_AQUI:6333/collections/frutas/points?wait=true" \
-H "api-key: SUA_CHAVE_AQUI" \
-H 'Content-Type: application/json' \
-d '{"points":[
{"id":1,"vector":[0.9,0.1,0.1,0.1],"payload":{"nome":"maca","cor":"vermelha"}},
{"id":2,"vector":[0.85,0.15,0.1,0.1],"payload":{"nome":"cereja","cor":"vermelha"}},
{"id":3,"vector":[0.1,0.9,0.1,0.1],"payload":{"nome":"banana","cor":"amarela"}},
{"id":4,"vector":[0.1,0.1,0.9,0.1],"payload":{"nome":"uva","cor":"roxa"}}]}'
Aquele ?wait=true no fim da URL é pequeno e importante. Sem ele, o Qdrant aceita a escrita e responde na hora, gravando logo em seguida. Você faria a busca no instante seguinte e poderia não achar nada, passando meia hora procurando erro na consulta, quando o problema era só pressa. Com o wait=true, ele só responde depois de gravar:
{
"result": {
"operation_id": 0,
"status": "completed"
},
"status": "ok",
"time": 0.011761709
}
Voltando ao painel, a coleção agora aparece na lista:
Status green, quatro pontos, e a configuração que a gente escolheu ali do lado: default 4 Cosine. No canto inferior esquerdo, a versão batendo com a que fixamos no compose.
🔍 A busca por semelhança
Agora o motivo de tudo isso. Vamos perguntar: quais frutas são mais parecidas com a maçã? Para isso, mandamos o vetor da maçã e pedimos os três primeiros:
curl -X POST http://SEU_IP_AQUI:6333/collections/frutas/points/search \
-H "api-key: SUA_CHAVE_AQUI" \
-H 'Content-Type: application/json' \
-d '{"vector":[0.9,0.1,0.1,0.1],"limit":3,"with_payload":true}'
Dá para fazer isso pelo painel também, na aba do console, que é o jeito mais confortável de brincar com as consultas:
E olhe os números da coluna da direita, porque eles contam a história inteira:
maca score 1.0
cereja score 0.99797505
uva score 0.23809524
A maçã tirou 1.0 porque comparei o vetor dela com ela mesma: semelhança perfeita. A cereja tirou 0,998, quase empatada. E a uva ficou lá embaixo, com 0,238.
Isso é a busca por semelhança acontecendo. Eu não perguntei por cor, não filtrei por nada, não escrevi "vermelha" em lugar nenhum da consulta: perguntei quem se parece com a maçã, e ele me trouxe a cereja. Troque as frutas por textos de artigos, e é exatamente assim que uma busca semântica funciona. ✨
Repare também no que não apareceu: pedi limit: 3 e vieram três, então a banana ficou de fora por ser a menos parecida. O limit aqui não é paginação, é o "me traga os N mais próximos".
✍️ "E se eu quiser buscar digitando uma palavra?"
Foi a primeira pergunta que me fizeram quando mostrei isto funcionando, e ela merece uma resposta clara: não dá para mandar texto direto para o Qdrant. Tentando, ele reclama:
{
"status": {
"error": "Format error in JSON body: data did not match any variant of untagged enum NamedVectorStruct"
}
}
É que ele não lê palavra nenhuma. O Qdrant guarda e compara números, só isso. Quem transforma "laranja vermelha" em números é o tal modelo de embeddings que citei lá no começo, e ele fica fora do banco.
O caminho completo é este:
E tem uma regra que não perdoa: o modelo da busca precisa ser o mesmo que gerou os vetores guardados. É como uma régua. Se você mediu tudo em centímetros, não adianta consultar em polegadas: os números até chegam, mas a comparação vira sorteio.
Para buscar digitando, o caminho é criar outra coleção, com o tamanho que o seu modelo devolve (384, 768 e 1.536 são os comuns), e gerar os vetores pelo modelo tanto na hora de gravar quanto na hora de buscar. Aí sim você digita "laranja vermelha" e ele acha "maçã vermelha e doce" sem que a palavra bata.
Busca semântica no Qdrant: digitando o que você querO passo a passo em Node.js, com o modelo rodando de graça no seu servidor e o filtro de preço e estoque na mesma consulta.blog.palomamacetko.com.br🎯 Misturando semelhança com filtro comum
Esse é o pulo do gato que costuma decidir a escolha do banco. Dá para pedir "o mais parecido com a maçã, mas só entre as amarelas", misturando a busca vetorial com um filtro nos dados normais:
curl -X POST http://SEU_IP_AQUI:6333/collections/frutas/points/search \
-H "api-key: SUA_CHAVE_AQUI" \
-H 'Content-Type: application/json' \
-d '{"vector":[0.9,0.1,0.1,0.1],"limit":3,"with_payload":true,
"filter":{"must":[{"key":"cor","match":{"value":"amarela"}}]}}'
E vem só a banana, com o score baixo que ela merece:
{
"result": [
{
"id": 3,
"score": 0.23809524,
"payload": {
"nome": "banana",
"cor": "amarela"
}
}
],
"status": "ok"
}
Na prática é isso que você usa o tempo todo: "artigos parecidos com este, mas só os publicados", "produtos parecidos com este, mas só os que têm estoque". A semelhança escolhe, o filtro restringe.
😵 Três erros que eu vi enquanto fazia isto
Todos os três dão mensagens claras, o que é uma boa notícia. Vale conhecer as três agora, para reconhecer na hora em vez de procurar no escuro.
1. O vetor com o tamanho errado. Mandei três números numa coleção de quatro:
{
"status": {
"error": "Wrong input: Vector dimension error: expected dim: 4, got 3"
},
"time": 0.001680171
}
Esse é o erro mais comum de quem está começando com embeddings de verdade, e quase sempre significa a mesma coisa: você trocou o modelo que gera os vetores, e o novo devolve um tamanho diferente do que a coleção espera. Como o tamanho é decidido na criação, o jeito é criar outra coleção e migrar.
2. A coleção que não existe. Um erro de digitação no nome:
{
"status": {
"error": "Not found: Collection `naoexiste` doesn't exist!"
},
"time": 0.000016
}
3. A chave errada. Volta o Invalid API key or JWT de antes. Detalhe cruel: é a mesma mensagem de quando você esquece o cabeçalho inteiro. Então, se aparecer isso, confira as duas coisas: se o cabeçalho está indo e se o valor dele está certo.
🤔 O zero que assusta e não é problema
Peça as informações da coleção e olhe com atenção:
curl http://SEU_IP_AQUI:6333/collections/frutas \
-H "api-key: SUA_CHAVE_AQUI"
{
"result": {
"status": "green",
"indexed_vectors_count": 0,
"points_count": 4,
"segments_count": 4
}
}
São quatro pontos, mas indexed_vectors_count é zero. Parece que a indexação falhou, ou que os dados não entraram direito. Não é isso.
O Qdrant só constrói o índice HNSW (a estrutura que deixa a busca rápida em volume grande) a partir de 20 mil vetores por segmento, que é o valor padrão do indexing_threshold. Abaixo disso, ele simplesmente compara um por um, e nesse tamanho isso é mais rápido do que consultar um índice, além de dar resultado exato.
Ou seja: com poucos dados, esse número vai ficar zero e a busca vai funcionar perfeitamente, como você acabou de ver. Vale saber disso agora, porque é o tipo de campo que assusta em produção e faz a pessoa sair mexendo em configuração que não precisava ser mexida. 😌
📊 Quanto ele consome, de verdade
Com tudo de pé, perguntei ao Docker:
docker stats --no-stream
NAME MEM USAGE / LIMIT CPU %
qdrant 28.31MiB / 7.755GiB 0.14%
28 MB de RAM. É menos que muita aba de navegador. A imagem no disco tem 279 MB, o que também é modesto perto de outros bancos.
Claro que esse número cresce: o Qdrant mantém o índice em memória, então quem manda no consumo é a quantidade de vetores e o tamanho de cada um. Mas para começar, testar e rodar um projeto pequeno, a VPS mais barata dá conta com folga.
💾 Provando que os dados sobrevivem
Lembra do volume lá no compose? Vamos provar que ele funciona, derrubando o contêiner de propósito:
cd /opt/qdrant
docker compose down
Container qdrant Removed
Network qdrant_default Removing
Network qdrant_default Removed
O contêiner foi removido, não só parado. Mas o volume continua lá:
docker volume ls
local qdrant_qdrant_dados
Subindo de novo e perguntando quantos pontos existem:
docker compose up -d
E a coleção frutas responde points_count: 4, com as mesmas frutas de antes. Os dados nunca estiveram dentro do contêiner: estavam no volume, ao lado dele.
🧰 Os comandos do dia a dia
Todos rodam de dentro de /opt/qdrant:
docker compose ps # o que esta de pe
docker compose logs -f # logs ao vivo (Ctrl+C para sair)
docker compose restart # reiniciar
docker compose up -d # subir, ou aplicar mudanca no compose
docker compose down # parar (volumes preservados)
O up -d é o mesmo comando de subir e de aplicar mudança: se você editar o docker-compose.yml, é ele que percebe a diferença e recria o contêiner.
🔓 O HTTP puro, e onde eu não pararia por aqui
Tem uma linha lá do log que eu deixei para o fim, de propósito:
INFO qdrant::actix: TLS disabled for REST API
Sem HTTPS, a sua chave de API viaja em texto puro em toda requisição. Para estudar, testar e montar um protótipo, tudo bem. Para guardar dado que importa, não: o caminho é pôr um proxy reverso na frente (Nginx, Caddy ou Traefik) com certificado, e deixar o Qdrant escutando só localmente.
E, já que a gente falou de firewall, vale a versão mais cuidadosa: em vez de ufw allow 6333/tcp para o mundo inteiro, dá para liberar só o IP que precisa acessar:
ufw allow from SEU_IP_DE_CASA to any port 6333 proto tcp
Assim o banco fica visível para você e invisível para o resto da internet, o que é bem mais confortável enquanto o HTTPS não entra.
Por hoje é só, meus unicórnios! 🦄✨
Que a magia do arco-íris continue brilhando em suas vidas! Até mais! 🌈🌟
Perguntas frequentes
O que é um banco de dados vetorial?
Quanto de servidor o Qdrant precisa?
docker stats foi de 28 MB de RAM e CPU praticamente parada. A imagem ocupa 279 MB no disco. Uma VPS básica dá conta com folga, e o que cresce depois é a memória, conforme a quantidade de vetores.O Qdrant já vem protegido por senha?
QDRANT__SERVICE__API_KEY, ele sobe sem autenticação nenhuma: quem souber o IP e a porta lê, escreve e apaga suas coleções. A proteção não é padrão, é opção. Depois de configurar a chave, qualquer requisição sem o cabeçalho api-key passa a receber 401.Por que meus vetores aparecem com indexed_vectors_count igual a zero?
indexing_threshold. Abaixo disso o Qdrant compara um por um, o que é mais rápido no volume pequeno. A busca funciona normalmente: o zero ali não significa que os dados sumiram nem que algo deu errado.O docker compose down apaga as coleções do Qdrant?
docker compose down remove o contêiner mas preserva o volume, então as coleções continuam lá quando você subir de novo. O que apaga tudo é o docker compose down -v: o -v remove os volumes junto. É a mesma diferença de qualquer stack com Docker, e vale conferir antes de digitar.Dá para buscar digitando uma palavra, tipo "laranja vermelha"?
Qual a diferença entre as portas 6333 e 6334 do Qdrant?
6333 é a API REST, a que você usa com curl e onde vive o painel web. A 6334 é a mesma API em gRPC, mais rápida e usada pelas bibliotecas oficiais quando você configura o cliente para isso. Para começar, basta liberar a 6333 no firewall: a gRPC só precisa ser exposta se algum sistema de fora for falar por ela.Leia também
OpenSEO: instalando na VPS e auditando um site
Como instalar o OpenSEO, alternativa aberta ao Semrush, numa VPS com Docker, auditar um site de verdade e entender a chave da DataForSEO.
changedetection.io: vigiando mudanças em sites na sua VPS
Instale o changedetection.io numa VPS com Docker, vigie um site com filtro CSS, receba o aviso no celular e acabe com o alarme falso do RSS.
Project NOMAD: seu servidor offline de emergência
Instale o Project NOMAD numa VPS Ubuntu e tenha Wikipédia, mapas, cursos e IA funcionando sem nenhuma conexão com a internet.