Docker · 13 min read · Oct 05, 2025

Como Configurar um Registro Docker Privado no Ubuntu 22.04

Se você está trabalhando para uma organização e deseja manter suas imagens Docker internamente para uma implantação rápida, então hospedar um repositório Docker privado é perfeito. Ter um registro docker privado permite que você possua seu pipeline de distribuição de imagens e tenha um controle mais rigoroso sobre o armazenamento e a distribuição de imagens. Você pode integrar seu registro com seu sistema CI/CD, melhorando seu fluxo de trabalho.

Este tutorial ensinará você a configurar e usar um registro Docker privado em um servidor Ubuntu 22.04 usando o Amazon S3 como local de armazenamento.

Pré-requisitos

  • Dois servidores Linux com Ubuntu 22.04. Um servidor atuará como o host do registro, enquanto o outro será usado como cliente para enviar solicitações e receber imagens do host.
  • Um nome de domínio registrado apontando para o servidor host. Usaremos registry.example.com para nosso tutorial.
  • Um usuário não-root com privilégios sudo em ambas as máquinas.
  • Certifique-se de que tudo está atualizado. $ sudo apt update $ sudo apt upgrade
  • Alguns pacotes que seu sistema precisa. $ sudo apt install wget curl nano software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release ubuntu-keyring unzip -y Alguns desses pacotes podem já estar instalados em seu sistema.

Passo 1 - Configurar o Firewall

O primeiro passo é configurar o firewall. O Ubuntu vem com o ufw (Uncomplicated Firewall) por padrão.

Verifique se o firewall está em execução.

$ sudo ufw status

Você deve obter a seguinte saída.

Status: inactive

Permita a porta SSH para que o firewall não interrompa a conexão atual ao ativá-lo.

$ sudo ufw allow OpenSSH

Permita também as portas HTTP e HTTPS.

$ sudo ufw allow http
$ sudo ufw allow https

Ative o Firewall

$ sudo ufw enable
Comando pode interromper conexões ssh existentes. Prosseguir com a operação (y|n)? y
Firewall está ativo e habilitado na inicialização do sistema

Verifique o status do firewall novamente.

$ sudo ufw status

Você deve ver uma saída semelhante.

Status: active

Para                         Ação      De
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443                        ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

Passo 2 - Instalar Docker e Docker Compose

Este passo é necessário em ambas as máquinas, servidor e cliente.

O Ubuntu 22.04 vem com uma versão mais antiga do Docker. Para instalar a versão mais recente, primeiro, importe a chave GPG do Docker.

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

Crie um arquivo de repositório Docker.

$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Atualize a lista de repositórios do sistema.

$ sudo apt update

Instale a versão mais recente do Docker.

$ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Verifique se está em execução.

$ sudo systemctl status docker
? docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2023-04-13 09:37:09 UTC; 3min 47s ago
TriggeredBy: ? docker.socket
       Docs: https://docs.docker.com
   Main PID: 2106 (dockerd)
      Tasks: 7
     Memory: 26.0M
        CPU: 267ms
     CGroup: /system.slice/docker.service
             ??2106 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Por padrão, o Docker requer privilégios de root. Se você quiser evitar usar sudo toda vez que executar o comando docker, adicione seu nome de usuário ao grupo docker.

$ sudo usermod -aG docker $(whoami)

Você precisará sair do servidor e entrar novamente como o mesmo usuário para habilitar essa alteração ou usar o seguinte comando.

$ su - ${USER}

Confirme que seu usuário foi adicionado ao grupo Docker.

$ groups
navjot wheel docker

Passo 3 - Configurar o Registro Docker

Criar diretórios de usuários

Crie um diretório para a configuração do registro.

$ mkdir ~/docker-registry

Mude para o diretório docker-registry.

$ cd ~/docker-registry

Crie um diretório para armazenar a senha de autenticação HTTP, arquivos de configuração do Nginx e certificados SSL.

$ mkdir auth

Crie outro diretório para armazenar os logs do Nginx.

$ mkdir logs

Criar Bucket Amazon S3

Você pode armazenar os dados do registro e as imagens em seu servidor ou usar um serviço de hospedagem em nuvem. Para nosso tutorial, usaremos o serviço em nuvem Amazon S3.

O próximo passo é configurar o arquivo de configuração com algumas configurações importantes. Essas configurações também podem ser definidas no arquivo docker-compose.yml, mas ter um arquivo separado é muito melhor.

Crie um bucket com as seguintes configurações.

  • ACL deve estar desativado.
  • O acesso público ao bucket deve estar desativado.
  • O versionamento do bucket deve estar desativado.
  • Ative a criptografia do bucket usando chaves gerenciadas pela Amazon S3. (SSE-S3)
  • O bloqueio de objeto deve estar desativado.

Crie um usuário IAM com a seguinte política.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation",
        "s3:ListBucketMultipartUploads"
      ],
      "Resource": "arn:aws:s3:::S3_BUCKET_NAME"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject",
        "s3:DeleteObject",
        "s3:ListMultipartUploadParts",
        "s3:AbortMultipartUpload"
      ],
      "Resource": "arn:aws:s3:::S3_BUCKET_NAME/*"
    }
  ]
}

Substitua S3_BUCKET_NAME pelo nome do seu bucket S3.

Anote a chave secreta, o valor secreto e a região do bucket para serem usados posteriormente.

Criar Arquivo Docker Compose

Crie o arquivo docker-compose.yml e abra-o para edição.

$ nano docker-compose.yml

Cole o seguinte código nele.

services:
  registry:
    image: registry:2
    restart: always
    environment:
      - REGISTRY_STORAGE=s3
      - REGISTRY_STORAGE_S3_REGION=us-west-2
      - REGISTRY_STORAGE_S3_BUCKET=hf-docker-registry
      - REGISTRY_STORAGE_S3_ENCRYPT=true
      - REGISTRY_STORAGE_S3_CHUNKSIZE=5242880
      - REGISTRY_STORAGE_S3_SECURE=true
      - REGISTRY_STORAGE_S3_ACCESSKEY=AKIA3FIG4NVFNXKQXMSJ
      - REGISTRY_STORAGE_S3_SECRETKEY=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
      - REGISTRY_STORAGE_S3_V4AUTH=true
      - REGISTRY_STORAGE_S3_ROOTDIRECTORY=/image-registry
      - REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR=inmemory
      - REGISTRY_HEALTH_STORAGEDRIVER_ENABLED=false
  nginx:
    image: "nginx:alpine"
    ports:
      - 443:443
    links:
      - registry:registry
    volumes:
      - ./auth:/etc/nginx/conf.d
      - ./auth/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./logs:/var/log/nginx
      - /etc/letsencrypt:/etc/letsencrypt

Salve o arquivo pressionando Ctrl + X e digitando Y quando solicitado.

Vamos passar pelo que configuramos em nosso arquivo de composição.

  1. O primeiro passo é pegar a imagem mais recente da versão 2 do registro Docker do hub. Não estamos usando a tag mais recente porque isso pode causar problemas no caso de uma atualização de versão principal. Defini-la como 2 permite que você receba todas as atualizações 2.x enquanto evita ser atualizado automaticamente para a próxima versão principal, que pode introduzir mudanças que quebram a compatibilidade.
  2. O contêiner do registro está configurado para reiniciar sempre em caso de falha ou desligamento inesperado.
  3. Definimos várias variáveis de ambiente para armazenamento Amazon S3. Vamos passar rapidamente por elas. - REGISTRY_STORAGE define o tipo de armazenamento. Selecionamos s3 uma vez que estamos usando o Amazon S3.
  • REGISTRY_STORAGE_S3_REGION define a região do seu bucket S3.
  • REGISTRY_STORAGE_S3_BUCKET define o nome do seu bucket S3.
  • REGISTRY_STORAGE_S3_ENCRYPT - defina como verdadeiro se você ativou a criptografia do bucket.
  • REGISTRY_STORAGE_S3_CHUNKSIZE define o tamanho dos chunks de upload. Deve ser maior que 5MB (5 1024 1024).
  • REGISTRY_STORAGE_S3_SECURE - defina como verdadeiro se você for usar HTTPS.
  • REGISTRY_STORAGE_S3_ACCESSKEY e REGISTRY_STORAGE_S3_SECRETKEY - Credenciais de usuário que você obteve após criar seu usuário IAM.
  • REGISTRY_STORAGE_S3_V4AUTH - defina como verdadeiro se você usar a versão 4 da autenticação AWS. Se você estiver recebendo erros relacionados ao login S3, defina como falso.
  • REGISTRY_STORAGE_S3_ROOTDIRECTORY - define o diretório raiz em seu bucket sob o qual seus dados do registro serão armazenados.
  • REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR - define o local para o Cache. No nosso caso, estamos armazenando na memória. Você também pode configurá-lo para usar o Redis.
  • REGISTRY_HEALTH_STORAGEDRIVER_ENABLED - Defina como falso para desativar o serviço de verificação de saúde de armazenamento do Registro. Há um bug no Registro que pode causar problemas se você não defini-lo como falso.
  1. O registro Docker se comunica pela porta 5000, que é o que expomos em nosso servidor para o docker.
  2. ./auth:/etc/nginx/conf.d garante que todas as configurações do Nginx estejam disponíveis no contêiner.
  3. ./auth/nginx.conf:/etc/nginx/nginx.conf:ro mapeia o arquivo de configurações do Nginx do sistema para um no contêiner em modo somente leitura.
  4. ./logs:/var/log/nginx permite o acesso aos logs do Nginx no sistema mapeando para o diretório de logs do Nginx no contêiner.
  5. As configurações do registro Docker são armazenadas no arquivo /etc/docker/registry/config.yml no contêiner, e nós o mapeamos para o arquivo config.yml no diretório atual, que criaremos no próximo passo.

Configurar Autenticação

Para configurar a autenticação HTTP, você precisa instalar o pacote httpd-tools.

$ sudo apt install apache2-utils -y

Crie o arquivo de senha no diretório ~/docker-registry/auth.

$ htpasswd -Bc ~/docker-registry/auth/nginx.htpasswd user1
Nova senha:
Re-digite a nova senha:
Adicionando senha para o usuário user1

A flag -c instrui o comando a criar um novo arquivo, e a flag -B é para usar o algoritmo bcrypt suportado pelo Docker. Substitua user1 por um nome de usuário de sua escolha.

Se você quiser adicionar mais usuários, execute o comando novamente, mas sem a flag -c.

$ htpasswd -B ~/docker-registry/auth/registry.password user2

Agora, o arquivo será mapeado para o contêiner do registro para autenticação.

Passo 4 - Instalar SSL

Precisamos instalar o Certbot para gerar o certificado SSL. Você pode instalar o Certbot usando o repositório do Ubuntu ou pegar a versão mais recente usando a ferramenta Snapd. Usaremos a versão Snapd.

O Ubuntu 22.04 vem com o Snapd instalado por padrão. Execute os seguintes comandos para garantir que sua versão do Snapd esteja atualizada.

$ sudo snap install core && sudo snap refresh core

Instale o Certbot.

$ sudo snap install --classic certbot

Use o seguinte comando para garantir que o comando Certbot possa ser executado criando um link simbólico para o diretório /usr/bin.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Execute o seguinte comando para gerar um Certificado SSL.

$ sudo certbot certonly --standalone --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d registry.example.com

O comando acima fará o download de um certificado para o diretório /etc/letsencrypt/live/registry.example.com em seu servidor.

Gere um certificado de grupo Diffie-Hellman.

$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096

Verifique o serviço agendador de renovação do Certbot.

$ sudo systemctl list-timers

Você encontrará snap.certbot.renew.service como um dos serviços agendados para execução.

PRÓXIMO                        RESTANTE          ÚLTIMO                        PASSADO        UNIDADE                      ATIVA
.....
Dom 2023-04-14 00:00:00 UTC 19min restante    Sáb 2023-02-25 18:04:05 UTC n/a          snap.certbot.renew.timer  snap.certbot.renew.service
Dom 2023-04-14 00:00:20 UTC 19min restante    Sáb 2023-02-25 10:49:23 UTC 14h atrás      apt-daily-upgrade.timer   apt-daily-upgrade.service
Dom 2023-04-14 00:44:06 UTC 3h 22min restante Sáb 2023-02-25 20:58:06 UTC 7h atrás       apt-daily.timer           apt-daily.service

Faça um teste do processo para verificar se a renovação do SSL está funcionando bem.

$ sudo certbot renew --dry-run

Se você não ver erros, está tudo pronto. Seu certificado será renovado automaticamente.

Copiar o arquivo Dhparam para o contêiner

Copie o certificado de grupo Diffie-Hellman para o diretório ~/docker-registry/auth, que será mapeado para o contêiner.

$ sudo cp /etc/ssl/certs/dhparam.pem ~/docker-registry/auth

Passo 5 - Configurar Nginx

O próximo passo envolve configurar o servidor Nginx como um proxy frontal para o servidor de registro Docker. O registro Docker vem com um servidor embutido operando na porta 5000. Vamos colocá-lo atrás do Nginx.

Crie e abra o arquivo ~/docker-registry/auth/nginx.conf para edição.

$ sudo nano ~/docker-registry/auth/nginx.conf

Cole o seguinte código nele.

events {
    worker_connections  1024;
}

http {

  upstream docker-registry {
    server registry:5000;
  }

  ## Defina uma variável para nos ajudar a decidir se precisamos adicionar o
  ## cabeçalho 'Docker-Distribution-Api-Version'.
  ## O registro sempre define esse cabeçalho.
  ## No caso do nginx realizar autenticação, o cabeçalho é desconfigurado
  ## uma vez que o nginx está autenticando antes de fazer o proxy.
  map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
    '' 'registry/2.0';
  }

  server {
    listen 443 ssl http2;
    server_name registry.example.com;

    # SSL
    ssl_certificate /etc/letsencrypt/live/registry.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/registry.example.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/registry.example.com/chain.pem;

    access_log  /var/log/nginx/registry.access.log;
    error_log   /var/log/nginx/registry.error.log;

    # Recomendações de https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers on;
    ssl_ecdh_curve X25519:prime256v1:secp384r1:secp521r1;
    ssl_session_cache shared:SSL:10m;
    ssl_dhparam /etc/nginx/conf.d/dhparam.pem;
    resolver 8.8.8.8;

    # desabilitar quaisquer limites para evitar HTTP 413 para uploads de imagem grandes
    client_max_body_size 0;

    # necessário para evitar HTTP 411: veja o Problema #1486 (https://github.com/moby/moby/issues/1486)
    chunked_transfer_encoding on;

    location /v2/ {
      # Não permitir conexões do docker 1.5 e anteriores
      # docker pré-1.6.0 não definiu corretamente o agente do usuário no ping, capture "Go *" agentes de usuário
      if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
        return 404;
      }

      # Para adicionar autenticação básica ao v2 use a configuração auth_basic.
      auth_basic "Realm do Registro";
      auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;

      ## Se $docker_distribution_api_version estiver vazio, o cabeçalho não é adicionado.
      ## Veja a diretiva map acima onde essa variável é definida.
      add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;

      proxy_pass                          http://docker-registry;
      proxy_set_header  Host              $http_host;   # necessário para o cliente docker
      proxy_set_header  X-Real-IP         $remote_addr; # passar o IP real do cliente
      proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
      proxy_set_header  X-Forwarded-Proto $scheme;
      proxy_read_timeout                  900;
    }
  }
}

Salve o arquivo pressionando Ctrl + X e digitando Y quando solicitado ao terminar.

Passo 6 - Iniciar o Registro Docker

Mude para o diretório do Registro Docker.

$ cd ~/docker-registry

Inicie o contêiner docker.

$ docker compose up -d

Verifique o status dos contêineres.

$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS              PORTS                                      NAMES
3328b7e36bb2   nginx:alpine   "/docker-entrypoint.…"   About a minute ago   Up 3 seconds        80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp   docker-registry-nginx-1
bf7cdfc0e013   registry:2     "/entrypoint.sh /etc…"   About a minute ago   Up About a minute   5000/tcp                                 docker-registry-registry-1

Faça login no registro Docker.

$ docker login -u=user1 -p=password https://registry.example.com

Você receberá a seguinte saída.

AVISO! Usando --password via CLI é inseguro. Use --password-stdin.
AVISO! Sua senha será armazenada sem criptografia em /home/username/.docker/config.json.
Configure um auxiliar de credenciais para remover este aviso. Veja
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Sucedido

Você também pode abrir a URL https://registry.example.com/v2/ em seu navegador, e ele pedirá um nome de usuário e senha. Você deve ver uma página vazia com {} nela.

Você pode verificar a URL no terminal usando curl.

$ curl -u user1 -X GET https://registry.example.com/v2/
Digite a senha do host para o usuário 'user1':
{}

Baixe a imagem Docker mais recente do Ubuntu.

$ docker pull ubuntu:latest

Marque esta imagem para o registro privado.

$ docker tag ubuntu:latest registry.example.com/ubuntu2204

Envie a imagem para o registro.

$ docker push registry.example.com/ubuntu2204

Teste se o envio foi bem-sucedido.

$ curl -u user1 -X GET https://registry.example.com/v2/_catalog
Digite a senha do host para o usuário 'user1':
{"repositories":["ubuntu2204"]}

Digite sua senha de autenticação do Nginx quando solicitado, e você verá a lista de repositórios disponíveis via o registro.

Faça logout usando o terminal para limpar as credenciais.

$ docker logout https://registry.example.com
Removendo credenciais de login para registry.example.com

Verifique a lista de imagens Docker atualmente disponíveis para uso.

$ docker images
REPOSITORY                            TAG       IMAGE ID       CREATED       SIZE
registry                             2         8db46f9d7550   2 weeks ago   24.2MB
nginx                                alpine    8e75cbc5b25c   2 weeks ago   41MB
ubuntu                               latest    08d22c0ceb15   5 weeks ago   77.8MB
registry.example.com/ubuntu2204      latest    08d22c0ceb15   5 weeks ago   77.8MB

Passo 7 - Acessar e Usar o registro Docker a partir da Máquina Cliente

Faça login no seu servidor cliente. No passo 1, instalamos o Docker na máquina cliente.

Faça login no registro Docker privado a partir da máquina cliente.

$ docker login -u=user1 -p=password https://registry.example.com

Baixe a imagem do Ubuntu do registro.

$ docker pull registry.example.com/ubuntu2204

Liste todas as imagens na sua máquina cliente.

$ docker images
REPOSITORY                        TAG        IMAGE ID       CREATED         SIZE
registry.example.com/ubuntu2204   latest     08d22c0ceb15   5 weeks ago   77.8MB

Crie e inicie um contêiner usando a imagem baixada.

$ docker run -it registry.example.com/ubuntu2204 /bin/bash

Você estará logado no Shell dentro do contêiner Ubuntu.

root@647899f255db:

Execute o seguinte comando para verificar a versão do Linux.

root@a2da49fdbea9$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.2 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.2 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

Agora, você pode começar a usar seu registro Docker a partir de suas máquinas clientes.

Conclusão

Isso conclui nosso tutorial sobre como configurar um registro Docker privado em um servidor Ubuntu 22.04 que usa o Amazon S3 como armazenamento. Se você tiver alguma dúvida, poste nos comentários abaixo.

Share: X/Twitter LinkedIn

Receba novas postagens na sua caixa de entrada

Sem spam. Cancele a assinatura a qualquer momento.