1. 프로젝트 구조
프로젝트 구조는 다음과 같다. Jenkinsfile, frontend폴더, bacnekd폴더가 가장 최상단에 있고 그 밑에 Dockerfile이 있다.
2. Jenkinsfile
tools에서 이전에 설치한 메이븐 이름을 쓴다. M3로 설정했으므로 maven "M3"을 적는다. stages는 네 단계로 나눴는데, 다음과 같다.
1) Docker kill
이미 프론트엔드, 백엔드 돌아가고있는 도커가 있다면 멈추고 해당 컨테이너를 지웠다.
만약 그 컨테이너가 없다면 오류가 나면서 빌드가 멈추기 때문에 || 연산을 사용해서 있든 없든 빌드가 계속되도록 했다.
2) Prepare
checkout scm 명령어로 깃 레파지토리를 가져온다.
성공한다면 prepare success, 실패한다면 prepare fail 메세지를 출력하도록 했다.
3) Frontend Build
프로젝트 최상단에서 frontend 폴더로 들어간다. 이 때, dir명령어를 사용한다.
위치에 맞게 잘 들어갔는지 확인을 위해서 echo 명령어를 썼고, 그 다음 도커 이미지를 만들었다.
프론트엔드 도커파일은 내부적으로 nginx를 사용해 80포트를 쓴다. 따라서 8081:80 을 써서 내부 80포트를 외부 8081포트로 실행되게끔 한다.
이 때 컨테이너 이름은 fe로 했다.
4) Backend Build
위에서 frontend 폴더로 갔으므로 ./backend로 가야 정확한 위치에 접근할 수 있다. frontend 폴더와 backend 폴더는 같은 레벨에 위치해있기 때문이다.
메이븐 clean package를 하고 dockerfile을 이용해 이미지를 생성한다. 스프링프로젝트는 3000포트를 사용하도록 했으므로 3000:3000을 썼다.
컨테이너 이름은 be로 했다.
pipeline {
agent any
tools {
maven "M3"
}
stages {
stage('Docker kill'){
steps {
sh 'docker stop fe || true && docker rm fe || true'
sh 'docker stop be || true && docker rm be || true'
}
post {
success {
echo "kill success"
}
failure {
echo "kill fail"
}
}
}
stage('Prepare') {
steps {
checkout scm
}
post {
success {
echo " prepare success"
}
failure {
echo "prepare fail"
}
}
}
stage('Frontend Build') {
steps {
dir('frontend'){
echo "here is frontend dir"
sh 'docker build -t frontend .'
sh 'docker run -d --name fe -p 8081:80 frontend'
}
}
}
stage('Backend Build') {
steps {
dir('./backend'){
echo "here is backend dir"
sh "mvn -Dmaven.test.failure.ignore=true clean package"
sh 'docker build -t backend .'
sh 'docker run -d --name be -p 3000:3000 backend'
}
}
}
}
}
3. Frontend
1) Dockerfile
노드로 먼저 package를 다운로드 받은 뒤 build한다.
그 파일들을 nginx를 이용해 실행시킨다.
# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY ./ .
RUN npm run build
# production stage
FROM nginx-alpine as production-stage
RUN mkdir /app
COPY --from=build-stage /app/dist /app
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
2) nginx.conf
https://cli.vuejs.org/guide/deployment.html#docker-nginx에서 복사해왔다. 프론트엔드폴더의 최상단에 넣으면 된다.
이 설정파일을 1)에서 copy시켜 사용한다.
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /app;
index index.html;
client_max_body_size 10M;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
}
4. Backend
1) Dockerfile
target 밑에 생성된 jar 파일을 app.jar로 copy한 후 실행시킨다.
FROM openjdk:8-jdk-alpine
COPY target/*.jar app.jar
ENTRYPOINT ["java", "-jar", "app.jar"]
EXPOSE 3000
5. 주의할 점
dockerfile에서 alpine을 전부 붙여서 사용했다. node alpine, jdk alpine, nginx alpine.. 경량화된 버전이라 필요한 부분만 가져와서 속도가 빨라진다는 장점이 있지만 혹시 docker container 내부로 접속할 일이 생긴다면 alpine 버전말고 다른 버전을 사용해야 한다.
'기록 > CI&CD' 카테고리의 다른 글
[Jenkins] gradle 설정 (0) | 2022.10.06 |
---|---|
[NLP] Docker로 Konlpy 사용하는 Flask 배포 (0) | 2022.09.23 |
[AWS] 같은 브랜치에 있는 프론트엔드, 백엔드 자동배포하기 (5) jenkins 컨테이너 내부에 docker 설치 및 Webhook 설정 (0) | 2022.08.17 |
[AWS] 같은 브랜치에 있는 프론트엔드, 백엔드 자동배포하기 (4) Jenkins 설치 및 설정 (0) | 2022.08.13 |
[AWS] 같은 브랜치에 있는 프론트엔드, 백엔드 자동배포하기 (3) Nginx 설치 및 설정 (0) | 2022.08.12 |
댓글