Instalar o Docker e o Docker Compose em Debian e Ubuntu

Publicado a 17 min de leitura

Porque é que o docker.io é demasiado antigo no Debian 12 mas serve no Ubuntu, como integrar o repositório oficial com keyring em vez de apt-key, porque é que o Compose é um plugin e por que motivo o grupo docker significa, na prática, root.

Instalar o Docker demora cinco minutos. Instalar o Docker de forma a que, um ano depois, o servidor continue a receber atualizações de segurança, o disco de sistema não encha e nem todos os utilizadores andem por ali com privilégios de root sem darem por isso, demora um pouco mais. Este artigo trata da segunda variante, verificada em Debian 13 (Trixie), Debian 12 (Bookworm), Ubuntu 24.04 (Noble) e Ubuntu 22.04 (Jammy).

docker.io ou Docker CE: a diferença que quase ninguém explica com honestidade

Há dois caminhos para chegar ao Docker. O pacote docker.io vem das fontes de pacotes da distribuição e é construído e mantido pela Debian ou pelo Ubuntu. O pacote docker-ce vem do repositório da própria Docker. Ambos contêm o mesmo software, mas com idades muito diferentes.

Estas são as versões que se encontram atualmente nas fontes das distribuições (medidas com apt-cache policy em containers acabados de criar):

Sistemadocker.io nas fontes da distribuição
Debian 13 (Trixie)26.1.5
Debian 12 (Bookworm)20.10.24
Ubuntu 24.04 (Noble)29.1.3
Ubuntu 22.04 (Jammy)29.1.3

É este o verdadeiro ponto da questão, e quase todos os guias o reduzem a uma recomendação geral. A verdade é bastante mais matizada:

  • Ubuntu 24.04 e 22.04: o docker.io está na 29.1.3 e, portanto, praticamente ao nível da versão upstream atual. Quem não tenha exigências especiais pode usar aqui o pacote da distribuição sem remorsos. As atualizações de segurança chegam depois pelo canal normal do Ubuntu.
  • Debian 13: a 26.1.5 é utilizável, mas fica um bom bocado atrás do upstream. Para a maioria dos casos de utilização chega perfeitamente.
  • Debian 12: a 20.10.24 é o caso problemático. Este ramo chegou ao fim do seu ciclo de vida upstream há anos. A Debian continua a integrar correções de segurança, mas faltam simplesmente muitas funcionalidades modernas, entre elas uma versão atual do BuildKit e uma boa parte da compatibilidade com o Compose.

A isto junta-se uma diferença prática: o docker-ce traz o Buildx e o Compose como pacotes de plugin próprios, ajustados à Engine. Com o docker.io tem de ir buscar essas peças separadamente a docker-buildx e docker-compose-v2, e o docker-compose-v2 só existe nas fontes do Ubuntu; na Debian esse pacote não existe de todo.

O que não funciona: os dois em paralelo. O pacote containerd.io do repositório da Docker entra em conflito com o pacote containerd da distribuição. Tem mesmo de escolher um.

Regra prática: no Ubuntu, o docker.io é uma escolha legítima. No Debian 12 não é. Para servidores que correm stacks de Compose com sintaxe atual, o Docker CE é em toda a parte a melhor decisão.

Remover os pacotes antigos antes de mais nada

Se já existir algum Docker seja de que forma for, tem de sair, caso contrário a instalação falha por conflitos de pacotes. O ciclo seguinte remove todos os suspeitos do costume e apanha pelo caminho os pacotes que nem sequer estão instalados ou que não existem de todo na sua distribuição:

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove -y $pkg || true; done

O || true dentro do ciclo não é um capricho, é mesmo necessário. Na Debian, o apt-get aborta na entrada docker-compose-v2 com E: Unable to locate package docker-compose-v2 e código de saída 100, porque esse pacote só existe nas fontes do Ubuntu e não em bookworm nem em trixie (nem em bullseye, onde além disso falta o podman-docker). O ciclo até continua a correr, mas deixa um código de saída diferente de 0, e é exatamente aí que morre um script com set -e ou uma cadeia com &&. Mensagens do género "Unable to locate package" são portanto normais neste ponto e podem ser ignoradas, tal como faz a documentação oficial do Docker.

Importa saber: com isto não se perde nada. As suas imagens, containers e volumes estão em /var/lib/docker, e o apt-get remove não toca nesse diretório. Depois de instalar o Docker CE, os seus containers voltam a estar lá. Só o sudo rm -rf /var/lib/docker apaga mesmo, e isso é irreversível.

Guardar a chave no sítio certo: o apt-key é história

Muitos guias na internet ainda contêm esta linha:

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -

Isto já não funciona de forma sensata em nenhum dos quatro sistemas aqui tratados. O apt-key está descontinuado e na Debian 13 já nem sequer existe. A razão não é cosmética: uma chave em /etc/apt/trusted.gpg assina todos os repositórios, não apenas aquele para o qual foi pensada. Um servidor espelho comprometido poderia assim impingir-lhe quaisquer pacotes.

O correto é um keyring próprio em /etc/apt/keyrings/, associado a exatamente uma fonte através de Signed-By.

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings

O comando seguinte vai buscar a chave certa e funciona tanto na Debian como no Ubuntu, porque lê o identificador da distribuição a partir de /etc/os-release:

sudo curl -fsSL "https://download.docker.com/linux/$(. /etc/os-release && echo "$ID")/gpg" -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

E agora o passo que praticamente ninguém descreve: verifique a impressão digital antes de confiar o seu sistema a essa chave.

gpg --show-keys /etc/apt/keyrings/docker.asc

A saída tem de conter a impressão digital 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88 e o identificador Docker Release (CE deb) <docker@docker.com>. Se não coincidir, interrompa aqui. Nesse caso há algo de errado com a sua ligação ou com a fonte.

Instalar o Docker CE com um bloco único para os quatro sistemas

A documentação oficial mostra blocos separados para Debian e Ubuntu. Isso é desnecessário. O bloco seguinte escreve a fonte de pacotes no moderno formato deb822 e determina sozinho a distribuição, o nome de código e a arquitetura:

sudo tee /etc/apt/sources.list.d/docker.sources > /dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/$(. /etc/os-release && echo "$ID")
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

Dois pormenores que poupam tempo. Primeiro o ${UBUNTU_CODENAME:-$VERSION_CODENAME}: em derivados do Ubuntu, como o Linux Mint, a variável VERSION_CODENAME contém o nome da derivação e não o do Ubuntu. Segundo, a linha Architectures: sem ela, o apt queixa-se em sistemas com a arquitetura estrangeira i386 ativada, com um aviso longo sobre listas de pacotes inexistentes.

Verifique o resultado antes de continuar:

cat /etc/apt/sources.list.d/docker.sources

Em Suites tem de constar trixie, bookworm, noble ou jammy. Se estiver ali outra coisa, o passo seguinte vai dar erro. Seguem-se então a atualização e a instalação:

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Os cinco pacotes são: o daemon, a ferramenta de linha de comandos, o runtime de containers, o construtor moderno de imagens e o Compose.

Como perceber que está mesmo a funcionar

O facto de o apt-get ter corrido sem erros significa apenas que há ficheiros no disco. As quatro verificações seguintes mostram se o sistema está realmente a trabalhar.

Primeiro: o cliente chega ao daemon?

docker version

O decisivo não é a secção Client, mas sim que por baixo apareça uma secção Server: Docker Engine - Community com um número de versão. Se faltar, ou o daemon não está a correr, ou não tem permissão para aceder ao socket.

Segundo: que driver de armazenamento está ativo?

docker info --format '{{.Driver}}'
docker info --format '{{.CgroupVersion}}'

Aqui espreita uma novidade a que muitos guias antigos respondem mal. Desde o Docker Engine 29, nas instalações novas vem predefinido o image store do containerd. O driver passa então a chamar-se overlayfs e já não overlay2. Ambos os valores estão bem. O que não quer ver é vfs: este driver de emergência copia cada camada por inteiro, devora um múltiplo do espaço em disco e é dolorosamente lento. Aparece tipicamente quando o Docker corre num ambiente sem o suporte adequado no kernel. A versão de cgroup tem de dar 2 nos quatro sistemas.

Se atualizou um sistema já existente e de repente todas as imagens parecem ter desaparecido: não foram apagadas. Ao mudar de image store, o conteúdo do outro armazenamento fica apenas oculto e reaparece assim que voltar atrás. A mudança de volta faz-se em /etc/docker/daemon.json:

{
  "features": {
    "containerd-snapshotter": false
  }
}

Terceiro: está mesmo a correr um container?

docker run --rm hello-world

Quarto: a rede e a resolução de nomes funcionam dentro do container? Este teste falta em quase todos os guias, apesar de ser precisamente aqui que nasce a maior parte dos problemas seguintes:

docker run --rm alpine:3 ping -c 2 1.1.1.1
docker run --rm alpine:3 nslookup deb.debian.org

Se o ping responder mas a resolução de nomes falhar, a causa costuma ser um servidor DNS que só escuta em 127.0.0.53. A partir do container esse endereço não é acessível. A solução passa por uma entrada em /etc/docker/daemon.json com "dns": ["9.9.9.9"] e um reinício do daemon.

O Compose é um plugin, já não é um programa próprio

O antigo docker-compose com hífen era um programa Python separado. Foi descontinuado e já não é distribuído. O sucessor é um plugin escrito em Go, invocado como subcomando da CLI do Docker, ou seja, docker compose com espaço.

docker compose version

Uma nota sobre o número de versão, porque isto gera confusão com regularidade: a expressão "Compose V2" designa o novo desenvolvimento em Go, não o número de versão. A saída mostra hoje uma versão do ramo 5. Isso está correto e não se trata de outro produto.

Na mudança há duas coisas que saltam à vista. Por um lado, a chave version: no início do docker-compose.yml tornou-se supérflua e gera um aviso:

WARN[0000] docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion

Apague simplesmente essa linha. Por outro lado, a nomenclatura muda: o Compose deriva o nome do projeto do nome do diretório e cria containers com hífen em vez de sublinhado, ou seja, meuprojeto-web-1 em vez de meuprojeto_web_1. Os scripts que se dirigem aos containers por nomes fixos deixam de funcionar. Nesses casos, defina o nome do projeto explicitamente com name: no ficheiro Compose ou com -p.

Se quiser mesmo ficar pelos pacotes da distribuição, o pacote adequado chama-se docker-compose-v2 e fornece o mesmo subcomando. Só está disponível, no entanto, nas fontes do Ubuntu. Verifique antes a versão disponível:

apt-cache policy docker-compose-v2

No Ubuntu 24.04 e 22.04 aparece uma tabela com a versão instalada e a versão candidata. Na Debian 13 e na Debian 12, o comando não devolve nada, uma saída vazia com código de saída 0. Isso não é um erro, é a resposta: na Debian este pacote não existe e o caminho para o Compose passa ali pelo docker-compose-plugin do repositório da Docker.

O grupo docker é root, apenas por um caminho indireto

Para que um utilizador normal possa usar o Docker sem sudo, é habitual acrescentá-lo ao grupo docker:

sudo groupadd -f docker
sudo usermod -aG docker $USER

A pertença ao grupo só produz efeito no próximo início de sessão. Pode confirmá-lo depois de voltar a autenticar-se, com id -nG. Quem não queira iniciar sessão de novo, abre uma shell com o novo grupo através de newgrp docker.

Agora a parte que tem mesmo de perceber: pertencer ao grupo docker equivale a ter privilégios de root em todo o servidor. Isto não é uma avaliação teórica, é uma consequência direta do modo de funcionamento. Quem pode falar com o socket do Docker pode dar ordens arbitrárias ao daemon, que corre como root. Basta um único comando:

docker run -it -v /:/hostfs alpine:3 chroot /hostfs sh

O resultado é uma shell de root no sistema anfitrião, sem sudo, sem pedido de palavra-passe, sem qualquer entrada no registo do sudo. Ler o /etc/shadow, colocar chaves SSH, trocar serviços: tudo possível. A documentação do Docker formula-o de forma curta e inequívoca: "The docker group grants root-level privileges to the user."

Consequências práticas para um servidor exposto à internet:

  • Inclua no grupo exclusivamente as contas a que confiaria root de qualquer maneira.
  • O utilizador sob o qual corre uma aplicação web ou um runner de CI não pertence a esse grupo. Caso contrário, uma invasão da aplicação seria automaticamente uma invasão do servidor.
  • Se precisar de rastreabilidade, dispense o grupo e invoque o Docker através de sudo docker. Assim, pelo menos a chamada fica registada.
  • Para uma separação a sério existe o modo rootless. Configura-se com o pacote docker-ce-rootless-extras e a ferramenta dockerd-rootless-setuptool.sh install, e precisa ainda de uidmap. O preço a pagar: as portas abaixo de 1024 não se deixam ocupar sem configuração adicional, e algumas funções de rede comportam-se de outra maneira.

Arranque automático: a armadilha chama-se docker.socket

O comando padrão é conhecido:

sudo systemctl enable --now docker.service
sudo systemctl enable --now containerd.service

Menos conhecido é o motivo pelo qual desativar muitas vezes não resulta. Além do docker.service, o Docker traz também um docker.socket. Esta unit escuta no socket e arranca o daemon automaticamente ao primeiro acesso. Quem executa systemctl disable docker.service e depois constata que o Docker continua a correr não viu nenhum fantasma: o primeiro docker ps voltou a levantar o daemon através da unit de socket. Para desativar por completo são precisos os dois:

sudo systemctl disable --now docker.service docker.socket

O estado pode ser confirmado com systemctl is-enabled docker.service, que tem de devolver enabled.

O segundo ponto diz respeito aos seus containers. Quem decide se um container volta depois de um reinício não é o systemd, mas a restart policy. E aí há uma diferença que surpreende com regularidade: always volta a arrancar um container mesmo quando o parou de propósito antes do reinício. unless-stopped respeita a sua paragem manual para lá do reinício. Para servidores, unless-stopped é quase sempre a escolha certa:

services:
  web:
    image: nginx:stable
    restart: unless-stopped

O teste para isso não é o docker ps, mas um reinício a sério do servidor com verificação a seguir.

Rotação de logs: a causa mais frequente de um disco de sistema cheio

Por norma, o Docker escreve a saída de cada container num ficheiro JSON em /var/lib/docker/containers/. Por predefinição, esse ficheiro cresce sem limite. Um reverse proxy tagarela consegue assim juntar dezenas de gigabytes ao longo de meses, até o servidor parar com no space left on device. O culpado é depois difícil de encontrar, porque o du no diretório da aplicação não mostra nada de estranho.

A solução pertence a qualquer servidor, e deve ser aplicada antes de surgir o primeiro problema:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}
EOF

Se já existir um daemon.json, este comando sobrepõe-se a ele. Verifique antes e acrescente as chaves à mão, se for esse o caso. Depois disso:

sudo systemctl restart docker

Três pontos em que, mesmo assim, as coisas correm mal:

  • Os valores têm de estar como cadeias de caracteres, entre aspas. "max-file": 3 sem aspas impede o daemon de arrancar.
  • A definição vale apenas para containers criados de novo. Os existentes mantêm a configuração antiga até serem recriados, no caso do Compose através de docker compose up -d --force-recreate.
  • Apagar com rm um ficheiro de log transbordado não devolve espaço em disco, porque o daemon ainda mantém o ficheiro aberto. Use antes sudo truncate -s 0 <caminho>.

Para saber se a definição se aplica a um container concreto, verifique assim:

docker inspect --format '{{json .HostConfig.LogConfig}}' meucontainer

Limpar com docker system prune sem perder dados

As imagens não utilizadas, os builds interrompidos e a cache do BuildKit vão-se somando. Primeiro convém ver para onde vai o espaço:

docker system df
docker system df -v

O comando padrão de limpeza remove containers parados, redes não utilizadas, imagens sem nome e a cache de build:

docker system prune

Duas opções merecem respeito. O -a apaga adicionalmente todas as imagens que não estejam a ser usadas por nenhum container nesse momento, incluindo imagens base cuidadosamente mantidas. Num servidor com conectividade limitada, voltar a descarregá-las pode demorar. Bastante mais perigoso é o --volumes: esta opção remove volumes nomeados sem container associado. Se o seu container de base de dados acabou de ser apagado mas o volume ainda contém os dados, estes desaparecem a seguir. Não há caixote do lixo onde os ir buscar.

Nunca utilize o --volumes num trabalho de limpeza automático.

Faz sentido definir um período de carência, para que só desapareça material realmente antigo:

docker system prune -a --filter "until=168h"
docker builder prune --filter "until=168h"

Como trabalho semanal, poupado em recursos durante a noite e sem apagar volumes, basta uma linha em /etc/cron.d/docker-prune:

15 4 * * 0 root /usr/bin/docker system prune -af --filter "until=168h" > /dev/null 2>&1

A prova de que resultou é um novo docker system df com a coluna "RECLAIMABLE" mais baixa.

As mensagens de erro na íntegra e o que está por trás delas

permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
O utilizador não está no grupo docker, ou a pertença ao grupo ainda não produziu efeito na sessão atual. Inicie sessão de novo ou use newgrp docker.

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
O daemon não está a correr. A causa e o texto exato são dados pelo systemctl status docker e, com mais detalhe, pelo journalctl -u docker -n 50 --no-pager. Muito frequentemente está por trás um /etc/docker/daemon.json defeituoso. Esse ficheiro tem de ser JSON válido, basta uma vírgula a mais.

docker: 'compose' is not a docker command.
Falta o plugin. Instale ou o docker-compose-plugin do repositório da Docker ou, apenas no Ubuntu, o docker-compose-v2 da distribuição.

E: Conflicting values set for option Signed-By regarding source https://download.docker.com/linux/debian/ trixie: /etc/apt/keyrings/docker.asc != /etc/apt/keyrings/docker.gpg
O clássico depois de se seguirem vários guias: existem ao mesmo tempo um antigo /etc/apt/sources.list.d/docker.list e o novo docker.sources. Apague o ficheiro antigo e repita o sudo apt-get update. Ganhe uma visão de conjunto com ls -l /etc/apt/sources.list.d/.

The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8D81803C0EBFCD88
A chave não está onde o Signed-By a espera, ou o ficheiro descarregado está incompleto (por exemplo, porque um proxy devolveu uma página de erro HTML). O gpg --show-keys /etc/apt/keyrings/docker.asc mostra de imediato se existe sequer alguma chave lá dentro.

E: The repository 'https://download.docker.com/linux/debian trixie Release' does not have a Release file.
O nome de código não corresponde à fonte. Isso acontece em distribuições derivadas e quando se misturam guias de Debian e de Ubuntu. Verifique as linhas URIs e Suites no docker.sources.

Bind for 0.0.0.0:80 failed: port is already allocated
Outro serviço ocupa a porta, muitas vezes um servidor web instalado diretamente. O sudo ss -tulpn | grep :80 identifica o responsável.

Docker e a firewall: uma palavra sobre segurança

Uma particularidade que pode sair cara num servidor acessível publicamente: o Docker inscreve as suas regras de encaminhamento na tabela NAT e contorna assim as regras que manteve no ufw. Um container arrancado com -p 5432:5432 fica acessível a partir da internet, mesmo que o ufw status não permita essa porta em lado nenhum. Isto continua a aplicar-se, embora o Docker Engine 28 tenha endurecido o comportamento de rede no seu conjunto e tenha bloqueado o acesso externo às portas não publicadas.

A contramedida mais simples e mais fiável é ligar explicitamente ao endereço de loopback os serviços de que só se precisa localmente:

services:
  db:
    image: postgres:17
    ports:
      - "127.0.0.1:5432:5432"
    restart: unless-stopped

Melhor ainda: não publique de todo essas portas e deixe os containers falarem entre si através de uma rede Docker comum. O resultado verifica-se melhor a partir de um segundo computador, porque um teste feito no próprio servidor não responde à pergunta decisiva.

Em resumo

Na Debian 12 opte sem hesitar pelo Docker CE; no Ubuntu pode escolher entre o docker.io e o Docker CE. Integre o repositório com um keyring próprio e a impressão digital verificada, não com o apt-key. Utilize o docker compose com espaço. Trate o grupo docker como um acesso root, porque é exatamente isso que ele é. E configure a rotação de logs e um trabalho de prune semanal antes de o servidor falhar pela primeira vez por causa de um disco cheio.

A propósito disto: Configurar a firewall UFW em Debian e Ubuntu e Instalar o Nginx em Debian e Ubuntu.

Perguntas frequentes

Devo instalar o docker.io ou o docker-ce?
No Debian 12, claramente o Docker CE, porque ali o pacote da distribuição está na 20.10.24 e esse ramo já terminou upstream. No Debian 13, o docker.io fornece a 26.1.5; no Ubuntu 24.04 e 22.04 fornece mesmo a 29.1.3, ou seja, praticamente o estado atual. Aí, o pacote da distribuição é uma escolha legítima, desde que instale o Buildx e o Compose à parte. O pacote docker-compose-v2 só existe, no entanto, nas fontes do Ubuntu; na Debian, o caminho para o Compose passa pelo docker-compose-plugin do repositório da Docker.
Porque é que o docker-compose com hífen já não funciona?
O antigo docker-compose era um programa Python autónomo e já não é distribuído. O sucessor é um plugin em Go da CLI do Docker e invoca-se como docker compose, com espaço. Está no pacote docker-compose-plugin (repositório da Docker) ou, apenas no Ubuntu, em docker-compose-v2 da distribuição. Verifique com: docker compose version.
O grupo docker é mesmo tão perigoso como se diz?
Sim. Quem pode aceder ao socket do Docker pode dar ordens arbitrárias ao daemon, que corre como root, por exemplo montar o diretório raiz do anfitrião dentro de um container e abrir aí uma shell de root. A documentação do Docker fala mesmo de root-level privileges. Inclua apenas contas a que confiaria root de qualquer maneira, ou utilize o modo rootless.
Porque é que o docker info me mostra overlayfs em vez de overlay2?
Desde o Docker Engine 29, nas instalações novas vem predefinido o image store do containerd. O seu snapshotter chama-se overlayfs. Isso está correto e não é um erro. Problemático seria apenas o valor vfs, que indica falta de suporte no kernel e consome muitíssimo espaço em disco.
As minhas imagens desapareceram depois de uma atualização, foram apagadas?
Regra geral, não. Ao mudar entre o image store clássico e o image store do containerd, o conteúdo do outro armazenamento fica apenas oculto, os dados permanecem no disco. Volte atrás a título de teste, através de features containerd-snapshotter em /etc/docker/daemon.json, e elas reaparecem.
Como evito que os logs dos containers encham o disco?
O driver json-file não roda por predefinição. Acrescente em /etc/docker/daemon.json a secção log-opts com max-size 10m e max-file 3; os valores têm de estar entre aspas, como cadeias de caracteres. Depois de systemctl restart docker, isso vale apenas para containers criados de novo; os existentes têm de ser recriados com docker compose up -d --force-recreate.
O docker system prune é seguro?
Sem opções, em larga medida sim: remove containers parados, redes não utilizadas, imagens sem nome e a cache de build. A opção -a apaga adicionalmente todas as imagens que não estejam a ser usadas nesse momento. Perigosa é a --volumes, porque com ela desaparecem os volumes nomeados sem container associado, ou seja, possivelmente a sua base de dados. Em trabalhos automáticos, a --volumes nunca deve entrar.

Docker Docker Compose Debian Ubuntu Servidor Linux containerd apt Administração de servidores