목차
- 개요
- 의존성 다운 오류
- 빌드 권한 오류
- 캐시 설정
- 도커 푸시
- 파일 권한 오류
- 결과
개요
폐쇄망 서버에서 수동 CI로 수동 배포 하던 것을 GitLab CI를 이용해서 소스 코드 변경시 자동 CI가 되도록 작업 수행필요.
gitlab과 gitlab-runner가 이미 설치되어있음을 가정함.
GitLab CI를 적용하는 과정에서 발생한 오류와 이슈 정리.
초기 작성한 .gitlab-ci.yml파일 (참고용)
stages:
- test
- build
- push
variables:
COMMIT_TAG: $CI_COMMIT_TAG
COMMIT_BRANCH: ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}
IMAGE_TAG: $CI_COMMIT_TAG
HARBOR_URL1: https://10.10.5.66:444
HARBOR_USERNAME1: [계정]
HARBOR_PASSWORD1: [비밀번호]
HARBOR_PROJECT: [프로젝트명]
HARBOR_REPOSITORY_URI: 10.10.5.66:444/${HARBOR_PROJECT}
HARBOR_REPOSITORY_NAME: mobile_framework_api/mobile_framework_api
test:
stage: test
tags:
- mobile_framework
script:
- echo COMMIT_TAG - ${COMMIT_TAG}
- echo COMMIT_BRANCH - ${COMMIT_BRANCH}
- echo IMAGE_TAG - ${IMAGE_TAG}
- echo HARBOR_REPOSITORY_URI - ${HARBOR_REPOSITORY_URI}
- echo HARBOR_REPOSITORY_NAME - ${HARBOR_REPOSITORY_NAME}
build:
image: gradle:8.8-jdk17
stage: build
tags:
- mobile_framework
variables:
JAVA_TOOL_OPTIONS: -Dhttp:profiles.active=dev
script:
- gradle :api:clean :api:bootJar
push:
image: docker:latest
stage: push
tags:
- mobile_framework
script:
- echo ${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG} ${HARBOR_REPOSITORY_URI}/${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG}
의존성 다운 오류
개요 섹션에 있는 초기 .gitlab-ci.yml파일을 가지고 gitlab ci의 pipeline 실행시 아래와 같은 오류 발생
Gradle download Failed : timeout
Exception in thread "main" java.io.IOException : Downloading from https://services.gradle.org/distributions/gradle-8.2-bin.zip failed: timeout
...
gradle wrapper가 해당 프로젝트를 빌드하기 위해 사용해야할 gradle 엔진 버전의 다운로드 경로를 지정합니다.
현재 사용하는 경우 폐쇄망인데 접근은 허용이 되어서 그런지 빌드시 오류가 날때가 있고 지나칠 경우가 있었습니다.
그래서 프로젝트 자체에 zip파일을 저장하는 방법을 사용하기로 했습니다.


결과

의존성 다운로드 실패
Running with gitlab-runner 15.10.1 (dcfb4b66) on mobile_framework t1_sp1w7z, system ID: r_8TmhTVi1a4GG Preparing the "docker" executor 00:05 Using Docker executor with image gradle:8.8-jdk17 ... Pulling docker image gradle:8.8-jdk17 ... Using docker image sha256:ef9ee5686c26e2e914a4855afe89047e5d515c60cd5a46a0281997872d36af01 for gradle:8.8-jdk17 with digest gradle@sha256:6ff0b959f7da8ba5109f815697f174549668f1a44659d1177eaf8ef11132f476 ... Preparing environment 00:00 Running on runner-t1sp1w7z-project-121-concurrent-0 via 6584f805922b... Getting source from Git repository 00:01 Fetching changes with git depth set to 20... Reinitialized existing Git repository in /builds/nextti/mobileframework/.git/ Checking out 8e212ebf as detached HEAD (ref is prod)... Skipping Git submodules setup Executing "step_script" stage of the job script 02:57 Using docker image sha256:ef9ee5686c26e2e914a4855afe89047e5d515c60cd5a46a0281997872d36af01 for gradle:8.8-jdk17 with digest gradle@sha256:6ff0b959f7da8ba5109f815697f174549668f1a44659d1177eaf8ef11132f476 ... $ gradle :api:clean :api:bootJar Picked up JAVA_TOOL_OPTIONS: -Dhttp:profiles.active=dev Starting a Gradle Daemon (subsequent builds will be faster) > Task :api:clean UP-TO-DATE > Task :core:compileJava > Task :core:compileJava FAILED FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':core:compileJava'. > Could not resolve all files for configuration ':core:compileClasspath'. > Could not download lombok-1.18.34.jar (org.projectlombok:lombok:1.18.34) > Could not get resource 'https://repo.maven.apache.org/maven2/org/projectlombok/lombok/1.18.34/lombok-1.18.34.jar'. > Premature end of Content-Length delimited message body (expected: 2,050,471; received: 1,211,528) > Could not download hibernate-core-6.2.9.Final.jar (org.hibernate.orm:hibernate-core:6.2.9.Final) > Could not get resource 'https://repo.maven.apache.org/maven2/org/hibernate/orm/hibernate-core/6.2.9.Final/hibernate-core-6.2.9.Final.jar'. > Premature end of Content-Length delimited message body (expected: 11,017,378; received: 9,611,200) * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. > Get more help at https://help.gradle.org. Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/8.8/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. BUILD FAILED in 2m 56s 2 actionable tasks: 1 executed, 1 up-to-date ERROR: Job failed: exit code 1
오류 핵심 내용
Could not download lombok-1.18.34.jar (org.projectlombok:lombok:1.18.34)
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':core:compileJava'.
> Could not resolve all files for configuration ':core:compileClasspath'.
> Could not download lombok-1.18.34.jar (org.projectlombok:lombok:1.18.34)
> Could not get resource 'https://repo.maven.apache.org/maven2/org/projectlombok/lombok/1.18.34/lombok-1.18.34.jar'.
> Premature end of Content-Length delimited message body (expected: 2,050,471; received: 1,211,528)
> Could not download hibernate-core-6.2.9.Final.jar (org.hibernate.orm:hibernate-core:6.2.9.Final)
> Could not get resource 'https://repo.maven.apache.org/maven2/org/hibernate/orm/hibernate-core/6.2.9.Final/hibernate-core-6.2.9.Final.jar'.
> Premature end of Content-Length delimited message body (expected: 11,017,378; received: 9,611,200)
프로젝트 구성이 메인 모듈을 구성하는 두개의 서브 모듈이 있습니다.(core, api)
api는 core에 의존하는 관계여서 아래와 같이 구성되어 있습니다.
//settings.gradle(:core)
rootProject.name = 'api'
include ':core'
project(':core').projectDir = file('../core')
빌드시 core를 먼저 빌드하게 되는데 서브 모듈에 필요한 의존성(lombok, hibernate-core 등..)이 폐쇄망 환경에 의해 다운받아 지지 않는다는 오류였습니다.
시도 1) 저장소 위치 변경
디렉터리를 찾아보니 build.gradle에서 각 서브 모듈들이 의존성 저장소를 별도 디렉터리에서 가져다 쓰도록 설정해 놓을 것을 확인했습니다.
의존성 저장소 조회 순서를 바꿔보면 해결되지 않을까 싶어서, 사용자가 임의로 추가한 libs파일을 찾도록 수정했습니다.


시도 1. 결과 실패.
시도 2) 네트워크 시간 증가
혹시 내가 모르게 내부적으로 인터넷 통신하는게 있어서 네트워크가 느려서 그런걸까 싶어서 gradle-wrapper.porperties에서 네트워크 시간을 증가 시켜봄.
//gradle-wrapper.properties
networkTimeout=100000 //gradle의 전체 네트워크 최대 작업 시간
connectionTimeout=120000 //gradle의 원격 서버(maven central, nexus, tcp/ip) 연결 수립 최대 시간
readTimeout=120000 //연결 후 실제 의존성 파일을 서버로부터 수신하는데 기다리는 최대 시간
시도 2. 결과 실패.
시도 3) 프록시 정보 추가
프록시 서버 사용으로 인한 프록시 접근이라면 정보 세팅을 해줘야한다고해서 gitlab-ci 정보 수정.
variables 의 JAVA_TOOL_OPTIONS옵션에 proxyHost, proxyPort, profiles.active 정보 세팅
(팀에서 사용하던 이전 스크립트 참고)
build:
image: gradle:8.8-jdk17
stage: build
tags:
- mobile_framework
variables:
JAVA_TOOL_OPTIONS: "-Dhttp.proxyHost=$CI_PROXY_HOST -Dhttp.proxyPort=$CI_PROXY_PORT -Dhttps.proxyHost=$CI_PROXY_HOST -Dhttps.proxyPort=$CI_PROXY_PORT -Dspring.profiles.active=dev"
시도 3. 결과
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :api:clean UP-TO-DATE
> Task :core:compileJava
> Task :core:compileJava FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':core:compileJava'.
> Could not resolve all files for configuration ':core:compileClasspath'.
> Could not download httpclient5-5.3.1.jar (org.apache.httpcomponents.client5:httpclient5:5.3.1)
> Could not get resource 'https://repo.maven.apache.org/maven2/org/apache/httpcomponents/client5/httpclient5/5.3.1/httpclient5-5.3.1.jar'.
> Could not GET 'https://repo.maven.apache.org/maven2/org/apache/httpcomponents/client5/httpclient5/5.3.1/httpclient5-5.3.1.jar'.
> The server may not support the client's requested TLS protocol versions: (TLSv1.2, TLSv1.3). You may need to configure the client to allow other protocols to be used. For more on this, please refer to https://docs.gradle.org/8.2/userguide/build_environment.html#sec:gradle_system_properties in the Gradle documentation.
> Remote host terminated the handshake
무슨 갑자기 httpclient를 못찾는다는 에러가 발생. TLS protocol을 사용할 수 없다는 오류인데 불필요한것 같아서 proxy 정보 수정한거 롤백.
Starting a Gradle Daemon (subsequent builds will be faster)
> Task :api:clean UP-TO-DATE
> Task :core:compileJava
> Task :core:compileJava FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':core:compileJava'.
> Could not resolve all files for configuration ':core:compileClasspath'.
> Could not download spring-security-config-6.1.4.jar (org.springframework.security:spring-security-config:6.1.4)
> Could not get resource 'https://repo.maven.apache.org/maven2/org/springframework/security/spring-security-config/6.1.4/spring-security-config-6.1.4.jar'.
> Premature end of Content-Length delimited message body (expected: 2,272,583; received: 654,473)
롤백하니까 또 다른 의존성 다운 못받는다는 에러가남.
시도 4) 사용자 지정 저장소에 의존성 저장
최후의 수단으로 다운받을 수 없다는 의존성을 리스트업 하고, 사용자 지정으로 만든 libs에 수동으로 tar파일을 다운받아서 저장.
시도 4. 결과
* What went wrong:
Execution failed for task ':api:bootJar'.
> Entry BOOT-INF/lib/spring-security-config-6.1.4.jar is a duplicate but no duplicate handling strategy has been set. Please refer to https://docs.gradle.org/8.2/dsl/org.gradle.api.tasks.Copy.html#org.gradle.api.tasks.Copy:duplicatesStrategy for details.
시도 5) 의존성 중복 오류
로컬에서 수동으로 추가했던 의존성이 중복된다는 오류 발생.
:core 모듈과 :api모듈의 각 build.gradle의 jar 생성 설정에 중복 전략에 중복시 무시 옵션추가.
//build.gralde(:core) 추가
tasks.named('bootJar'){
enabled = false
}
tasks.named('jar'){
enabled = true
duplicatesStrategy = DuplicatesStrategy.EXCLUDE //추가
}
//build.gradle(:api)
tasks.named('bootJar'){
duplicatesStrategy = DuplicatesStrategy.EXCLUDE //추가
}
시도 5. 결과

로컬에서 bootJar 실행시 성공적으로 빌드가 되어 jar파일 생성된것을 확인함.
이후에 gitlab ci로 빌드했을때 다운 받을수 없다는 의존성 몇개 더 수동으로 libs에 저장후 돌리니까 빌드 성공

의존성 빌드 권한 오류
gitlab ci에서 spring boot 빌드를 수행하는 명령어(./gradlew :api:clean :api:bootJar)를 작성했을때 ./gradlew: Permission denied 오류 발생

gitlab ci의 빌드 작업(job)의 jdk환경에서 ./gradlew 접근 권한이 없어서 발생하는 오류입니다.
해당 작업에서 빌드를 하기 전에 gradlew에 접근 권한을 부여하는 명령어를 추가(chmod +x gradlew)하였습니다.
https://stackoverflow.com/questions/17668265/gradlew-permission-denied
gradlew: Permission Denied
I am attempting to run gradlew from my command line, but am constantly facing the following error. Brendas-MacBook-Pro:appx_android brendalogy$ ./gradlew compileDebug --stacktrace -bash: ./gradlew:
stackoverflow.com
결과
성공
캐시 설정
gitlab ci 스크립트의 cache를 사용하면 빌드 시간을 단축하고 의존성 다운로드 횟수를 최소화 하여 gradle기능을 gitlab ci환경에 맞게 최적화 할수 있다고 합니다.
아래는 gpt한테 추천받은 캐시 설정.
//.gitlab-ci.yml 빌드 작업 부분
build:
image: gradle:8.8-jdk17
stage: build
tags:
- mobile_framework
variables:
JAVA_TOOL_OPTIONS: "-Dspring.profiles.active=dev"
## 캐시 설정 필드
cache:
key:
files:
- gradle/wrapper/gradle-wrapper.properties
paths:
- cache/caches/
- cache/notifications/
- cache/wrapper/
script:
- chmod +x gradlew
## 빌드시 캐시 사용
- ./gradlew :api:clean :api:bootJar --build-cache --gradle-user-home cache/ -x test
artifacts:
paths:
- api/build/libs/*.jar
cache
gitlab ci의 cache 블록은 지정된 파일이나 디렉터리를 gitlab또는 gitlab-runner에 저장해두었다가 다음에 동일한 작업이 실행될때 자동으로 복원해주는 기능을 합니다.
key
캐시의 고유 식별자를 지정합니다.
gradle/wrapper/gradle-wrapper.properties 파일 내용에 기반하여 캐시 키를 생성합니다.
이 파일의 내용(gradle 엔진 버전)이 변경될 때만 새로운 캐시를 생성하고 기존 캐시는 무시됩니다.
paths
캐시할 실제 디렉터리를 지정합니다.
이 디렉터리들은 작업이 시작될 때 runner에 다운로드되고, 작업이 성공적으로 완료될 때 gitlab에 업로드되어 저장됩니다.
- cache/wrapper/
- gradle wrapper 바이너리(gradle-8.8-bin.zip 등)이 저장됩니다.
- 첫 빌드 후 gradle 엔진을 다시 다운로드 하지 않아도 됩니다.
- cache/caches/
- 다운로드된 의존성 라이브러리(.jar, .pom 파일)
- 의존성 파일이 이미 존재한다면 외부 레지스트리 접근 없이 로컬 캐시에서 바로 로드해서 빌드 시간을 단축할 수 있습니다.
- cache/notifications/
- gradle관련 내부 알림 및 메타데이터
- gradle이 이전 빌드 상태를 빠르게 파악하여 빌드 효율성을 높입니다.
script
--build-cache
gradle의 자체 빌드 캐시를 활성화합니다.
gradle은 이전 빌드 단계 결과물(컴파일 클래스)을 저장해두었다가 입력 파일이 변경되지 않았으면 재실행 없이 저장된 결과물을 재사용합니다.

--gradle-user-home cache
gradle에게 로컬 캐시(사용자 홈 디렉터리)를 기본 경로(~/.gradle)가 아닌, 작업 워크스페이스 내의 cache/ 디렉터리를 사용하도록 강제합니다.
gitlab ci의 paths 설정이 cache/ 디렉터리 내부를 바라보도록 지정하였습니다. gradle이 사용하는 모든 캐시 파일은 gitlab캐시 시스템에 의해 관리됩니다.
-x test
테스트를 제외합니다.
별도의 테스트는 다른 작업에서 수행하도록 하여 빌드 시간을 단축시킬 수 있습니다.
도커 푸시 실패
gitlab-ci에서 빌드 작업을 끝낸 후, jar파일을 도커 이미지로 변경하여 개인 이미지 저장소(harbor)에 이미지를 푸시하는 작업을 해야합니다.
아래는 gitlab-ci에서 빌드 파일을 도커 이미지화 하고 저장소에 푸시하는 작업입니다.
#이미지 도커 푸시하는 작업 부분
push:
image: docker:latest
stage: push
tags:
- mobile_framework
before_script:
- echo ${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG} ${HARBOR_REPOSITORY_URI}/${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG}
- echo ${HARBOR_URL1} / ${HARBOR_USERNAME1} / ${HARBOR_PASSWORD1}
- docker login ${HARBOR_URL1} --username ${HARBOR_USERNAME1} --password-stdin
script:
- cd api
- docker build -t ${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG}
- docker tag ${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG} ${HARBOR_REPOSITORY_URI}/${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG}
- echo "Docker 이미지를 HARBER 레지스트리에 푸시 중..."
- docker push ${HARBOR_REPOSITORY_URI}/${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG}
after_script:
- docker logout
로그인 실패
작업 실행 결과 아래와 같이 Error: Cannot perform an interactive login from a non TTY device에러가 발생합니다.

이유를 찾다보니 어떤 블로그에서 stdin으로 로그인하는 법을 사용했는데 명령어가 잘못 입력되어있었다.
아래와 같이 수정하니 해결.
echo ${HARBOR_PASSWORD1} | docker login ${HARBOR_URL1} --username ${HARBOR_USERNAME1} --password-stdin
결과
성공
unknown authority 오류

도커로 harbor에 로그인을 하려고 하는데 x509 : certification signed by unknown authority 오류가 발생했습니다.
이유는 https접근을 해야하는데 인증서가 없어서 권한 오류가 발생한것이었습니다.
인증서를 어떻게 가져올까 고민하다가 다른 프로젝트에서 volume 설정을 하고있는것을 확인.
/var/run/docker.sock파일은 로컬 시스템에서 도커 데몬과 통신할 수 있는 소켓 파일입니다.
이 소켓 파일을 gitlab-runner의 config.toml에서 volumes에 추가를 해줍니다.

이러한 결과는 소켓 파일을 https인증서가 있는 호스트 리눅스 서버에 마운트를 시켜주어 https통신이 가능해지는것 같습니다.
(확실하지 않습니다. 반박 가능)
참고로 docker-compose.yml 설정에 gitlab-runner 컨테이너가 호스트 리눅스 서버의 도커 데몬 통신 소켓에 접근할 수 있도록 권한을 부여하도록 하였습니다.
이 설정을 통해 runner컨테이너에서 실행되는 도커 명령어를 호스트의 도커 데몬이 받아서 실행시키게 됩니다.
즉, runner가 호스트의 도커 클라이언트 역할이 되는것입니다.

그렇기 때문에 작업을 수행하는 runner 내부에서 수행되는 docker login 명령어가 https인증서를 가지고 있는 호스트 리눅스 서버에서 실행되어 https통신이 가능해지는 것입니다.
파일 권한 오류
배포 환경은 OKD라고 운영 모니터링 및 콘솔 도구를 제공하는 제품을 사용하고 있습니다. (kubernates를 사용한다고 보면 됩니다.)
아무튼, spring boot 프로젝트의 도커 이미지까지 생성이 되었고 이미지를 okd에 올려서 컨테이너를 생성하려고 하니 로그 파일 관련해서 오류 발생.
오류 로그
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112)
at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63)
at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:359)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:310)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298)
at com.hana.api.ApiApplication.main(ApiApplication.java:22)
... 8 more
Caused by: java.lang.IllegalStateException: Logback configuration error detected:
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[FILE] - Failed to create parent directories for [/BiCoLab/logs/api.log]
ERROR in ch.qos.logback.core.rolling.RollingFileAppender[FILE] - openFile(/BiCoLab/logs/api.log,true) call failed. java.io.FileNotFoundException: /BiCoLab/logs/api.log (No such file or directory)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.reportConfigurationErrorsIfNecessary(LogbackLoggingSystem.java:270)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:248)
at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:80)
at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:60)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:188)
at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:332)
... 27 more
Suppressed: java.io.FileNotFoundException: /BiCoLab/logs/api.log (No such file or directory)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:291)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:234)
at ch.qos.logback.core.recovery.ResilientFileOutputStream.<init>(ResilientFileOutputStream.java:26)
at ch.qos.logback.core.FileAppender.openFile(FileAppender.java:206)
at ch.qos.logback.core.FileAppender.start(FileAppender.java:126)
at ch.qos.logback.core.rolling.RollingFileAppender.start(RollingFileAppender.java:104)
at ch.qos.logback.core.model.processor.AppenderModelHandler.postHandle(AppenderModelHandler.java:84)
at ch.qos.logback.core.model.processor.DefaultProcessor.secondPhaseTraverse(DefaultProcessor.java:257)
at ch.qos.logback.core.model.processor.DefaultProcessor.secondPhaseTraverse(DefaultProcessor.java:253)
at ch.qos.logback.core.model.processor.DefaultProcessor.secondPhaseTraverse(DefaultProcessor.java:253)
at ch.qos.logback.core.model.processor.DefaultProcessor.traversalLoop(DefaultProcessor.java:90)
at ch.qos.logback.core.model.processor.DefaultProcessor.process(DefaultProcessor.java:106)
at ch.qos.logback.core.joran.GenericXMLConfigurator.processModel(GenericXMLConfigurator.java:208)
at org.springframework.boot.logging.logback.SpringBootJoranConfigurator.processModel(SpringBootJoranConfigurator.java:122)
at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:170)
at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:122)
at ch.qos.logback.core.joran.GenericXMLConfigurator.doConfigure(GenericXMLConfigurator.java:65)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.configureByResourceUrl(LogbackLoggingSystem.java:280)
at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:243)
... 31 more
Failed to create parent directories for [/BiCoLab/logs/api.log] 이런 내용을 보아하니 로그 파일 생성하는데 권한이 없어서 발생하는 오류인걸로 보였음.

로그 설정 파일을 확인해보니 /BioCoLab/logs/api.log 경로에 파일을 생성하고 있는데 okd 컨테이너에서 로그 생성을 하려는데 해당 경로에 접근할수가 없어서 에러가 나는것이었습니다.
.gitlab-ci.yml파일에 빌드 명령어 수행 전에 각 로그 파일을 생성할 디렉터리를 생성하고 권한을 변경해주는 명령어를 추가했습니다.
RUN mkdir -p /BiCoLab/logs && chown 1000:1000 /BiCoLab/logs
RUN mkdir -p /BiCoLab/logs && chmod 777 /BiCoLab/logs

결과
성공
결과
stages:
- build
- push
variables:
# COMMIT_BRANCH: ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}
COMMIT_BRANCH: ${CI_COMMIT_BRANCH}
IMAGE_TAG: ${CI_COMMIT_TAG}
HARBOR_URL1: ${HARBOR_URL}
HARBOR_USERNAME1: ${HARBOR_USERNAME}
HARBOR_PASSWORD1: ${HARBOR_PASSWORD}
HARBOR_PROJECT: nextti
HARBOR_REPOSITORY_URI: ${HARBOR_IP}/${HARBOR_PROJECT}
HARBOR_REPOSITORY_NAME: mobile_framework_api
build:
image: gradle:8.8-jdk17
stage: build
tags:
- mobile_framework
variables:
JAVA_TOOL_OPTIONS: "-Dspring.profiles.active=dev"
cache:
key:
files:
- gradle/wrapper/gradle-wrapper.properties
paths:
- cache/caches/
- cache/notifications/
- cache/wrapper/
script:
- chmod +x gradlew
- ./gradlew :api:clean :api:bootJar --build-cache --gradle-user-home cache/ -x test
artifacts:
paths:
- api/build/libs/*.jar
rules:
- if: $CI_COMMIT_TAG =~ /^(prod|uat)-.*$/
push:
image: docker:latest
stage: push
tags:
- mobile_framework
services:
- name: docker:dind
before_script:
- echo ${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG} ${HARBOR_REPOSITORY_URI}/${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG}
- echo ${HARBOR_PASSWORD1} | docker login ${HARBOR_URL1} --username ${HARBOR_USERNAME1} --password-stdin
script:
- cd api
- docker build -t ${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG} .
- docker tag ${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG} ${HARBOR_REPOSITORY_URI}/${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG}
- echo "Docker 이미지를 HARBER 레지스트리에 푸시 중..."
- docker push ${HARBOR_REPOSITORY_URI}/${HARBOR_REPOSITORY_NAME}:${IMAGE_TAG}
after_script:
- docker logout
rules:
- if: $CI_COMMIT_TAG =~ /^(prod|uat)-.*$/
참조
https://stackoverflow.com/questions/17668265/gradlew-permission-denied
gradlew: Permission Denied
I am attempting to run gradlew from my command line, but am constantly facing the following error. Brendas-MacBook-Pro:appx_android brendalogy$ ./gradlew compileDebug --stacktrace -bash: ./gradlew:
stackoverflow.com
https://jusths.tistory.com/302
~/.zprofile가 무시된다.
문제 GitHub의 Container Registry인 GHCR로 로그인을 하려 했는데 에러가 발생했다. $ echo $CR_PAT | docker login ghcr.io -u $GITHUB_USERNAME --password-stdin // 에러는 아래와 같다. Error: Cannot perform an interactive login from a
jusths.tistory.com
https://jfbta.tistory.com/275#google_vignette
[Error] is a duplicate but no duplicate handling strategy has been set. Please refer to https://docs.gradle.org/8.1.1/dsl/org.gr
Maven에서 Gradle로 마이그레이션 하는 과정에서 해당 에러가 발생하였다. 굉장히 쉽게 해결할 수 있었다. tasks { war { duplicatesStrategy = DuplicatesStrategy.EXCLUDE } } tasks { war { duplicatesStrategy = DuplicatesStrategy
jfbta.tistory.com
'develop > server' 카테고리의 다른 글
| [GitLab CI] React(vite) 배포 과정(삽질) (0) | 2025.11.12 |
|---|---|
| [npm] 폐쇄망 환경에서 배포시 의존성 문제 해결하기 (0) | 2025.11.10 |
| [ERROR] GitLab pipeline pending (Job is stuck. Check runners.) (0) | 2025.11.09 |
| [Docker] 폐쇄망 React + Nginx 도커 이미지로 배포 (1) | 2025.11.07 |
| [GitLab] GitLab Runner 등록 (0) | 2025.11.06 |