hyeonga_code

Project_Docker DockerCompose 본문

Project_HYEONGARL

Project_Docker DockerCompose

hyeonga 2024. 6. 12. 05:59
반응형

 

Docker.

공부를 할 때 블로그를 참고하는 것보다 공식 문서를 한 번 쭉 훑어보는게 좋다고 하셔서 공식 문서를 보다가 

Dokcer 공식 문서를 풀어서 설명하신 블로그를 보고 이해하는 데 도움이 많이 되었다.

 

[Docker] Docker 이해하기 -1 : 기초 이론(아키텍처, 흐름, 주요 용어)

해당 글에서는 Docker를 사용하기 위해 기본적인 아키텍처에 대한 이해와 흐름, 주요 용어들에 대해 이해를 돕기 위해 작성한 글입니다. 1) Docker 💡 Docker - ‘컨테이너화’를 사용하여 응용 프로

adjh54.tistory.com

 

 


DockerFile.

> 빌드 단계

#syntax=docker/dockerfile:1

# openjdk:17-jdk 이미지를 사용하여 빌드 환경을 설정
FROM openjdk:17-jdk-alpine as builder

# 작업 디렉토리를 /app으로 설정
WORKDIR /app

# GradleWrapper와 관련된 파일을 복사
COPY gradlew ./gradlew
COPY gradle ./gradle

# 프로젝트 파일을 복사
COPY settings.gradle ./
COPY api/build.gradle ./
COPY api/src ./src

# gradlew에 실행 권한을 부여
RUN chmod +x ./gradlew

# Gradle 빌드를 실행
RUN ./gradlew clean build

 

 

> 이미지 생성 단계

# openjdk:17-jdk-alpine 이미지로 경량의 실행 환경 설정
FROM openjdk:17-jdk-alpine

# 작업 디렉토리 설정
WORKDIR /app

# 빌드된 JAR 파일을 builder 스테이지에서 복사
COPY --from=builder /app/build/libs/*.jar app.jar

# 애플리케이션 실행
ENTRYPOINT ["java", "-jar", "/app/app.jar"]



> 전체 코드

더보기
#syntax=docker/dockerfile:1

# Base image
FROM openjdk:17-jdk-alpine as builder

# Set the working directory
WORKDIR /app

# Copy Gradle Wrapper
COPY gradlew ./gradlew
COPY gradle ./gradle

# Copy project files
COPY settings.gradle ./
COPY api/build.gradle ./
COPY api/src ./src

# Build the application
RUN ./gradlew clean build

FROM openjdk:17-jdk-alpine

WORKDIR /app

COPY --from=builder /app/build/libs/*.jar app.jar

# Run the application
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

 

 

 

docker-compose.yml

서비스를 정의

> MySQL 설정

services:
  mysql:
    # 컨테이너 이름 설정
    container_name: hyeongarldb
    # 최신 MySQL 서버 이미지를 사용 
    image: mysql/mysql-server:latest	
    # 환경 변수를 사용하여 데이터베이스 설정 구성
    environment:			
      # 루트 사용자 비밀번호 설정
      MYSQL_ROOT_PASSWORD: ---
      # 기본 데이터베이스 이름 설정
      MYSQL_DATABASE: ---
      # 데이터베이스 사용자 이름 설정
      MYSQL_USER: ---
      # 데이터베이스 사용자 비밀번호 설정
      MYSQL_PASSWORD: ---
      # 타임존 설정
      TZ: Asia/Seoul
    # 포트 매핑
    ports:				
      - 3307:3306
    # 볼륨을 사용하여 MySQL 데이터 지속화
    volumes:				
      - mysql_data:/var/lib/mysql
    # 네트워크 연결 설정
    networks:
      - hyeongarl_network
    # MySQL 컨테이너의 상태를 주기적으로 확인
    healthcheck:
      # 명령어를 통해 데이터베이스의 상태를 확인
      test: ["CMD-SHELL", "mysqladmin ping -h localhost"]
      # 10초마다 확인
      interval: 10s
      # 상태 확인 명령의 타임아웃을 10초로 설정
      timeout: 10s
      # 상태 확인 실패 시 2번 재시도
      retries: 2

# 모든 서비스가 상호 연결되도록 커스텀 네트워크 설정
networks:
  hyeongarl_network:

# 볼륨 설정
volumes:
  mysql_data:

 

 

 

> 작성  코드

  app:
    # 컨테이너 이름 설정
    container_name: server
    # api 모듈의 DockerFile을 빌드
    build:
      # 현재 디렉토리에서 빌드 컨텍스트를 설정
      context: .
      # Docker 이미지를 빌드하는 파일 설정
      dockerfile: ./api/Dockerfile
    # 포트 매핑
    ports:
      - 8081:8080
    # SpringBoot 애플리케이션이 MySQL 데이터베이스에 접근할 수 있도록 환경 변수 설정
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://"MySQL컨테이너이름":"컨테이너내포트(3306)"/"DB이름"
      SPRING_DATASOURCE_USERNAME: ---
      SPRING_DATASOURCE_PASSWORD: ---
    # 데이터베이스와 의존성을 가짐
    depends_on:
      mysql:
        # MySQL 서비스가 건강한 상태인 경우 서비스를 시작
        condition: service_healthy
    networks:
      - hyeongarl_network



> 전체 코드

더보기
services:
  mysql:
    container_name: hyeongarldb
    image: mysql/mysql-server:latest
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: hyeongarl
      MYSQL_USER: hyeongarl
      MYSQL_PASSWORD: hyeongarl@45
      TZ: Asia/Seoul
    ports:
      - 3307:3306
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - hyeongarl_network
    healthcheck:
      test: ["CMD-SHELL", "mysqladmin ping -h localhost"]
      interval: 10s
      timeout: 10s
      retries: 2

  app:
    container_name: server
    build:
      context: .
      dockerfile: ./api/Dockerfile
    ports:
      - 8081:8080
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://hyeongarldb:3306/hyeongarl?serverTimezone=Asia/Seoul
      SPRING_DATASOURCE_USERNAME: hyeongarl
      SPRING_DATASOURCE_PASSWORD: hyeongarl@45
    depends_on:
      mysql:
        condition: service_healthy
    networks:
      - hyeongarl_network

networks:
  hyeongarl_network:

volumes:
  mysql_data:

 

 

> 실행

더보기
 > docker-compose up --build
 
[+] Building 0.0s (0/0)  docker:default
[+] Building 2.4s (16/16) FINISHED                                                                                                                                                                                            docker:default
 => [app internal] load build definition from Dockerfile                                                                                                                                                                                0.0s
 => => transferring dockerfile: 557B                                                                                                                                                                                                    0.0s 
 => [app] resolve image config for docker-image://docker.io/docker/dockerfile:1                                                                                                                                                         1.1s 
 => CACHED [app] docker-image://docker.io/docker/dockerfile:1@sha256:a57df69d0ea827fb7266491f2813635de6f17269be881f696fbfdf2d83dda33e                                                                                                   0.0s
 => [app internal] load metadata for docker.io/library/openjdk:17-jdk-alpine                                                                                                                                                            0.7s
 => [app internal] load .dockerignore                                                                                                                                                                                                   0.0s
 => => transferring context: 2B                                                                                                                                                                                                         0.0s 
 => [app builder 1/8] FROM docker.io/library/openjdk:17-jdk-alpine@sha256:4b6abae565492dbe9e7a894137c966a7485154238902f2f25e9dbd9784383d81                                                                                              0.0s 
 => [app internal] load build context                                                                                                                                                                                                   0.1s 
 => => transferring context: 5.84kB                                                                                                                                                                                                     0.0s 
 => CACHED [app builder 2/8] WORKDIR /app                                                                                                                                                                                               0.0s
 => CACHED [app builder 3/8] COPY gradlew ./gradlew                                                                                                                                                                                     0.0s 
 => CACHED [app builder 4/8] COPY gradle ./gradle                                                                                                                                                                                       0.0s 
 => CACHED [app builder 5/8] COPY settings.gradle ./                                                                                                                                                                                    0.0s 
 => CACHED [app builder 6/8] COPY api/build.gradle ./                                                                                                                                                                                   0.0s 
 => CACHED [app builder 7/8] COPY api/src ./src                                                                                                                                                                                         0.0s 
 => CACHED [app builder 8/8] RUN ./gradlew clean build                                                                                                                                                                                  0.0s 
 => CACHED [app stage-1 3/3] COPY --from=builder /app/build/libs/*.jar app.jar                                                                                                                                                          0.0s 
 => [app] exporting to image                                                                                                                                                                                                            0.0s 
 => => exporting layers                                                                                                                                                                                                                 0.0s 
 => => writing image sha256:4fd0f7914d2f3aa3de87b4e608654e1cfb96d98829676fccdd84bf2cc6d52f5d                                                                                                                                            0.0s 
 => => naming to docker.io/library/hyeongarl-app                                                                                                                                                                                        0.0s 
[+] Running 2/2
 ✔ Container hyeongarldb  Created                                                                                                                                                                                                       0.0s 
 ✔ Container server       Created                                                                                                                                                                                                     0.2s 
Attaching to hyeongarldb, server

 

 

문제.

build시 테스트 코드에서 오류가 계속 발생해서 Build Fail이 되었다.

해결.

Gradle 빌드 스크립트에서 테스트 작업을 비활성화 하는 코드를 추가하면 된다.

 

> Build.gradle

tasks.withType(Test).configureEach {
	enabled = false
}

 

모든 테스트 작업을 선택하여 선택된 각 작업에 대한 설정을 비활성화한다.

 

 

 

jar파일 문제

build/libs 폴더에 들어가보면 .jar 파일이 두개가 있는 것을 볼 수 있다.

api-1.0-SNAPSHOT.jar
  기본적인  JAR 파일
  프로젝트의 클래스 파일과 리소스 파일이 포함
  프로젝트 코드와 라이브러리 등 모든 것을 포함
api-1.0-SNAPSHOT-plain.jar
  plain / fat JAR
  실행 가능한 JAR 파일로 해당 프로젝트의 클래스 파일 뿐만 아니라 종속성 라이브러리도 포함
  JAR 파일 안에 포함되어 독립적으로 실행할 수 있다.

 

> Build.gradle

jar {
	enabled = false
}

 

이 코드를 추가하는 경우 plain.jar 파일이 생성되지 않는다.

 

> 전체 코드

더보기
plugins {	// Gradle에서 지원하는 플러그인
	id 'java'
	id 'org.springframework.boot' version '3.2.5'
	id 'io.spring.dependency-management' version '1.1.5'
	id "io.freefair.lombok" version "8.6"

	/*
        1) id 'java'
            java 코드 컴파일, 테스트, 애플리케이션 패키징
        2) id 'org.springframework.boot' version '3.2.5'
            SpringBoot 애플리케이션을 실행, 실행 가능한 JAR 또는 WAR패키징
        3) id 'io.spring.dependency-management' version '1.1.5'
            일관된 방식으로 종속성을 관리하는 데 사용
            섹션을 사용하여 프로젝트의 모든 종속성에 적용해야 하는 종속성 버전을 정의하여 충돌을 방지
        4) id "io.freefair.lombok" version "8.6"
            롬복 사용 (gradle에서 관리하므로 플러그인으로 설정 가능)
    */
}

// 프로젝트 그룹 ID 설정 (패키지 이름 지정 및 종속성 관리에 사용)
group = 'com.heyongarl'

// 프로젝트의 버전을 설정
version = '1.0-SNAPSHOT'

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(17)
	}
	/*
        toolchain VS sourceCompatibility
        toolchain
            Gradle 자체를 실행하는 데 사용되는 JDK와 별개로
            프로젝트를 컴파일, 테스트, 실행하는 데 사용할 JDK 버전을 지정할 수 있다.
        sourceCompatibility
            소스 코드의 Java 버전 호환성을 명시하는 데 사용
    */
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.boot:spring-boot-starter-web-services'
	implementation 'org.springframework.boot:spring-boot-starter-validation'

	// JPA
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

	// MySQL JPA
	runtimeOnly 'com.mysql:mysql-connector-j'

	testImplementation 'org.springframework.boot:spring-boot-starter-test'

	/*
        1) implementation 'org.springframework.boot:spring-boot-starter-web'
            Spring MVC를 사용하여 웹 애플리케이션을 빌드하기 위한 종속성
        2) implementation 'org.springframework.boot:spring-boot-starter-web-services'
            웹 서비스 제작을 지원
        3) implementation 'org.springframework.boot:spring-boot-starter-validation'
            Java Bean의 유효성을 검사하기 위한 종속성 (@NotNull, @Size)
        4) implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
            Spring Data JPA를 포함한 JPA 기반 데이터 엑세스에 대한 지원을 제공
        5) runtimeOnly 'com.mysql:mysql-connector-j'
            MySQL 데이터베이스에 연결하는 데 필요한 MySQL JDBC 드라이버
        6) testImplementation 'org.springframework.boot:spring-boot-starter-test'
            JUnit, Jamcrest, Mockito를 포함한 Spring Boot 애플리케이션 테스트를 위한 종속성
    */
}

tasks.named('test') {
	useJUnitPlatform()
}

tasks.withType(Test).configureEach {
	enabled = false
}

jar {
	enabled = false
}

 

 

 

반응형