1. 소개

이 사용방법(예제)에서는 널리 사용되는 오픈 소스 데이터베이스 PostgreSQL을 사용하여 Spring Boot 애플리케이션을 실행하려고합니다. 이전 기사 에서 우리는 여러 컨테이너를 한 번에 처리하기 위해 Docker Compose살펴 보았습니다 . 따라서 PostgreSQL을 별도의 애플리케이션으로 설치하는 대신 Docker Compose를 사용하여 Spring Boot 및 PostgreSQL을 실행합니다 .

2. 스프링 부트 프로젝트 생성

Spring Initializer 로 이동하여 Spring Boot 프로젝트를 생성 합니다 . PostgreSQL 드라이버스프링 데이터 JPA 모듈을 추가 할 것 입니다. 결과 ZIP 파일을 다운로드하고 폴더에 압축을 푼 후 새 애플리케이션을 실행할 수 있습니다.

./mvnw spring-boot:run

데이터베이스에 연결할 수 없기 때문에 애플리케이션이 실패합니다.

***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class

3. Dockerfile

Docker Compose로 PostgreSQL을 시작하기 전에 Spring Boot 애플리케이션을 Docker 이미지로 전환해야합니다 . 첫 번째 단계는 애플리케이션을 JAR 파일로 패키징하는 것입니다.

./mvnw clean package -DskipTests

여기서는 애플리케이션을 패키징하기 전에 먼저 이전 빌드를 정리합니다. 또한 PostgreSQL 없이는 실패하므로 테스트를 건너 뜁니다.

이제 대상 디렉토리 에 애플리케이션 JAR 파일이 있습니다. 해당 파일의 이름에는 프로젝트 이름과 버전 번호가 있으며 -SNAPSHOT.jar로 끝납니다 . 따라서 그 이름은 docker-spring-boot-postgres-0.0.1-SNAPSHOT.jar 일 수 있습니다.

새로운 src / main / docker 디렉토리를 만들어 보겠습니다 . 그런 다음 여기에 애플리케이션 JAR 파일을 복사합니다.

cp target/docker-spring-boot-postgres-0.0.1-SNAPSHOT.jar src/main/docker

마지막으로 동일한 디렉터리 에이 Dockerfile만듭니다 .

FROM adoptopenjdk:11-jre-hotspot
ARG JAR_FILE=*.jar
COPY ${JAR_FILE} application.jar
ENTRYPOINT ["java", "-jar", "application.jar"]

이 파일은 Docker가 Spring Boot 애플리케이션을 실행하는 방법을 설명합니다 . AdoptOpenJDK의 Java 11을 사용   하고 애플리케이션 JAR 파일을 application.jar에 복사합니다 . 그런 다음 해당 JAR 파일을 실행하여 Spring Boot 애플리케이션을 시작합니다.

4. Docker 작성 파일

이제 Docker Compose 파일 인 docker-compose.yml을 작성 하고 src / main / docker 에 저장하겠습니다 .

version: '2'

services:
  app:
    image: 'docker-spring-boot-postgres:latest'
    build:
      context: .
    container_name: app
    depends_on:
      - db
    environment:
      - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/compose-postgres
      - SPRING_DATASOURCE_USERNAME=compose-postgres
      - SPRING_DATASOURCE_PASSWORD=compose-postgres
      - SPRING_JPA_HIBERNATE_DDL_AUTO=update
          
  db:
    image: 'postgres:13.1-alpine'
    container_name: db
    environment:
      - POSTGRES_USER=compose-postgres
      - POSTGRES_PASSWORD=compose-postgres

우리 응용 프로그램의 이름은  app입니다. 두 서비스 중 첫 번째입니다 (4-15 행).

  • Spring Boot Docker 이미지의 이름은  docker-spring-boot-postgres : latest (5 행)입니다. Docker 는 현재 디렉터리 Dockerfile 에서 해당 이미지를 빌드합니다 (6-7 행).
  • 컨테이너 이름은 app입니다  (8 행). db 서비스 에 따라 다릅니다 (10 행). 그것이 db 컨테이너 이후에 시작되는 이유입니다.
  • 애플리케이션은 db PostgreSQL 컨테이너를 데이터 소스로 사용합니다 (12 행). 데이터베이스 이름, 사용자 이름 및 암호는 모두 compose-postgres입니다 (12-14 행).
  • Hibernate는 필요한 데이터베이스 테이블을 자동으로 생성하거나 업데이트합니다 (15 행).

PostgreSQL 데이터베이스의 이름은 db 이고 두 번째 서비스입니다 (17-22 행).

  • PostgreSQL 13.1을 사용합니다 (18 행).
  • 컨테이너 이름은 db입니다 (19 행).
  • 사용자 이름과 암호는 모두  compose-postgres입니다 (21-22 행).

5. Docker Compose로 실행

Docker Compose를 사용하여 Spring Boot 애플리케이션과 PostgreSQL을 실행 해 보겠습니다 .

docker-compose up

먼저 Spring Boot 애플리케이션에 대한 Docker 이미지를 빌드합니다. 다음으로 PostgreSQL 컨테이너를 시작합니다. 마지막으로 애플리케이션 Docker 이미지를 시작합니다. 이번에는 애플리케이션이 정상적으로 실행됩니다.

Starting DemoApplication v0.0.1-SNAPSHOT using Java 11.0.9 on f94e79a2c9fc with PID 1 (/application.jar started by root in /)
[...]
Finished Spring Data repository scanning in 28 ms. Found 0 JPA repository interfaces.
[...]
Started DemoApplication in 4.751 seconds (JVM running for 6.512)

보시다시피 SpringData는 저장소 인터페이스를 찾지 못했습니다. 맞습니다 – 아직 만들지 않았습니다!

모든 컨테이너를 중지하려면 먼저 [Ctrl-C]를 눌러야합니다. 그런 다음 Docker Compose를 중지 할 수 있습니다.

docker-compose down

6. 고객 엔터티 및 리포지토리 생성

애플리케이션에서 PostgreSQL 데이터베이스를 사용하기 위해 간단한 고객 엔티티를 생성합니다 .

@Entity
@Table(name = "customer")
public class Customer {

    @Id
    @GeneratedValue
    private long id;
    
    @Column(name = "first_name", nullable = false)
    private String firstName;
    
    @Column(name = "last_name", nullable = false)
    private String lastName;

고객은 생성 된이 아이디 : 속성과 두 개의 필수 속성 인 firstNamelastName 속성 .

이제이 엔티티에 대한 저장소 인터페이스를 작성할 수 있습니다 .

public interface CustomerRepository extends JpaRepository<Customer, Long> { }

JpaRepository 를 확장하기 만하면 Customer 엔터티 를 만들고 쿼리하는 메서드를 상속합니다 .

마지막으로 애플리케이션에서 다음 메서드를 사용합니다.

@SpringBootApplication
public class DemoApplication {
    @Autowired 
    private CustomerRepository repository; 
  
    @EventListener(ApplicationReadyEvent.class)
    public void runAfterStartup() {
        List allCustomers = this.repository.findAll(); 
        logger.info("Number of customers: " + allCustomers.size());
 
        Customer newCustomer = new Customer(); 
        newCustomer.setFirstName("John"); 
        newCustomer.setLastName("Doe"); 
        logger.info("Saving new customer..."); 
        this.repository.save(newCustomer); 
 
        allCustomers = this.repository.findAll(); 
        logger.info("Number of customers: " + allCustomers.size());
    }
}
  • 의존성 주입을 통해 고객 저장소에 액세스 합니다.
  • 저장소로 기존 고객 수를 쿼리합니다.이 값은 0이됩니다.
  • 그런 다음 고객을 만들고 저장합니다.
  • 그런 다음 기존 고객을 다시 쿼리하면 방금 생성 한 고객을 찾을 수 있습니다.

7. Docker Compose Again으로 실행

업데이트 된 Spring Boot 애플리케이션을 실행하려면 먼저 다시 빌드해야합니다 . 따라서 프로젝트 루트 디렉터리에서 다음 명령을 한 번 더 실행합니다.

./mvnw clean package -DskipTests
cp target/docker-spring-boot-postgres-0.0.1-SNAPSHOT.jar src/main/docker

이 업데이트 된 애플리케이션 JAR 파일로 Docker 이미지를 어떻게 다시 빌드합니까? 가장 좋은 방법은 docker-compose.yml 에 이름을 지정한 기존 Docker 이미지를 제거하는 입니다. 그러면 다음에 Docker Compose 파일을 시작할 때 Docker가 이미지를 다시 빌드하게됩니다.

cd src/main/docker
docker-compose down
docker rmi docker-spring-boot-postgres:latest
docker-compose up

따라서 컨테이너를 중지 한 후 애플리케이션 Docker 이미지를 삭제합니다. 그런 다음 Docker Compose 파일을 다시 시작하여 애플리케이션 이미지를 다시 빌드합니다.

다음은 애플리케이션 출력입니다.

Finished Spring Data repository scanning in 180 ms. Found 1 JPA repository interfaces.
[...]
Number of customers: 0
Saving new customer...
Number of customers: 1

Spring Boot는 빈 고객 저장소를 찾습니다. 따라서 고객없이 시작한 다음 성공적으로 생성합니다.

8. 결론

이 짧은 사용방법(예제)에서는 PostgreSQL 용 Spring Boot 애플리케이션을 만드는 것으로 시작했습니다. 다음으로 PostgreSQL 컨테이너로 애플리케이션 컨테이너를 실행하기 위해 Docker Compose 파일을 작성했습니다.

마지막으로 고객 엔터티와 저장소를 생성하여 고객을 PostgreSQL에 저장할 수있었습니다.

평소처럼이 예제의 소스 코드는 GitHub 에서 찾을 수 있습니다 .