saverioriotto.it

Avviare un’applicazione Spring Boot su container Docker

In questo tutorial, vedremo come dockerizzare un'applicazione Spring Boot per eseguirla in un ambiente isolato, noto anche come container. Impareremo come creare una composizione di container, che dipendono l'uno dall'altro e sono collegati tra loro con una rete privata virtuale. Vedremo anche come gestirli insieme con i singoli comandi.

Avviare un’applicazione Spring Boot su container Docker

Per spiegare nel dettaglio questa procedura partiamo da un progetto Spring Boot già pronto del tutorial precedente. Per iniziare cloniamo il progetto tramite il comando git:

git clone -b integrazione-swagger2-springboot-rest https://git.saverioriotto.it/saverioriotto.it/spring-boot-rest-tutorial.git

Per iniziare la dockerizzazione dell'applicazione, creremo un Dockerfile con il seguente contenuto:

FROM maven:3.8.2-jdk-8
LABEL maintainer="Saverio Riotto [email protected]"
WORKDIR /spring-app-rest
COPY . .
RUN mvn clean install
CMD mvn spring-boot:run

Questo file contiene le seguenti informazioni:

FROM: immagine di base, utilizzeremo maven con jdk-8
LABEL: chi gestisce l'immagine.
COPY : Docker copia tutti i file del progetto nell'immagine.
RUN: comando maven da eseguire per compilare il progetto e portare giù le dipendenze necessarie
CMD: comando maven per avviare il progetto Spring Boot

Per creare un'immagine dal nostro Dockerfile, dobbiamo eseguire il comando 'docker build':

docker build --tag=spring-boot-rest-app:latest .

Infine, siamo in grado di eseguire il container dalla nostra immagine:

docker run -p8080:8080 spring-boot-rest-app:latest

Dopo aver lanciato quest'ultimo comando la nostra applicazione sara raggiungibile tramite chiamata HTTP sulla porta 8080. (es: http://localhost:8080/api/).

In questo modo abbiamo avviato un singolo container con la nostra applicazione e senza parametri di configurazione.

Dockerizzazione tramite docker compose 

I comandi Docker e i Dockerfile sono particolarmente adatti per la creazione di singoli container. Tuttavia, se vogliamo operare su una rete di applicazioni isolate, la gestione dei container diventa rapidamente complessa e disordinata.

Per risolvere questo problema, ricorriamo al Docker Compose. Questo strumento viene fornito con il proprio file di compilazione in formato YAML ed è più adatto per la gestione di più contenitori. Ad esempio, è in grado di avviare o arrestare un insieme di servizi in un comando o unire l'output dei logs di più servizi in un unico pseudo-tty e tanto altro ancora che puoi scoprire tramite un precedente articolo chiamato: Docker Compose: Che cos'è e come si usa.

Prendiamo sempre il nostro progetto e cerchiamo di dividerlo in più servizi creando il nostro docker-compose.yml :

version: '3.9'
services:
    rest-server:
        container_name: rest-server
        build:
            dockerfile: Dockerfile
        ports:
            - $SPRING_DOCKER_PORT:$SPRING_DOCKER_PORT
        networks:
            - spring-network
        depends_on:
            - mariadb
        restart: on-failure
        env_file: ./.env
        environment:
            SPRING_APPLICATION_JSON: '{
                "spring.datasource.url"  : "jdbc:mariadb://$DB_HOST:3306/$DB_NAME?useSSL=false",
                "spring.datasource.username" : "$DB_USER",
                "spring.datasource.password" : "$DB_PASSWORD",
                "spring.jpa.properties.hibernate.dialect" : "org.hibernate.dialect.MariaDB10Dialect",
                "spring.jpa.hibernate.ddl-auto" : "update",
                "saverioriotto.app.jwtSecret" : "sRSecretKey",
                "saverioriotto.app.jwtExpirationMs" : "86400000",
                "server.port" : "$SPRING_DOCKER_PORT"}'
    mariadb:
      image: mariadb:10.2
      container_name: mariadb
      env_file: ./.env
      environment:
        MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
        MYSQL_DATABASE: ${DB_NAME}
        MYSQL_USER: ${DB_USER}
        MYSQL_PASSWORD: ${DB_PASSWORD}
      volumes:
      - mariadb:/var/lib/mysql
      networks:
        - spring-network
      restart: on-failure
      
    phpmyadmin:
        image: phpmyadmin/phpmyadmin
        container_name: phpma
        links:
        - mariadb:mariadb
        ports:
        - 80:80
        environment:
          PMA_HOST: mariadb
          PMA_PORT: 3306
        networks:
          - spring-network 
        
networks:
    spring-network:
        driver: bridge

volumes:
    mariadb:
        driver: local

version: specifica quale versione del formato deve essere utilizzata. Questo è un campo obbligatorio. Qui utilizziamo la versione 3.9, mentre il formato legacy è "1".
services: ogni oggetto in questa chiave definisce un servizio, alias container. Questa sezione è obbligatoria.
build: se fornito, docker-compose è in grado di creare un'immagine da un Dockerfile.
image: dice a Docker quale nome dovrebbe dare all'immagine quando vengono utilizzate le funzioni di build. In caso contrario, sta cercando questa immagine nella libreria o nel repository remoto.
networks: questo è l'identificatore delle reti da utilizzare. Specificato con un dato nome-valore. In questo esempio, lasciamo che docker-compose crei per noi una rete denominata di tipo 'bridge'.
depends_on: utilizzato per impostare l'ordine in cui i servizi devono essere avviati e arrestati.Nel nostro caso prima di avviare il servizio rest abbiamo bisogno che il container “mariadb” sia già stato avviato. Stessa situazione per il phpmyadmin
environment: In questa sezione dichiariamo tutte le variabili d’ambiente che vengono richiamate, nel nostro caso, da un file .env:

DB_USER=tutorial_user
DB_PASSWORD=tut04i@lu53r
DB_NAME=tutorialdb
DB_ROOT_PASSWORD=tut04i@lroo1
DB_HOST=mariadb
SPRING_DOCKER_PORT=8080

La variabile d'ambiente SPRING_APPLICATION_JSON invece contiene la configurazione parametrizzata del file application.properties di Spring Boot.

Prima di continuare, controlliamo che il nostro docker-compose.yml non abbiamo errori di sintassi con il seguente comando:

docker-compose config

Se risulta corretto possiamo avviare la build che costruirà tutti i container configurati con il seguente comando:

docker-compose up --build

Questo avvierà tutti e tre i container dichiarati come servizi in con un unico comando.

Per fermare i container, rimuoverli da Docker e rimuovere da esso le reti connesse Possiamo usare il comando opposto:

docker-compose down

Conclusione

In questo articolo abbiamo appreso come creare immagini Docker personalizzate, eseguire un'applicazione Spring Boot come container Docker e creare più container con un singolo docker-compose.yaml.

Il codice sorgente di questo tutorial lo trovi su Github.




Commenti
* Obbligatorio