1 개발자가 만든 테스트코드를 TEST & BUILD하고, Dockerfile을 작성하여 이를 Build하여 실행파일을 이미지화하여 Docker Hub에 Push까지 하는 작업을 하는 환경을 위해 EC2인스턴스를 생성한다.
2 ssh를 통해 인스턴스에 접속한다.
# 이름 설정
sudo hostnamectl set-hostname jenkins-docker
exec bash
# USER에 docker 그룹 부여
sudo usermod -aG docker $USER
exit
# 재접속 시 도커 사용 가능
3 git clone
개발자가 테스트 코드를 올려놓은 git 저장소를 clone해서 가져온다.
# 현재 테스트 코드가 있는 저장소
git clone https://github.com/tkfka1/GoormUniversity-course-registration.git
4 docker 설치
5 Java설치
개발자의 코드가 Java Spring Boot로 작업되었기 때문에 java를 설치한다.
sudo apt update
sudo apt search openjdk-11-jdk
sudo apt install openjdk-11-jdk
6 Gradle 설치
Gradle은 Ant와 Maven의 최고의 특징들을 결합한 것이다. 스크립팅에 XML을 사용하는 이전 버전과 달리 Gradle은 Java 플랫폼용 동적 객체 지향 프로그래밍 언어인 Groovy를 사용하여 프로젝트를 정의하고 스크립트를 작성한다.
Building Java Projects with Gradle 참조
# /tmp 디렉토리에서 Gradle 이진 전용 zip 파일을 다운로드
VERSION=8.0.2
wget https://services.gradle.org/distributions/gradle-${VERSION}-bin.zip -P /tmp
sudo unzip -d /opt/gradle /tmp/gradle-${VERSION}-bin.zip
"sudo : unzip : command not found"라는 오류 메시지가 표시되면 unzip 패키지를 설치
$ sudo apt install unzip
# gradle 설치 디렉터리를 가리키는 latest라는 이름의 심볼 링크 설정
sudo ln -s /opt/gradle/gradle-${VERSION} /opt/gradle/latest
# 환경변수 설정
sudo vi /etc/profile.d/gradle.sh # 아래 두줄 작성 후 저장
export GRADLE_HOME=/opt/gradle/latest
export PATH=${GRADLE_HOME}/bin:${PATH}
# 스크립트 권한 설정
sudo chmod +x /etc/profile.d/gradle.sh
source /etc/profile.d/gradle.sh
# Gradle 설치 확인
gradle -v
-> 출력 결과
Welcome to Gradle 8.0.2!
일일이 작업할때마다 gradle을 설치하지 않아도, 즉 gradle없이도 gradle을 사용하게 해주는 것이 gradle wrapper이다.
Gradle wrapper
gradle wrapper --gradle-version 8.0.2
./gradlew build
java -jar <파일 명>.jar
1 Dockerfile 작성
vi Dockerfile
FROM gradle:8.0.2-jdk11 AS mbuilder # gradle 8.0.2버전, java 11버전
COPY . /usr/src/
WORKDIR /usr/src/
RUN ./gradlew build # build/libs디렉터리 생성 및 jar파일 생성
FROM openjdk:11-jre # java 11버전
COPY --from=mbuilder /usr/src/build/libs/finalproject-0.0.1-SNAPSHOT.jar /usr/src/
CMD ["java","-jar","/usr/src/finalproject-0.0.1-SNAPSHOT.jar"] # jar파일 배포
# Dockerfile 빌드
docker build -t backend:testv1 .
2 개발자분에게 물어보니 해당 test디렉터리는 필요가없는 부분이여서 생략하고 빌드해도 된다고 하였다.
vi build.gradle # gradle 빌드 설정 파일 접속
. . .
test.onlyIf {
!project.hasProperty('test')
}
따라서 test 디렉터리에 대해서 무시하는 코드를 빌드 설정 파일 마지막부분에 추가하였고 이후 다시 Dockerfile을 빌드해보니 정상적으로 빌드가 되는 것을 알 수 있다.
3 Docker Hub에 Push, 생성한 이미지를 DockerHub에 Push하기 위해서는 일치하는 계정명이 있어야 하기때문에 tag작업을 한다.
docker login # id/passwd 입력
docker tag backend:testv1 suhwan11/backend:testv1
docker push suhwan11/backend:testv1
4 ArgoCD로 배포
git add .
git commit -m "change back image to test back image"
git push
ArgoCD는 자신과 연동된 Git에 새로운 Push가 들어왔음을 감지하고 새로운 image가 적용된 컨테이너를 가지고 있는 파드를 Deployment에 의해서 Rolling Update로 배포하는 것을 볼 수 있다.
1 nginx의 환경변수 설정
해당 테스트 코드는 Vue.js로 이루어져 있으며 node.js와 nginx를 이용하여 Dockerfile을 작성할 예정이다.
Vue.js프로젝트는 기본적으로 정적인 웹페이지이며 이를 서빙하기 위해 Nginx서버를 사용한다.
현재 프로젝트에 nginx.config파일이 없으므로 해당 파일을 먼저 작성해야 한다.
Nginx 서버가 동작하는 방식을 결정하는 다양한 옵션과 지시어를 포함하는 파일
전체적인 구조
# nginx.config
server {
listen 80;
server_name _;
location / {
root /usr/share/nginx/html; # 서비스하는 파일들이 위치하는 디렉토리 경로 지정
index index.html; # 해당 디렉토리에서 요청된 파일이 없을 경우, Nginx가 우선적으로 찾는 파일 이름 정의
try_files $uri $uri/ /index.html; # 파일을 찾는 순서 정의
}
}
위의 설정 파일을 사용하면, Nginx는 웹 서버로 작동하고, 프론트엔드 웹 애플리케이션을 호스팅하며, 클라이언트 요청에 따라 적절한 파일을 제공한다.
또한, 해당 파일이 없을 경우 index.html을 반환하여 SPA의 라우팅 처리를 지원한다.
2 Dockerfile 작성
해당 도커파일은 두 개의 빌드단계로 작성한다.
vi Dockerfile
FROM node:16-alpine AS builder
WORKDIR /app # /app을 작업디렉토리로 설정
COPY package*.json ./ # 필요한 모듈 복사
RUN npm install # 의존성 패키지 설치
COPY . . # 모든 파일 복사
RUN npm run build # 프로젝트 빌드
FROM nginx:stable-alpine
COPY ./nginx.conf /etc/nginx/conf.d/default.conf # nginx.conf 복사
COPY --from=builder /app/dist /usr/share/nginx/html # 빌드된 프로젝트 파일 복사
EXPOSE 80 # 80번 포트 노출
CMD ["nginx", "-g", "daemon off;"] # 포그라운드로 nginx실행
로컬 컴퓨터 환경이 아닌, AWS 인스턴스를 통해 확인하려는 와중 다른 팀원에 의해 프론트 테스트 코드 도커라이징 완료.
3 이미지 생성 및 ArgoCD로 배포
Backend와 마찬가지로 Dockerfile을 빌드하고 생성된 이미지를 Docker Hub에 Push한다
ArgoCD와 연동중인 Git에 Frontend Deployment의 yaml파일에서 파드의 image를 Docker Hub에 Push된 이미지로 교체한다.
이후 add와 commit, Push를 한다.
ArgoCD에서 새로운 Push를 감지하고 새로운 이미지가 적용된 컨테이너를 가진 파드를 Deployment에 의해서 Rolling Update로 배포한다.
AWS콘솔에서 기존의 Frontend Ingress에 의해 생성된 ALB의 DNS Name을 브라우저에 입력하면 정상적으로 Vue로 작성된 웹페이지가 나타나는 것을 확인.