docker-compose(SpringBoot) AWS RDS(MySQL) 연동

devdo·5일 전
0

Docker

목록 보기
11/11
post-thumbnail

https://velog.io/@mooh2jj/docker-compose로-SprongBoot-JPA-MySql-DB-서버만들기

전 블로그에서 docker-compose 로 springboot, mysql 모두 컨테이너로 배포하는 시스템을 구축해보았다.

이번에는 DB를 AWS RDS 로 대체해볼려고 한다. 실제 운영상에서는 docker-compose로 DB를 관리하지 않고 클라우드상 안정적인 DB 시스템을 구축한다.

여기서 docker-compose 는 DB(MySQL)과 연동하는 springBoot 앱만 띄울 것이다.

역시나 여기서도 .env 파일을 사용할 것이다.


AWS RDS(MySQL)

AWS 에 들어가서 RDS 서비스에서 데이터베이스 생성을 눌러주자.
MySQL은 8.0 버전으로 한다.

퍼블릭 엑세스도 로 하자.

포트 3306

2정보가 중요하다.

1) HOST
2) 마스터비번

연결이 sccessful 이 뜨면! 다음 SQL을 입력해주자!

ALTER TABLE post.posts CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

SpringBoot 프로젝트

build.gradle

    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'

    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

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

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

    // test에서 lombok 사용
    testCompileOnly 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'

    // dotenv
    implementation 'io.github.cdimascio:java-dotenv:5.1.1'

application.yml

application:
  name: deploy-backend-post

server:
  port: 8080

spring:
  profiles:
    active: local # 로컬 프로파일 활성화
    group:
      local:
        - common
      prod:
        - common

---
spring:
  config:
    activate:
      on-profile: common # 공통 프로파일
    import: optional:file:.env[.properties] # 환경변수 파일 로드
  output:
    ansi:
      enabled: always # ANSI 콘솔 색상 활성화 (JUnit 테스트 포함)
---
spring:
  config:
    activate:
      on-profile: local # 로컬 프로파일

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://${LOCAL_HOST}:3307/${MYSQL_DATABASE}?useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8&allowPublicKeyRetrieval=true
    username: ${MYSQL_USER}
    password: ${MYSQL_PASSWORD}

  jpa:
    open-in-view: false # controller 에서 지연로딩을 사용할 때 false로 설정
    hibernate:
      ddl-auto: update # 테이블 생성 및 업데이트 전략 (create, create-drop, update, validate, none)
    show-sql: false
    properties:
      hibernate:
        format_sql: false # P6Spy 사용시 비활성화
        highlight_sql: false # P6Spy 사용시 비활성화
        use_sql_comments: false # P6Spy 사용시 비활성화

cors:
  allowed-origins:
    - http://localhost:3000

logging:
  level:
    org.hibernate: error # Hibernate 로그 완전 차단
    org.hibernate.SQL: off # SQL 로그 완전 비활성화
    org.hibernate.type.descriptor.sql.BasicBinder: off # 바인딩 파라미터 로그 비활성화
    org.hibernate.orm.jdbc.bind: off # JDBC 바인딩 로그 비활성화
    org.hibernate.orm.jdbc.extract: off # JDBC 추출 로그 비활성화

---
spring:
  config:
    activate:
      on-profile: prod # 운영 프로파일

  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://${PROD_HOST}:3306/${MYSQL_DATABASE}?useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8&allowPublicKeyRetrieval=true
    username: ${MYSQL_USER}
    password: ${MYSQL_PASSWORD}

  jpa:
    open-in-view: false # controller 에서 지연로딩을 사용할 때 false로 설정
    hibernate:
      ddl-auto: update # 테이블 생성 및 업데이트 전략 (create, create-drop, update, validate, none)
    properties:
      hibernate:
        format_sql: true # SQL 포맷팅
        highlight_sql: true # 하이라이트 SQL 출력
        use_sql_comments: true # 실제 JPQL SQL 주석 사용


cors:
  allowed-origins:
    - https://dsgpost.link
    - https://www.dsgpost.link

logging:
  level:
    #    org.springframework.security.web: trace
    org.hibernate: error # Hibernate의 로그 레벨을 error로 설정

.env 설정

.env

#DB
# 기존 MySQL 설정도 유지 (RDS 접속 정보로 사용)
LOCAL_HOST=localhost
PROD_HOST=your-rds-endpoint.amazonaws.com

# Mysql
MYSQL_ROOT_PASSWORD=1234
MYSQL_DATABASE=post
MYSQL_USER=admin
MYSQL_PASSWORD=your-secure-rds-password

DotEnvConfig

@Slf4j
@Configuration
public class DotEnvConfig {

    @Bean
    public Dotenv dotenv() {
        log.info(".env file loading...");
        // .env 파일을 읽어서 환경변수로 사용
        return Dotenv.configure().directory("./")
                .ignoreIfMissing() // .env 파일이 없어도 에러 발생 안함
                .load();
    }
}

Docker

Dockerfile

# 1단계: Gradle 빌드 스테이지
FROM gradle:8.5-jdk17 AS build

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

# Gradle 캐시를 위해 build.gradle과 settings.gradle 먼저 복사
COPY build.gradle settings.gradle ./
COPY gradle gradle
COPY gradlew ./

# gradlew 실행 권한 부여 (중요!)
RUN chmod +x ./gradlew

# 의존성 다운로드 (캐시 최적화)
RUN ./gradlew dependencies --no-daemon

# 소스 코드 복사
COPY src src

# JAR 파일 빌드
RUN ./gradlew build --no-daemon -x test

# 2단계: 실행 스테이지
FROM openjdk:17-jdk-slim AS runtime

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

# 환경 변수 파일 복사
COPY .env .env

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

# 포트 노출
EXPOSE 8080

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

docker-compose-prod.yml

-> springBoot만! MySQL 설정X

version: "3.8"

services:
  # Spring Boot 애플리케이션 서비스 (운영용 - AWS RDS 연결)
  app:
    build:
      context: . # 현재 디렉토리를 빌드 컨텍스트로 사용
      dockerfile: Dockerfile # Dockerfile 위치
    container_name: spring_app_prod
    env_file:
      - .env
    environment:
      # Spring Profile 설정 - 운영 환경
      - SPRING_PROFILES_ACTIVE=prod

      # AWS RDS 연결 정보 (.env 파일에서 로드)
      - PROD_HOST=${PROD_HOST}

      # MySQL 데이터베이스 정보
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
    ports:
      - "8080:8080" # 호스트 포트 8080 -> 컨테이너 포트 8080
    restart: unless-stopped # 컨테이너 자동 재시작

    # 헬스체크 설정 (RDS 연결 확인)
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

    # 로그 설정 (운영 환경용)
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
# 운영 환경에서는 외부 RDS를 사용하므로 별도 네트워크 불필요

실행

docker-compose -f docker-compose-prod.yml up --build -d

결과

profile
배운 것을 기록합니다.

0개의 댓글