Condividi tramite


Esercitazione: Creare applicazioni multi-contenitore con MySQL e Docker Compose

Questo articolo descrive come creare app multi-contenitore con mySQL e Docker Compose. Un'app con più contenitori consente di dedicare contenitori per attività specializzate, in modo che ogni contenitore possa concentrarsi su una singola attività. L'uso di app multi-contenitore offre molti vantaggi:

  • I contenitori separati consentono di gestire le API e le risorse front-end in modo diverso rispetto ai database.
  • Più contenitori consentono di eseguire la versione e aggiornare le versioni in isolamento.
  • I database locali possono essere gestiti in contenitori e servizi gestiti usati per i database nell'ambiente di produzione.
  • Le app multi-contenitore sono più efficienti rispetto all'esecuzione di più processi con un gestore di processi, che aggiunge complessità all'avvio/arresto del contenitore.

In questa guida, tu:

  • Avvia MySQL
  • Esegui l'app multi-contenitore con MySQL
  • Creare un file Docker Compose per l'app
  • Eseguire lo stack di applicazioni con Docker Compose

Prerequisiti

  • Questo articolo fa parte di una serie di esercitazioni. Le procedure si basano su un esempio stabilito che richiede Docker Desktop per i contenitori Linux.

    L'approccio consigliato è di completare la prima esercitazione, Creare un'app contenitore, soddisfacendo i prerequisiti, e anche di seguire l'esercitazione Rendere persistenti i dati nell'app. Dopo aver eseguito queste esercitazioni, continuare con le procedure descritte in questo articolo.

  • L'esempio in questo articolo usa Docker Compose.

    Docker Desktop per Windows include Docker Compose.

    Eseguire il comando seguente per verificare l'installazione di Docker:

    docker-compose version
    

Visual Studio Code

Questa serie di esercitazioni descrive le procedure per Visual Studio Code (VS Code). Esaminare le considerazioni seguenti per lavorare in questo ambiente:

  • Usare il menu a sinistra per passare dalla visualizzazione ESPLORA CONTENITORI o EXPLORER (file e cartelle):

    Screenshot che mostra la visualizzazione Esplora contenitori e Esplora file/cartelle in Visual Studio Code.

  • Aprire una finestra della riga di comando in VS Code selezionando Terminale>Nuovo terminale. È anche possibile usare i tasti di scelta rapida CTRL+MAIUSC+` (segno di graduazione indietro).

  • Se non diversamente specificato, eseguire i comandi in una finestra Bash. La maggior parte dei comandi etichettati per Bash vengono eseguiti in una finestra Bash o nella finestra della riga di comando di VS Code.

Avviare il sistema di gestione del database MySQL

Per impostazione predefinita, i contenitori vengono eseguiti in isolamento. Un contenitore non è a conoscenza di altri processi o di altri contenitori nello stesso computer.

Per abilitare la comunicazione tra contenitori, è necessario collegarsi alla stessa rete. Più contenitori nella stessa rete possono condividere dati ed elaborare informazioni tra loro.

Esistono due modi per collegare un contenitore a una rete. È possibile collegare un contenitore a una rete durante la creazione o collegare un contenitore esistente a una rete in un secondo momento.

In questo esempio si crea la rete e si collega il contenitore MySQL all'avvio.

  1. Creare una rete denominata todo-app:

    docker network create todo-app
    
  2. Avviare un contenitore MySQL denominato todo-mysql-data e collegarlo alla rete todo-app. Il comando crea un alias di rete mysql per il database MySQL todos.

    Quando si esegue il comando, immettere la password root di MySQL per il segnaposto <your-password>.

    docker run -d --network todo-app --network-alias mysql -v todo-mysql-data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=<your-password> -e MYSQL_DATABASE=todos mysql:lts
    

    Questo comando definisce anche le variabili di ambiente MYSQL_ROOT_PASSWORD e MYSQL_DATABASE. Per altre informazioni, vedere elenco su Docker Hub di MySQL.

    Avvertimento

    Questa esercitazione illustra le credenziali delle password per l'autenticazione con un database MySQL, che non è il metodo più sicuro. Per altre informazioni sui metodi di autenticazione più sicuri, vedere la documentazione di MySQL.

  3. Ottenere l'ID contenitore da usare nel passaggio successivo.

    docker ps
    
  4. Verificare che sia possibile connettersi al contenitore nella rete mysql.

    Quando si esegue il comando, immettere l'ID del contenitore per il segnaposto <mysql-container-id>.

    docker exec -it <mysql-container-id> mysql -p
    

    Al prompt immettere la password specificata al momento della creazione del contenitore todo-mysql-data.

  5. Nella shell MySQL elencare i database e verificare che venga visualizzato il database todos.

    SHOW DATABASES;
    

    Verrà visualizzato l'output seguente:

    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    | todos              |
    +--------------------+
    5 rows in set (0.00 sec)
    
  6. Per terminare la connessione e tornare al prompt della riga di comando, immettere exit.

Esegui la tua app con MySQL

L'app todo supporta l'impostazione di determinate variabili di ambiente per specificare le impostazioni di connessione mySQL. Nella tabella seguente sono elencate le variabili supportate e i valori usati nell'esempio presentato in questa sezione.

Nome variabile Valore di esempio Descrizione
MYSQL_HOST mysql Nome host per il server MySQL.
MYSQL_USER root Nome utente da usare per la connessione.
MYSQL_PASSWORD <your-password> Password da utilizzare per la connessione. In questo esempio sostituire la password di root con il segnaposto <your-password>.
MYSQL_DATABASE todos Nome del database da utilizzare dopo che è stata stabilita la connessione.

Avvertimento

L'uso delle variabili di ambiente per impostare le impostazioni di connessione è accettabile per lo sviluppo, ma questa procedura non è consigliata per l'esecuzione di applicazioni nell'ambiente di produzione. Per altre informazioni, vedere Perché non è consigliabile usare le variabili di ambiente per i dati segreti.

Un meccanismo più sicuro consiste nell'usare il supporto segreto fornito dal framework di orchestrazione dei contenitori. Nella maggior parte dei casi, questi segreti vengono montati come file nel contenitore in esecuzione.

Nell'esempio seguente si avvia l'app e si connette il contenitore dell'app al contenitore MySQL.

  1. Eseguire il comando docker seguente. Si noti che il comando specifica le variabili di ambiente descritte in precedenza.

    Quando si esegue il comando, ricordarsi di immettere la password di root di MySQL per il segnaposto <your-password>.

    docker run -dp 3000:3000 -w /app -v ${PWD}:/app --network todo-app -e MYSQL_HOST=mysql -e MYSQL_USER=root -e MYSQL_PASSWORD=<your-password> -e MYSQL_DB=todos node:lts-alpine sh -c "yarn install && yarn run dev"
    
  2. Nell'editor di VS Code aprire Esplora contenitori, fare clic con il pulsante destro del mouse sul contenitore dell'app e selezionare Visualizza log.

    È anche possibile visualizzare i log dalla riga di comando usando il comando docker logs.

  3. Esaminare l'output del log. Si noti la riga che indica che l'app è connessa al database MySQL: Connected to mysql db at host mysql.

    # Previous log messages omitted
    $ nodemon src/index.js
    [nodemon] 1.19.2
    [nodemon] to restart at any time, enter `rs`
    [nodemon] watching dir(s): *.*
    [nodemon] starting `node src/index.js`
    Connected to mysql db at host mysql
    Listening on port 3000
    
  4. Nel browser internet, vai alla tua applicazione in esecuzione: http://localhost:3000.

  5. Nell'applicazione in esecuzione aggiungere alcuni elementi all'elenco todo.

  6. Connettersi al database del contenitore MySQL nella rete mysql in modo da poter controllare il database.

    Quando si esegue il comando, immettere l'ID del contenitore per il segnaposto <mysql-container-id>.

    docker exec -ti <mysql-container-id> mysql -p todos
    

    Al prompt immettere la password specificata al momento della creazione del contenitore todo-mysql-data.

  7. Nella shell MySQL verificare che il todo_items aggiunto sia scritto nel database todos.

    use todos;
    select * from todo_items;
    

    L'output dovrebbe essere simile all'esempio seguente:

    +--------------------------------------+--------------------+-----------+
    | id                                   | name               | completed |
    +--------------------------------------+--------------------+-----------+
    | c906ff08-60e6-44e6-8f49-ed56a0853e85 | Do amazing things! |         0 |
    | 2912a79e-8486-4bc3-a4c5-460793a575ab | Be awesome!        |         0 |
    +--------------------------------------+--------------------+-----------+
    

È ora disponibile un'applicazione che archivia i dati in un database esterno in esecuzione in un contenitore separato. Questa procedura illustra come abilitare la comunicazione tra contenitori usando la rete.

Creare un file Docker Compose

Docker Compose consente di definire e condividere applicazioni multi-contenitore. Un file Docker Compose può specificare tutti i servizi necessari, in modo da poter avviare o terminare tutti i processi correlati con un singolo comando. È possibile definire lo stack di applicazioni in un file Docker Compose nella radice del repository del progetto e mantenere la configurazione sotto il controllo della versione. Questo approccio consente ad altri utenti di contribuire al progetto quando clonano il repository.

Nell'esempio seguente viene configurato un file Docker Compose per l'applicazione multi-contenitore todo.

  1. Nella radice del progetto di app todo creare un file Docker Compose denominato docker-compose.yml.

    Nota

    Per impostazione predefinita, la versione dello schema YAML è impostata sulla versione più recente. Quando si esegue l'app, se la versione dello schema è obsoleta, viene visualizzato un messaggio di avviso. Per esaminare le versioni correnti dello schema e una matrice di compatibilità, vedere la panoramica (file di composizione).

  2. Nel file docker-compose.yml aggiungere gli elementi seguenti. Specifica la tua app name e inizia a elencare i services (o container) che desideri eseguire come parte della tua applicazione.

    name: todo
    
    services:
    

    L'elenco dei servizi è univoco per la tua app. Gli esempi includono app, web, db, proxye così via. Si estende la definizione per l'elemento services in un passaggio successivo.

    Consiglio

    Il rientro è significativo nei file .yml e. Se si sta modificando in VS Code, IntelliSense indica eventuali errori nel formato o nella sintassi.

  3. Tornare alla definizione di services nel file di docker-compose.yml. Estendere la definizione aggiungendo una voce per definire l'elemento del servizio app, che include l'immagine per il contenitore.

    services:
      app:
        image: node:lts-alpine
    

    È possibile selezionare qualsiasi nome per il servizio. Il nome diventa automaticamente un alias di rete, utile quando si definisce il servizio MySQL.

  4. Estendere la definizione dell'elemento app per specificare un command da eseguire.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
    
  5. Definire il ports da usare con il servizio app. Si noti che queste porte corrispondono all'argomento -p 3000:3000 per il comando usato per eseguire l'app con MySQL.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
    
  6. Identificare la directory di lavoro working_dir per il servizio app e anche il volumesmappato.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
    

    Quando si definiscono volumi Docker Compose, è possibile usare percorsi relativi in base alla directory corrente.

  7. Specificare le definizioni di variabili environment da usare nell'eseguire comandi per il servizio app.

      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
        environment:
          MYSQL_HOST: mysql
          MYSQL_USER: root
          MYSQL_PASSWORD: <your-password>
          MYSQL_DB: todos
    

    Ricorda di inserire la password di root di MySQL per il segnaposto <your-password>.

  8. Aggiungere la definizione per il servizio MySQL mysql dopo la definizione del servizio app. Specificare i nomi e i valori degli elementi, come illustrato e con lo stesso rientro.

    services:
      app:
        ...
      mysql:
        image: mysql:lts
    

    La definizione del servizio mysql corrisponde al comando usato in precedenza per avviare MySQL. Quando si definisce il servizio, riceve automaticamente l'alias di rete.

  9. Identificare il volumes mappato per il servizio di mysql.

    services:
      app:
        ...
      mysql:
        image: mysql:lts
        volumes:
          - todo-mysql-data:/var/lib/mysql
    
  10. Specificare le definizioni di variabili environment da usare nell'eseguire comandi per il servizio mysql.

    services:
      app:
        ...
      mysql:
        image: mysql:lts
        volumes:
          - todo-mysql-data:/var/lib/mysql
        environment: 
          MYSQL_ROOT_PASSWORD: <your-password>
          MYSQL_DATABASE: todos
    

    Ricorda di inserire la password di root di MySQL per il segnaposto <your-password>.

  11. Definire la mappatura dei volumi per l'intera app. Aggiungere una sezione volumes: dopo la sezione services: e con lo stesso rientro.

    services:
       ...
    
    volumes:
      todo-mysql-data:
    
  12. Verificare che il file di docker-compose.yml completato sia simile all'esempio seguente. Dovresti vedere la password di root di MySQL per il segnaposto <your-password>.

    name: todo
    
    services:
      app:
        image: node:lts-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
        environment:
          MYSQL_HOST: mysql
          MYSQL_USER: root
          MYSQL_PASSWORD: <your-password>
          MYSQL_DB: todos
    
      mysql:
        image: mysql:lts
        volumes:
          - todo-mysql-data:/var/lib/mysql
        environment: 
          MYSQL_ROOT_PASSWORD: <your-password>
          MYSQL_DATABASE: todos
    
    volumes:
      todo-mysql-data:
    

Eseguire lo stack di applicazioni con Docker Compose

È ora possibile provare a eseguire il file docker-compose.yml.

  1. Interrompere le istanze in esecuzione dell'applicazione e del database.

    • di Visual Studio Code
    • della riga di comando

    Seguire questa procedura in VS Code:

    1. Aprire CONTAINER EXPLORER (estensione Strumenti contenitore).

    2. Per ogni contenitore in esecuzione, fare clic con il pulsante destro del mouse sul contenitore e selezionare Rimuovi.

  2. Avvia l'app multi-contenitore e tutti i servizi.

    • di Visual Studio Code
    • della riga di comando

    Seguire questa procedura in VS Code:

    1. Apri la visualizzazione EXPLORER (file e cartella).

    2. Fare clic con il pulsante destro del mouse sul file di docker-compose.yml e selezionare Compose Up.

    L'output dovrebbe essere simile all'esempio seguente:

    [+] Building 0.0s (0/0)
    [+] Running 2/2
    ✔ Container app-app-1    Started  0.9s 
    ✔ Container app-mysql-1  Running
    

    Questa operazione crea il volume mappato per l'app e la rete. Per impostazione predefinita, Docker Compose crea una rete specifica per lo stack di applicazioni.

  3. Esaminare i log del contenitore in esecuzione.

    • di Visual Studio Code
    • della riga di comando

    Seguire questa procedura in VS Code:

    1. Aprire CONTAINER EXPLORER (estensione Strumenti contenitore).

    2. Fare clic con il pulsante destro del mouse sul contenitore dell'app e selezionare Visualizza log.

    L'output dovrebbe essere simile all'esempio seguente:

    mysql_1  | 2019-10-03T03:07:16.083639Z 0 [Note] mysqld: ready for connections.
    mysql_1  | Version: '5.7.27'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
    app_1    | Connected to mysql db at host mysql
    app_1    | Listening on port 3000
    

    I log mostrano il nome del servizio e il numero di istanza, ad esempio app_1 all'inizio di ogni riga. Questo formato consente di distinguere i messaggi in base al servizio e all'istanza. I log di ogni servizio vengono interleavati in un singolo flusso. Questo approccio consente di controllare i problemi correlati alla tempistica.

  4. È ora possibile passare all'applicazione in esecuzione nel browser Internet: http://localhost:3000.

Fermare Docker Compose e i contenitori in esecuzione

Quando hai finito con l'app e i contenitori, puoi rimuoverli.

  • di Visual Studio Code
  • della riga di comando

Seguire questa procedura in VS Code:

  1. Apri la visualizzazione EXPLORER (file e cartella).

  2. Fare clic con il pulsante destro del mouse sul file di docker-compose.yml e selezionare Compose down.

Questa operazione arresta tutti i container in esecuzione e rimuove la rete.

Per impostazione predefinita, i volumi denominati nel file compose non vengono rimossi. Se si desidera rimuovere questi volumi, è possibile usare il comando docker-compose down --volumes.

Pulire le risorse

Se all'installazione sono stati applicati i componenti prerequisiti in questa serie di esercitazioni, è possibile riutilizzare la configurazione per lo sviluppo futuro di Docker. Non è essenziale eliminare o disinstallare alcun componente.