Docker 환경변수 설정

박세건·2024년 9월 20일
0

기술 실습

목록 보기
9/18
post-thumbnail

모든 마이크로서비스 CI/CD 적용

하나의 마이크로서비스의 CI/CD를 구축해서 적용시켰다면 나머지 서비스에 대해서도 동일하게 적용시켜보자
각각의 마이크로서비스의 CI/CD 적용과정은 복사붙이기가 전부라서 빠르게 진행한다

내가 틀린 주의할점

  • Branch 명
  • Port 번호

Docker 환경변수 설정

마이크로서비스들의 CI/CD를 진행하던 중에 applcation.yml 파일에 대한 암호화를 진행하는 문제가 발생
해당 문제를 해결하기위해 환경변수를 지정해줘서 지정변수가 노출되지 않도록 설정해보려고한다.

application.yml 수정

이전에 작성했던 application.yml은 코드 push 할때 중요정보가 노출될 위험이 있기때문에 코드를 수정한다.

spring:
  datasource:
    url: jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_NAME}?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul
    username: ${DB_USER}
    password: ${DB_PASSWORD}
    driver-class-name: com.mysql.cj.jdbc.Driver

Pipeline Script 수정

${}로 감싸진 해당 변수들에 올바른 값들을 넣어주기 위해서 환경변수를 설정해주어야하고 이를 위해서 docker run 할때의 Script를 수정해준다.

steps {
                sh '''
                    docker run --name notification -d \
                    -p 8083:8083 \
                    -e DB_HOST=j11a604.p.ssafy.io \
                    -e DB_PORT=3306 \
                    -e DB_USER=root \
                    -e DB_PASSWORD=ssafy \
                    -e DB_NAME=trabean \
                    qkrtprjs/notification
                '''
                echo 'Run New member image'
            }

[트러블슈팅] 환경변수 설정후 이미지 빌드 실패

NotificationApplicationTests > contextLoads() FAILED
    java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:180
        Caused by: org.springframework.beans.factory.BeanCreationException at AbstractAutowireCapableBeanFactory.java:1806
            Caused by: jakarta.persistence.PersistenceException at AbstractEntityManagerFactoryBean.java:421
                Caused by: org.hibernate.exception.JDBCConnectionException at SQLExceptionTypeDelegate.java:51
                    Caused by: java.sql.SQLNonTransientConnectionException at SQLError.java:111
                        Caused by: com.mysql.cj.exceptions.UnableToConnectException at null:-1
                            Caused by: com.mysql.cj.exceptions.WrongArgumentException at null:-1
                                Caused by: java.lang.NumberFormatException at null:-1

위와 같은 에러가 발생했고 원인은 데이터베이스에 연결할 수 없음을 나타낸다고 한다.

생각해보니 실패는 이미지 빌드하는 과정에서 실패했고 수정해준 코드는 docker run 하는 부분이다. 즉. 빌드하는 과정에서는 환경변수가 적용되지 않는것 같아서 발생한 에러같다.

찾아보니 빌드하는 과정에서도 사용할 환경 변수를 설정해주어야 빌드시에 에러가 발생하지 않다고 한다.

  • 시도 1 : 빌드하는 과정에도 환경변수 설정

    • dockerfile 수정
    FROM eclipse-temurin:17-jdk
    
    		ARG DB_HOST
    		ARG DB_PORT
    		ARG DB_USER
    		ARG DB_PASSWORD
    		ARG DB_NAME
    
    WORKDIR /app
    
    COPY build/libs/notification-0.0.1-SNAPSHOT.jar app.jar
    
    ENV DB_HOST=${DB_HOST}
    ENV DB_PORT=${DB_PORT}
    ENV DB_USER=${DB_USER}
    ENV DB_PASSWORD=${DB_PASSWORD}
    ENV DB_NAME=${DB_NAME}
    
    EXPOSE 8083
    
    ENTRYPOINT ["java", "-jar", "app.jar"]
    
    VOLUME ["/data"]
    • script 수정
    dir('notification') {
                      
                      sh 'chmod +x ./gradlew'
                      sh './gradlew build'
                      sh 'pwd'
                      sh '''
                          docker build -t qkrtprjs/notification \
                          --build-arg DB_HOST=j11a604.p.ssafy.io \
                          --build-arg DB_PORT=3306 \
                          --build-arg DB_USER=root \
                          --build-arg DB_PASSWORD=ssafy \
                          --build-arg DB_NAME=trabean .
                      '''
                  }
    • 여전히 같은 에러 발생
  • 시도 2 : ubuntu에 접속해서 직접 docker 명령어를 실행
    정상적으로 작동되는 것을 확인 심지어 run하는 과정에서는 환경변수 설정도 해주지 않음

    • 에러가 발생하지 않았던 이유는 이전에 만들어놓은 jar파일로 docker build와 docker run을 진행했던 것.
    • 그렇다면 ./gradlew build 이 과정에서 에러가 발생했다고 생각, 프로젝트에서 따로 터미널을 열어서 해당코드를 실행시켜보니 같은 에러 발생.
    • 아마 빌드하는 과정에서 환경변수 세팅이 이루어지지 않아서 발생한 에러라고 생각
  • 시도 3 : ./gradlew build 하는 과정에도 환경변수를 설정해주는 방법

    • 스크립트 수정
    sh '''
                          export DB_HOST=j11a604.p.ssafy.io
                          export DB_PORT=3306
                          export DB_USER=root
                          export DB_PASSWORD=ssafy
                          export DB_NAME=trabean
    
                          ./gradlew build
                      '''

    해당 스크립트에서 export 명령어를 사용해서 빌드하는 과정에 환경변수를 미리 세팅해주는 과정으로 진행

    • 결과 : 해결, 정상적으로 운영되는것을 확인

      그렇다면, 빌드하는과정, 이미지 빌드하는 과정, 이미지 실행시키는 과정 이 세개의 과정에서 모두 반복되는 환경변수 세팅을 해줘야하는 것인데, 반복적인 과정이 비효율적 처럼보인다. 하지만 이를 해결하기 위해서는 따로 파일을 지정해주는 방식이 있다고 하는데 이 또한, GitLab이나 Github에 올리게되면 중요 내용이 노출될 가능성이 있다. 좀 더 공부해보자


      알아보니 Spring Cloud Config를 활용하면 설정 파일을 외부로 분리하는 아키텍처를 활용할 수 있다고 한다.

      • 개발/테스트 환경 그리고 운영 환경까지 모든 환경 구성을 간편하게 관리
      • 환경변수가 바뀌었을때 어플리케이션을 다시 빌드하고 배포할 필요가 없기 때문에 개발 생산성에 좋은 영향
        결과적으로, 설정이 바뀔 때마다 빌드와 배포가 필요 없는 구조로 어플리케이션을 설계 가능

추가적으로 진행해서 나머지 마이크로서비스들의 CI/CD를 완성시켰고 이제 API Gateway와 Eureka를 적용시켜서 조금 더 완성적인 MSA 구조를 만들어보자

profile
멋있는 사람 - 일단 하자

0개의 댓글