Docker Registry · 12 min read · Oct 05, 2025

Come impostare un registro Docker privato su Ubuntu 22.04

Se lavori per un’organizzazione e vuoi mantenere le tue immagini Docker interne per un rapido deployment, allora ospitare un repository Docker privato è perfetto. Avere un registro Docker privato ti consente di possedere la tua pipeline di distribuzione delle immagini e avere un controllo più stretto sullo storage e la distribuzione delle immagini. Puoi integrare il tuo registro con il tuo sistema CI/CD migliorando il tuo flusso di lavoro.

Questo tutorial ti insegnerà come impostare e utilizzare un registro Docker privato su un server Ubuntu 22.04 utilizzando Amazon S3 come posizione di archiviazione.

Prerequisiti

  • Due server Linux con Ubuntu 22.04. Un server fungerà da host del registro, mentre l’altro sarà utilizzato come client per inviare richieste e ricevere immagini dall’host.
  • Un nome di dominio registrato che punta al server host. Useremo registry.example.com per il nostro tutorial.
  • Un utente non root con privilegi sudo su entrambe le macchine.
  • Assicurati che tutto sia aggiornato. $ sudo apt update $ sudo apt upgrade
  • Alcuni pacchetti di cui il tuo sistema ha bisogno. $ sudo apt install wget curl nano software-properties-common dirmngr apt-transport-https gnupg2 ca-certificates lsb-release ubuntu-keyring unzip -y Alcuni di questi pacchetti potrebbero già essere installati sul tuo sistema.

Passo 1 - Configurare il Firewall

Il primo passo è configurare il firewall. Ubuntu viene fornito di default con ufw (Uncomplicated Firewall).

Controlla se il firewall è attivo.

$ sudo ufw status

Dovresti ottenere il seguente output.

Status: inactive

Consenti la porta SSH in modo che il firewall non interrompa la connessione attuale quando viene abilitato.

$ sudo ufw allow OpenSSH

Consenti anche le porte HTTP e HTTPS.

$ sudo ufw allow http
$ sudo ufw allow https

Abilita il Firewall

$ sudo ufw enable
Il comando potrebbe interrompere le connessioni ssh esistenti. Procedere con l'operazione (y|n)? y
Il firewall è attivo e abilitato all'avvio del sistema

Controlla di nuovo lo stato del firewall.

$ sudo ufw status

Dovresti vedere un output simile.

Status: active

To                         Action      From
--                         ------      ----
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 - Installare Docker e Docker Compose

Questo passaggio è necessario su entrambe le macchine, server e client.

Ubuntu 22.04 viene fornito con una versione più vecchia di Docker. Per installare l’ultima versione, prima importa la chiave GPG di Docker.

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

Crea un file di repository 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

Aggiorna l’elenco dei repository di sistema.

$ sudo apt update

Installa l’ultima versione di Docker.

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

Verifica che sia in esecuzione.

$ 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

Per impostazione predefinita, Docker richiede privilegi di root. Se vuoi evitare di usare sudo ogni volta che esegui il comando docker, aggiungi il tuo nome utente al gruppo docker.

$ sudo usermod -aG docker $(whoami)

Dovrai disconnetterti dal server e riconnetterti come lo stesso utente per abilitare questa modifica o usare il seguente comando.

$ su - ${USER}

Conferma che il tuo utente sia stato aggiunto al gruppo Docker.

$ groups
navjot wheel docker

Passo 3 - Configurare il Registro Docker

Crea directory utente

Crea una directory per la configurazione del registro.

$ mkdir ~/docker-registry

Passa alla directory docker-registry.

$ cd ~/docker-registry

Crea una directory per memorizzare la password di autenticazione HTTP, i file di configurazione di Nginx e i certificati SSL.

$ mkdir auth

Crea un’altra directory per memorizzare i log di Nginx.

$ mkdir logs

Crea un Bucket Amazon S3

Puoi memorizzare i dati del registro e le immagini sul tuo server o utilizzare un servizio di hosting cloud. Per il nostro tutorial, utilizzeremo il servizio cloud Amazon S3.

Il passo successivo è impostare il file di configurazione con alcune impostazioni importanti. Queste impostazioni possono anche essere definite nel file docker-compose.yml, ma avere un file separato è molto meglio.

Crea un bucket con le seguenti impostazioni.

  • L’ACL dovrebbe essere disabilitato.
  • L’accesso pubblico al bucket dovrebbe essere disabilitato.
  • La versioning del bucket dovrebbe essere disabilitata.
  • Abilita la crittografia del bucket utilizzando le chiavi gestite da Amazon S3. (SSE-S3)
  • Il blocco degli oggetti dovrebbe essere disabilitato.

Crea un utente IAM con la seguente policy.

{
  "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/*"
    }
  ]
}

Sostituisci S3_BUCKET_NAME con il nome del tuo bucket S3.

Annota la chiave segreta, il valore segreto e la regione del bucket da utilizzare in seguito.

Crea il file Docker Compose

Crea il file docker-compose.yml e aprilo per la modifica.

$ nano docker-compose.yml

Incolla il seguente codice in esso.

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

Salva il file premendo Ctrl + X e inserendo Y quando richiesto.

Esaminiamo cosa abbiamo impostato nel nostro file di composizione.

  1. Il primo passo è prendere l’ultima immagine della versione 2 del registro Docker dall’hub. Non stiamo usando il tag latest perché potrebbe causare problemi in caso di un aggiornamento di versione principale. Impostarlo su 2 ti consente di ottenere tutti gli aggiornamenti 2.x mentre previene l’aggiornamento automatico alla prossima versione principale, che può introdurre cambiamenti incompatibili.
  2. Il contenitore del registro è impostato per riavviarsi sempre in caso di guasto o spegnimento imprevisto.
  3. Abbiamo impostato varie variabili ambientali per l’archiviazione Amazon S3. Esaminiamole rapidamente. - REGISTRY_STORAGE imposta il tipo di archiviazione. Abbiamo selezionato s3 poiché stiamo usando Amazon S3.
  • REGISTRY_STORAGE_S3_REGION imposta la regione del tuo bucket S3.
  • REGISTRY_STORAGE_S3_BUCKET imposta il nome del tuo bucket S3.
  • REGISTRY_STORAGE_S3_ENCRYPT - impostalo su true se hai abilitato la crittografia del bucket.
  • REGISTRY_STORAGE_S3_CHUNKSIZE imposta la dimensione dei chunk di upload. Dovrebbe essere maggiore di 5MB (5 1024 1024).
  • REGISTRY_STORAGE_S3_SECURE - impostalo su true se intendi utilizzare HTTPS.
  • REGISTRY_STORAGE_S3_ACCESSKEY e REGISTRY_STORAGE_S3_SECRETKEY - Credenziali utente che hai ottenuto dopo aver creato il tuo utente IAM.
  • REGISTRY_STORAGE_S3_V4AUTH - impostalo su true se utilizzi v4 dell’autenticazione AWS. Se ricevi errori relativi al login S3, impostalo su false.
  • REGISTRY_STORAGE_S3_ROOTDIRECTORY - imposta la directory radice nel tuo bucket sotto la quale verranno memorizzati i dati del tuo registro.
  • REGISTRY_STORAGE_CACHE_BLOBDESCRIPTOR - imposta la posizione per la Cache. Nel nostro caso, lo stiamo memorizzando in memoria. Puoi anche impostarlo per utilizzare Redis.
  • REGISTRY_HEALTH_STORAGEDRIVER_ENABLED - impostalo su false per disabilitare il servizio di controllo della salute dello storage del Registro. C’è un bug con il Registro che può causare problemi se non lo imposti su false.
  1. Il registro Docker comunica tramite la porta 5000, che è quella che abbiamo esposto nel nostro server al docker.
  2. ./auth:/etc/nginx/conf.d mapping garantisce che tutte le impostazioni di Nginx siano disponibili nel contenitore.
  3. ./auth/nginx.conf:/etc/nginx/nginx.conf:ro mappa il file delle impostazioni di Nginx dal sistema a quello nel contenitore in modalità di sola lettura.
  4. ./logs:/var/log/nginx consente l’accesso ai log di Nginx sul sistema mappando alla directory dei log di Nginx nel contenitore.
  5. Le impostazioni del registro Docker sono memorizzate nel file /etc/docker/registry/config.yml nel contenitore, e lo abbiamo mappato al file config.yml nella directory corrente, che creeremo nel passaggio successivo.

Imposta l’autenticazione

Per impostare l’autenticazione HTTP, devi installare il pacchetto httpd-tools.

$ sudo apt install apache2-utils -y

Crea il file di password nella directory ~/docker-registry/auth.

$ htpasswd -Bc ~/docker-registry/auth/nginx.htpasswd user1
Nuova password:
Re-inserisci la nuova password:
Aggiunta password per l'utente user1

Il flag -c istruisce il comando a creare un nuovo file, e il flag -B è per utilizzare l’algoritmo bcrypt supportato da Docker. Sostituisci user1 con un nome utente a tua scelta.

Se vuoi aggiungere più utenti, esegui di nuovo il comando, ma senza il flag -c.

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

Ora, il file sarà mappato al contenitore del registro per l’autenticazione.

Passo 4 - Installare SSL

Dobbiamo installare Certbot per generare il certificato SSL. Puoi installare Certbot utilizzando il repository di Ubuntu o ottenere l’ultima versione utilizzando lo strumento Snapd. Useremo la versione Snapd.

Ubuntu 22.04 viene fornito con Snapd installato di default. Esegui i seguenti comandi per assicurarti che la tua versione di Snapd sia aggiornata.

$ sudo snap install core && sudo snap refresh core

Installa Certbot.

$ sudo snap install --classic certbot

Usa il seguente comando per assicurarti che il comando Certbot possa essere eseguito creando un collegamento simbolico alla directory /usr/bin.

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

Esegui il seguente comando per generare un certificato SSL.

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

Il comando sopra scaricherà un certificato nella directory /etc/letsencrypt/live/registry.example.com sul tuo server.

Genera un certificato di gruppo Diffie-Hellman.

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

Controlla il servizio di pianificazione del rinnovo di Certbot.

$ sudo systemctl list-timers

Troverai snap.certbot.renew.service come uno dei servizi programmati per l’esecuzione.

NEXT                        LEFT          LAST                        PASSED        UNIT                      ACTIVATES
.....
Sun 2023-04-14 00:00:00 UTC 19min left    Sat 2023-02-25 18:04:05 UTC n/a          snap.certbot.renew.timer  snap.certbot.renew.service
Sun 2023-04-14 00:00:20 UTC 19min left    Sat 2023-02-25 10:49:23 UTC 14h ago      apt-daily-upgrade.timer   apt-daily-upgrade.service
Sun 2023-04-14 00:44:06 UTC 3h 22min left Sat 2023-02-25 20:58:06 UTC 7h ago       apt-daily.timer           apt-daily.service

Fai un tentativo di prova del processo per controllare se il rinnovo SSL funziona correttamente.

$ sudo certbot renew --dry-run

Se non vedi errori, sei a posto. Il tuo certificato si rinnoverà automaticamente.

Copia il file Dhparam nel contenitore

Copia il certificato di gruppo Diffie-Hellman nella directory ~/docker-registry/auth, che sarà mappata al contenitore.

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

Passo 5 - Configurare Nginx

Il passo successivo comporta la configurazione del server Nginx come proxy front-end per il server del registro Docker. Il registro Docker viene fornito con un server integrato che opera sulla porta 5000. Lo metteremo dietro Nginx.

Crea e apri il file ~/docker-registry/auth/nginx.conf per la modifica.

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

Incolla il seguente codice in esso.

events {
    worker_connections  1024;
}

http {

  upstream docker-registry {
    server registry:5000;
  }

  ## Imposta una variabile per aiutarci a decidere se dobbiamo aggiungere il
  ## header 'Docker-Distribution-Api-Version'.
  ## Il registro imposta sempre questo header.
  ## Nel caso di nginx che esegue l'autenticazione, l'header è disattivato
  ## poiché nginx sta autenticando prima di fare il 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;

    # Raccomandazioni da 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;

    # disabilita eventuali limiti per evitare HTTP 413 per upload di immagini grandi
    client_max_body_size 0;

    # necessario per evitare HTTP 411: vedere il problema #1486 (https://github.com/moby/moby/issues/1486)
    chunked_transfer_encoding on;

    location /v2/ {
      # Non consentire connessioni da docker 1.5 e precedenti
      # docker pre-1.6.0 non impostava correttamente l'agente utente su ping, cattura "Go *" agenti utente
      if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
        return 404;
      }

      # Per aggiungere l'autenticazione di base a v2 usa l'impostazione auth_basic.
      auth_basic "Registry realm";
      auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;

      ## Se $docker_distribution_api_version è vuoto, l'header non viene aggiunto.
      ## Vedi la direttiva map sopra dove questa variabile è definita.
      add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;

      proxy_pass                          http://docker-registry;
      proxy_set_header  Host              $http_host;   # necessario per il bene del client docker
      proxy_set_header  X-Real-IP         $remote_addr; # passa l'IP reale del client
      proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
      proxy_set_header  X-Forwarded-Proto $scheme;
      proxy_read_timeout                  900;
    }
  }
}

Salva il file premendo Ctrl + X e inserendo Y quando richiesto una volta terminato.

Passo 6 - Avviare il Registro Docker

Passa alla directory del Registro Docker.

$ cd ~/docker-registry

Avvia il contenitore docker.

$ docker compose up -d

Controlla lo stato dei contenitori.

$ 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

Accedi al registro Docker.

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

Riceverai il seguente output.

WARNING! Using --password via the CLI is insecure. Use --password-stdin.
WARNING! Your password will be stored unencrypted in /home/username/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

Puoi anche aprire l’URL https://registry.example.com/v2/ nel tuo browser, e ti verrà chiesto un nome utente e una password. Dovresti vedere una pagina vuota con {} su di essa.

Puoi controllare l’URL nel terminale usando curl.

$ curl -u user1 -X GET https://registry.example.com/v2/
Inserisci la password dell'host per l'utente 'user1':
{}

Scarica l’ultima immagine di Ubuntu.

$ docker pull ubuntu:latest

Tagga questa immagine per il registro privato.

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

Invia l’immagine al registro.

$ docker push registry.example.com/ubuntu2204

Verifica se l’invio è stato effettuato con successo.

$ curl -u user1 -X GET https://registry.example.com/v2/_catalog
Inserisci la password dell'host per l'utente 'user1':
{"repositories":["ubuntu2204"]}

Inserisci la tua password di autenticazione Nginx quando richiesto, e vedrai l’elenco dei repository disponibili tramite il registro.

Disconnettiti usando il terminale per cancellare le credenziali.

$ docker logout https://registry.example.com
Rimozione delle credenziali di accesso per registry.example.com

Controlla l’elenco delle immagini Docker attualmente disponibili per l’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 - Accedere e utilizzare il registro Docker dalla macchina client

Accedi al tuo server client. Nel passo 1, abbiamo installato Docker sulla macchina client.

Accedi al registro Docker privato dalla macchina client.

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

Scarica l’immagine di Ubuntu dal registro.

$ docker pull registry.example.com/ubuntu2204

Elenca tutte le immagini sulla tua macchina client.

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

Crea e avvia un contenitore utilizzando l’immagine scaricata.

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

Sarai connesso alla Shell all’interno del contenitore Ubuntu.

root@647899f255db:

Esegui il seguente comando per controllare la versione di 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

Ora puoi iniziare a utilizzare il tuo registro Docker dalle tue macchine client.

Conclusione

Questo conclude il nostro tutorial su come impostare un registro Docker privato su un server Ubuntu 22.04 che utilizza Amazon S3 come archiviazione. Se hai domande, postale nei commenti qui sotto.

Share: X/Twitter LinkedIn

Ricevi i nuovi post nella tua casella di posta.

Nessuno spam. Disiscriviti in qualsiasi momento.