멀티커네이너 프로젝트 세팅 매뉴얼

선종우·2023년 7월 10일
0

1. 프로젝트 구조

/project-root
--/database    #db container 설정 및 docker file
---/config     #db 설정 파일
---/init       #db 초기화 파일(sql 문)
---Dockerfile
--/redis       #db redis container docker file
---Dockerfile
--/src         #프로젝트 소스
---/main
----/java
----/resources   #템플릿, 정적파일, yaml파일
-----application.yaml
---/test
--.env           #docker 환경설정 파일
--docker-compose.yml #배포용 docker 환경설정 파일
--docker-compose-local.yml #local 개발용
--Dockerfile     # application image 제작용 docker file 
--build.gradle

2. application.yaml

spring:
  profiles:
    active: local # default
    group:
      local: # local과 common을 그룹으로 묶어 어플리케이션 실행
        - common
      prod: # prod와 common을 그룹으로 묶어 어플리케이션 실행
        - common

---
spring:
  config:
    activate:
      on-profile: common

kakao:
  rest:
    api:
      key: ${KAKAO_REST_API_KEY}


---
spring:
  config:
    activate:
      on-profile: local
  datasource:
    driver-class-name: org.mariadb.jdbc.Driver
    url: jdbc:mariadb://localhost:3307/pharmacy-recommendation
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}
  redis:
    host: localhost
    port: 6379
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: true

pharmacy:
  recommendation:
    base:
      url: http://localhost:8080/dir/

---
spring:
  config:
    activate:
      on-profile: prod
  datasource:
    driver-class-name: org.mariadb.jdbc.Driver
    url: jdbc:mariadb://pharmacy-recommendation-database:3306/pharmacy-recommendation #docker-compose service명
    username: ${SPRING_DATASOURCE_USERNAME}
    password: ${SPRING_DATASOURCE_PASSWORD}
  redis:
    host: pharmacy-recommendation-redis #docker-compose service명
    port: 6379
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: true

pharmacy:
  recommendation:
    base:
      url: http://13.124.200.5/dir/

2.1 테스트용 yaml

spring:
  datasource:
    driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver #db를 testcontainer로 설정
    url: jdbc:tc:mariadb:10:/// #tc뒤에 오는 값은 무시된다.
  jpa:
    hibernate:
      ddl-auto: create
    show-sql: true

kakao:
  rest:
    api:
      key: ${KAKAO_REST_API_KEY}

pharmacy:
  recommendation:
    base:
      url: http://localhost:8080/dir/

3. docker-compose.yml

#docker-compose up -f 파일명 --build (캐싱된 이미지 체크하지 않고 빌드)                      
version: "3.8"             # 파일 규격 버전
services:
  pharmacy-recommendation-redis:
    container_name: pharmacy-recommendation-redis
    build:
      dockerfile: Dockerfile
      context: ./redis
    image: sun/pharmacy-recommendation-redis #사용할 이미지
    ports:
      - "6379:6379"
  pharmacy-recommendation-database:
    container_name: pharmacy-recommendation-database
    build:
      dockerfile: Dockerfile
      context: ./database
    image: sun/pharmacy-recommendation-database
    environment:
      - MARIADB_DATABASE=pharmacy-recommendation
      - MARIADB_ROOT_PASSWORD=${SPRING_DATASOURCE_PASSWORD}
    volumes: #db 초기화 시 필요한 파일을 container와 연결
      - ./database/config:/etc/mysql/conf.d
      - ./database/init:/docker-entrypoint-initdb.d
    ports:
      - "3306:3306"
    healthcheck: #depends_on healtcheck 관련 내용
      test: "/usr/bin/mysql --user=${SPRING_DATASOURCE_USERNAME} --password=${SPRING_DATASOURCE_PASSWORD} --execute \"SHOW DATABASES;\""
      interval: 2s
      timeout: 20s
      retries: 10
  pharmacy-recommendation-app:
    container_name: pharmacy-recommendation-app
    build: .
    depends_on:
      pharmacy-recommendation-database:
        condition: service_healthy #db container 헬스체크해서 성공했을 경우 컨테이너 시작
      pharmacy-recommendation-redis:
        condition: service_started
    image: sun/pharmacy-recommendation-app
    environment:
      - SPRING_DATASOURCE_USERNAME=${SPRING_DATASOURCE_USERNAME}
      - SPRING_DATASOURCE_PASSWORD=${SPRING_DATASOURCE_PASSWORD}
      - SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE}
      - KAKAO_REST_API_KEY=${KAKAO_REST_API_KEY}
    ports:
      - "80:8080"
    restart: always #의존성 문제 등으로 container가 꺼졌을 경우 재시작
  • 헬스체크 관련 글 링크 : [링크]

4. Dockerfile

FROM openjdk:17
ARG  JAR_FILE=build/libs/app.jar
COPY ${JAR_FILE} ./app.jar
ENV TZ=Asia/Seoul
ENTRYPOINT ["java", "-jar", "./app.jar"]

5. build.gradle

plugins {
	id 'java'
	id 'org.springframework.boot' version '2.7.13'
	id 'io.spring.dependency-management' version '1.1.0'
	id 'groovy'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '17'
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.springframework.retry:spring-retry:'
	//implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-data-redis'
	implementation 'pl.allegro.tech.boot:handlebars-spring-boot-starter:0.3.4'
	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
	annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'

	testImplementation('org.spockframework:spock-core:2.1-groovy-3.0')
	//testImplementation('org.spockframework:spock-core:2.4-M1-groovy-4.0')
	testImplementation('org.spockframework:spock-spring:2.1-groovy-3.0')
	//testImplementation('org.spockframework:spock-spring:2.4-M1-groovy-4.0')

	testImplementation('net.bytebuddy:byte-buddy:1.12.10')

	//testcontainer
	testImplementation('org.testcontainers:spock:1.17.1')
	//testImplementation('org.testcontainers:spock:1.17.6')

	testImplementation('org.testcontainers:mariadb:1.17.1')
	//testImplementation('org.testcontainers:mariadb:1.17.6')

	testImplementation('com.squareup.okhttp3:okhttp:4.10.0')
	testImplementation('com.squareup.okhttp3:mockwebserver:4.10.0')

	// https://github.com/seruco/base62
	implementation 'io.seruco.encoding:base62:0.1.3'


}

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

bootJar{
	archiveFileName = 'app.jar'
}
//./gradlew clean build -PKAKAO_REST_API_KEY={api key 값}
processTestResources{
	boolean hasProperty = project.hasProperty("KAKAO_REST_API_KEY")
	System.out.println("Set kakao rest api key : $hasProperty")
	filesMatching('**/application.yaml'){
		expand(project.properties)
	}
}

6. EC2 세팅(서버에서 직접 빌드)

  1. EC2 인스턴스 생성(AWS linux)
  2. Elastic IP 할당
  3. 보안그룹 설정
  4. 초기세팅
    1. sudo yum update -y
    2. sudo yum install java-17-amazon-corretto
    3. sudo yum install git -y
    4. sudo yum install docker
    5. sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    6. sudo systemctl start docker
    7. sudo chmod +x /usr/local/bin/docker-compose
    8. sudo chmod 666 /var/run/docker.sock
    9. (필요시)sudo dnf install libxcrypt-compat
    10. (필요시) swap 메모리 설정
  5. git clone project
  6. .env파일 세팅 -> docker-compose config 명령어로 최종 세팅된 파일을 볼 수 있음
  7. docker-compose build #프리티어 인스턴스 부하를 줄이기 위해 build와 up을 별도로 진행
  8. docker-compose up

0개의 댓글