CI/CD 파이프라인에서 Jenkins는 자동화 도구로 널리 사용됩니다. 특히, Docker를 사용하면 Jenkins를 손쉽게 설치하고 실행할 수 있으며, Docker 컨테이너에서 일관된 환경에서 애플리케이션을 빌드하고 배포할 수 있습니다.
Docker 컨테이너로 Jenkins를 실행하고, 이를 통해 애플리케이션을 빌드하여 Docker 이미지로 생성하고 AWS에 배포하는 하는 중 권한 관련 문제 트러블이 생겨 정리 해보고자 합니다
먼저 Docker를 이용해 Jenkins를 실행합니다. 공식 Jenkins 이미지를 사용하여 Docker 컨테이너를 실행할 수 있습니다.
docker run -d -p 8080:8080 -p 50000:50000 \
--name jenkins \
-v jenkins_home:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
jenkins/jenkins:lts
-v /var/run/docker.sock:/var/run/docker.sock 옵션을 통해 Jenkins가 호스트의 Docker 데몬에 접근할 수 있게 합니다.
이 설정은 Jenkins가 Docker 컨테이너를 관리하고 빌드할 수 있도록 도와줍니다.
jenkins_home 볼륨은 Jenkins 설정과 데이터를 지속적으로 유지하기 위해 필요합니다.
Jenkins가 처음 실행되면 브라우저를 통해 초기 설정을 완료해야 합니다.
docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
Jenkins에서 애플리케이션을 빌드하고, Docker 이미지를 생성한 후, 이를 AWS에 배포하는 파이프라인을 구성합니다.
pipeline {
agent any
environment {
DOCKER_IMAGE = 'my-docker-repo/my-app:latest'
AWS_S3_BUCKET = credentials('AWS_S3_BUCKET')
AWS_REGION = credentials('AWS_REGION')
AWS_ACCESS_KEY = credentials('AWS_ACCESS_KEY')
AWS_SECRET_KEY = credentials('AWS_SECRET_KEY')
}
stages {
stage('Clone Repository') {
steps {
git branch: 'main', url: 'https://github.com/your-repo/your-app.git'
}
}
stage('Build Application') {
steps {
sh './gradlew clean build'
}
}
stage('Build Docker Image') {
steps {
script {
withCredentials([usernamePassword(credentialsId: 'dockerhub', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
sh '''
echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
docker build -t $DOCKER_IMAGE .
docker push $DOCKER_IMAGE
'''
}
}
}
}
stage('Configure AWS') {
steps {
sh '''
echo "cloud:" > src/main/resources/application.yml
echo " aws:" >> src/main/resources/application.yml
echo " s3:" >> src/main/resources/application.yml
echo " bucket: $AWS_S3_BUCKET" >> src/main/resources/application.yml
echo " region:" >> src/main/resources/application.yml
echo " static: $AWS_REGION" >> src/main/resources/application.yml
echo " stack:" >> src/main/resources/application.yml
echo " auto: false" >> src/main/resources/application.yml
echo " credentials:" >> src/main/resources/application.yml
echo " accessKey: $AWS_ACCESS_KEY" >> src/main/resources/application.yml
echo " secretKey: $AWS_SECRET_KEY" >> src/main/resources/application.yml
'''
}
}
stage('Deploy Application') {
steps {
sh '''
docker stop my-app || true
docker rm my-app || true
docker run -d --name my-app -p 8080:8080 \
-e AWS_ACCESS_KEY=$AWS_ACCESS_KEY \
-e AWS_SECRET_KEY=$AWS_SECRET_KEY \
-e AWS_REGION=$AWS_REGION \
-e AWS_S3_BUCKET=$AWS_S3_BUCKET \
$DOCKER_IMAGE
'''
}
}
}
post {
always {
sh 'docker logout'
}
}
}
Jenkins 대시보드에서 "New Item"을 클릭하고, 파이프라인을 선택하여 새로운 Job을 생성합니다.
소스 코드 관리에서 GitHub 저장소 URL을 입력하고, Jenkinsfile의 위치를 지정합니다.
파이프라인이 실행되면 Jenkins가 GitHub에서 소스 코드를 가져와 애플리케이션을 빌드하고, Docker 이미지를 생성 및 배포합니다.
Jenkins가 Docker 데몬에 접근할 수 없는 경우, 다음과 같은 권한 오류가 발생할 수 있습니다:
WARNING! Your password will be stored unencrypted in /var/jenkins_home/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-stores
Login Succeeded
+ docker build -t kanguk148/jenkins:test .
DEPRECATED: The legacy builder is deprecated and will be removed in a future release.
Install the buildx component to build images with BuildKit:
https://docs.docker.com/go/buildx/
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.47/build?buildargs=%7B%7D&cachefrom=%5B%5D&cgroupparent=&cpuperiod=0&cpuquota=0&cpusetcpus=&cpusetmems=&cpushares=0&dockerfile=Dockerfile&labels=%7B%7D&memory=0&memswap=0&networkmode=default&rm=1&shmsize=0&t=kanguk148%2Fjenkins%3Atest&target=&ulimits=%5B%5D&version=1": dial unix /var/run/docker.sock: connect: permission denied
script returned exit code 1
이 문제는 Jenkins 사용자가 Docker에 접근할 권한이 없기 때문에 발생합니다. 이를 해결하려면 Jenkins 사용자를 docker 그룹에 추가해야 합니다.
Docker 소켓의 권한을 확인합니다
docker exec -it -u root jenkins bash
ls -l /var/run/docker.sock
소켓의 권한이 적절하지 않다면, 다음 명령어로 권한을 수정합니다:
chmod 666 /var/run/docker.sock
Jenkins 컨테이너 내부의 Docker 그룹 GID가 호스트 시스템의 Docker 그룹 GID와 일치하는지 확인합니다. 일치하지 않는다면, 다음 명령어로 수정합니다:
groupmod -g <호스트_도커_GID> docker
Jenkins 사용자를 Docker 그룹에 다시 추가합니다:
usermod -aG docker jenkins
Jenkins 컨테이너를 재시작합니다:
docker restart jenkins