gitlab 프로젝트 CI/CD환경 구축하기 최종장 -프로젝트 배포 자동화하기-

1. jenkins 컨테이너 실행 옵션

 

이전에 jenkins docker in docker로 실행한 옵션으로 하면.. 컨테이너 삭제하면 모든 옵션이 초기화됨

 

docker run \
  -d \
  -p 8080:8080 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  --name jenkins \
  -u root \
  mbodji/jenkins-withdocker:v1.0

 

 

현재 아래와 같이 켜진 상태에서 한번 컨테이너 지워보자

 

 

끄고 다시 켜보면...

 

 

 

모든 옵션 초기화되어있음..

 

근데 이전에 실행해봤던 jenkins는 컨테이너 삭제해도 다시 키면 옵션이 유지되어 있더라구

 

왜 그런지... 알아봤더니

 

[CI/CD] 젠킨스와 도커로 프로젝트 자동배포하기(3) - Jenkins (crispyblog.kr)

 

Crispy's Blog

 

crispyblog.kr

 

여기서 알려주는 옵션대로 해볼까..?

 

그러면 docker out docker 방식으로 공식 jenkins 이미지 이용해서 옵션도 그대로고 docker도 사용할 수 있다던데

 

$ docker run -d --name jenkins -p 8080:8080 -v /jenkins:/var/jenkins_home -v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock -u root jenkins/jenkins:lts

 

공식 이미지에는 내가 이전에 해둔게 있다보니까

 

바로 로그인으로 나오더라고??

 

 

이러면 예전에 사용했던 옵션 그대로 남아있더라

 

백엔드 빌드도 잘 되는지 해보자

 

 

잘 되네...

 

최종적으로 핵심 옵션 살펴보면

 

-d는 백그라운드 모드로 실행해서.. shell이 꺼져도 계속 실행될 수 있도록

 

-v /jenkins:/var/jenkins_home 이 옵션이 컨테이너가 삭제되어도 설정해놓은 옵션을 유지시켜준다

 

-v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock는 도커 컨테이너 내부에서 호스트의 도커를 사용할 수 있게 한다

 

 

2. Dockerfile 수정

 

backend를 docker image로 만들다보니 여러가지 문제를 만나다가.. 고치면서

 

대충 어떤식으로 만들어야할지 익히긴 했다

 

FROM python:3.8

WORKDIR /SubPjt2/backend/

COPY . . ##얘 뭔가 빼도 될것 같은 느낌

RUN pip install --upgrade pip
RUN pip install tensorflow
RUN pip install CMake
RUN pip install dlib
RUN pip install torch
RUN pip install torchvision

FROM node:16.18

WORKDIR /SubPjt2/backend/

COPY --from=0 . .

COPY . .

RUN npm install

EXPOSE 3001

CMD ["npm", "start"]

 

자세한건 언젠가 공부할 기회가 있으면...(있을지 모르겠지만..)

 

FROM python:3.8은 docker에서 제공하는 3.8버전의 베이스 이미지를 컨테이너에 깔아놓는다

 

WORKDIR은 현재 작업 디렉토리를 설정하고

 

COPY . .은 현재 작업 디렉토리(.)의 모든 파일을 현재 컨테이너의 경로(.)으로 복사해온다

 

그리고 RUN부터 한 줄씩 차례대로 명령을 수행해서 파이썬 패키지를 설치한다

 

그리고 그 위에 nodejs에서 16.18버전의 베이스 이미지를 깔고

 

COPY --from=0 . .은 바로 위 스테이지(파이썬 깔아놓은 스테이지)에서 설치한 내용을 현재 디렉토리로 모두 복사해오고

 

그 아래 COPY . .은 현재 작업 디렉토리의 모든 파일을 현재 이미지로 복사해온다..

 

이게 나는 생각하기에.. 0번째 스테이지에서 설치한 내용 복사해오면..(COPY --from=0 . .)

 

당연히 현재 디렉토리의 모든 파일도 거기에 복사해있으니까 가져올줄 알았는데 아닌가봐

 

그냥 0번째 스테이지의 COPY . .을 빼버릴까??

 

COPY . . 안하고 RUN npm install하면 package.json이 없다고 에러뜨더라고

 

아무튼 마지막 EXPOSE 3001은 3001번 포트에 노출시킨다는 뜻 같고

 

CMD 부분은 docker run 했을때 실행되는 명령을 나타낸다네

 

 

아무튼 이러면 도커 이미지로 잘 만들어지고..

 

만들어진 도커 이미지는 AWS EC2 서버내에 저장되더라고

 

 

 

3. <none> 이미지 지우기

 

도커 이미지로 만들면 <none>이라는 쓸데없는 이미지가 만들어지더라

 

왜 인지는 모르겠지만..

 

docker rmi <이미지 명>은 해당 이미지를 삭제하는 명령어다

 

<none>이라고 치면 안먹힘

 

https://jhkimmm.tistory.com/9

 

[Docker] none 이미지 삭제하기

도커 이미지를 빌드하다보면 위와 같은 이미지들이 쌓이곤 하는데 일일히 ID입력해서 지우기는 너무 번거롭습니다. 이미지들을 일괄적으로 한번에 삭제하는 방법을 알아보겠습니다. docker rmi $(d

jhkimmm.tistory.com

 

다음 명령을 수행하면 모든 <none>이미지를 삭제한다

 

$ docker rmi $(docker images -f "dangling=true" -q)

 

근데 삭제하다보면 꼭 삭제가 안되는 이미지가 있음

 

 

이런 경우 rmi 뒤에 -f를 붙여서 강제로 지운다

 

$ docker rmi -f $(docker images -f "dangling=true" -q)

 

4. backend 배포하기

 

빌드된 백엔드 도커 이미지를 EC2 서버내에서 실행하면 누구나 해당 서버로 접속할 수 있게 된다

 

이것이 배포

 

도커 이미지로 빌드하면 EC2 서버내에 존재하므로 jenkins 명령에 해당 이미지를 run하면 되겠다

 

이게 현재 jenkins가 host의 도커를 사용해서 도커 이미지로 만든게 호스트의 EC2에 저장되고..

 

jenkins에서 명령을 실행하면 해당 도커 이미지가 실행되고...

 

$ docker -d -p 3001:3001 --name server -u root back_server

 

자세한 명령은 모르지만.. -p 3001:3001로 3001번 포트로 실행시키고.. -d는 백그라운드에서 실행시키고..

 

 

어떻게 실행시키면.. 잘 되지만 여기까지 우여곡절?이 있었다고 해야하나

 

DB가 local의 DB에 연결되어있으면 backend가 켜지지 않는다

 

특히 -d 옵션이 백그라운드 모드라 이게 콘솔에 에러 로그가 안찍히다보니 에러 찾기가 쉽지 않을 수 있다

 

에러가 발생한다고 생각하면 -d를 빼고 콘솔 모드에서 실행시켜서 에러 로그를 적극적으로 확인하자

 

 

5. frontend 도커 이미지로 빌드하기

 

react frontend는 npm run build로 빌드 파일을 쉽게 만들 수 있는데..

 

문제는 얘를 EC2로 보내야한다는 것

 

그리고 보냈다고 치더라도.. 빌드 파일을 실행시키고.. 얘를 우리 백엔드랑 연결시켜야하는데

 

이게 아무리 찾아봐도 못찾겠음(나오는데 뭔소린지 몰라서 안하는건지... 진짜 없는건지...)

 

그래서 위에 백엔드 도커 파일 작성한 것처럼 프론트엔드도 도커 파일을 작성해서 이미지로 만들려고 한다

 

도커 이미지로 만들면 EC2로 바로 전송이 되고.. docker run하면 프론트엔드도 실행될테니까.. 배포도 쉽게 될것

 

FROM node:16.18

WORKDIR /SubPjt2/frontend/

COPY package.json .
COPY package-lock.json .

RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

 

 

node 16.18버전을 베이스 이미지로 깔고.. 

 

WORKDIR은 현재 작업 디렉토리를 설정하고

 

package.json이랑 package-lock.json을 복사해서 현재 작업 디렉토리로 가져온다

 

그리고 npm install을 실행해서 패키지 설치

 

그리고 나머지 파일을 COPY . .으로 현재 디렉토리에 모두 복사해옴

 

CMD는 npm start이고.. docker run되면 실행되는 명령

 

 

프론트엔드 개발자를 위한 Docker로 React 개발 및 배포하기 (velog.io)

 

프론트엔드 개발자를 위한 Docker로 React 개발 및 배포하기

리액트 앱을 도커 컨테이너에 쉽게 띄워보자! 이 포스트는 Youtube의 Sanjeev Thiyagarajan라는 분이 올려주신 Docker + ReactJS tutorial 영상을 따라 쉽게 도커를 이해할 수 있도록 정리한 내용이다.

velog.io

 

 

도커 이미지 만들때 캐싱되는데 npm install을 COPY . . 뒤에 하면 소스코드가 조금이라도 달라지면 항상 npm install을 수행해서 시간이 낭비된다는데..

 

아무튼 캐싱되는건 맞긴함

 

도커 이미지 만들때 신기하게 이미 만들어져있는건 또 안만들고 가져옴

 

실제로 빌드해보면 성공적으로 이미지가 만들어진다

 

 

이미 해둔거라 그런지 캐싱되어있는데.. 아무튼 도커는 이미 해놓은거는 또 하지 않으려고 한다

 

 

6. invalid host header

 

프론트, 백엔드 모두 도커이미지로 만들어서 실행시키고 접속해보면..

 

이게 invalid host header 에러가 나타날 수도 있다

 

https://velog.io/@shimsungbo/React-Invaild-host-Header

 

[React] Invaild host Header

React : Invalid host header 리액트에 외부에서 도메인을 접속할려고 할 때 Invail host header라는 오류로 접속이 안됐습니다. 구글링 결과 webpackDevServer.config.js 안에 {disableHostCheck: tru

velog.io

 

frontend의 webpackDevServer.config.js에 들어가서..

 

 

 

바로 안에 disableFirewall 부분이 있는데

 

!proxy !! ~  부분 주석처리하고 const disableFirewall = true;로 고치면 에러 안나고 접속가능

 

 

7. 배포 테스트

 

도커 이미지로 만든 프론트엔드와 백엔드를 모두 run한다.

 

run 명령은 docker run -d -p <포트>:<포트> --name (이름) -u root (도커 이미지 이름)

 

그 외에 필요한 옵션 있으면 찾아서 추가해보고

 

디버깅을 해야한다면 -d를 빼서 콘솔모드로 수행

 

도메인 주소로 접속해보면...

 

접속이 안될거임.. 왜냐하면 개발시 proxy가 localhost에 맞춰져있다보니

 

서버 구축에 proxy 설정을 도메인 주소로 모두 고치고..

 

(frontend의 package.json에 맨 아래 proxy:)

 

(frontend의 config에서 webpack.config.dev.js에서 devServer 설정한 부분에 proxy /을 고쳐주고)

 

그리고 접속해보면..

 

 

이게 배포인가..?

 

개발환경이랑 배포환경이랑 다르다보니.. 뭔가 안되는게 많다..

 

(그런건 알아서 고쳐야겠지..)

 

 

8. CI/CD

 

지금까지 공부한 내용을 바탕으로 webhook 설정하고

 

프론트와 백엔드 모두 도커 이미지로 빌드하고 run하는 것을 jenkins에서 수행하면 자동화가 가능할 것 같다

 

먼저 project url 설정해주고 (물론 선택사항이지만)

 

 

소스코드 관리에 git부분 설정해주고(이건 필수)

 

 

 

다음 빌드 유발에서 webhook을 설정해준다

 

webhook url이랑, 아래 고급 > secret token generate 눌러서 token 생성하고

 

gitlab settings > webhook 들어가서 url, token 입력해서.. add webhook 누르면 생성

 

 

 

도커만 필요하니까 빌드 환경 설정은 필요없을 것 같고

 

빌드 스텝 들어가서 execute shell에서 명령어 작성

 

경로상에 프론트엔드로 들어가서 도커 빌드하고 run

 

다시 백엔드로 들어가서 도커 빌드하고 run

 

cd SubPjt2/frontend
docker build -f Dockerfile -t front .
docker run -d -p 3000:3000 --name frontend -u root front
cd ../
cd backend
docker build -f Dockerfile -t back_server .
docker run -d -p 3001:3001 --name server -u root back_server

 

도커 빌드할때.. 마지막에 .을 자꾸 빼먹더라고.. 

 

docker build -f Dockerfile -t front 이렇게 하면 에러나

 

docker build -f Dockerfile -t front . 이렇게 해야돼

 

-----------------------------------------------------------------------------------------

 

실제로 push해서 빌드 되고 배포 되고 접속까지 잘 되나 테스트해보자..

 

그러면 내 push에 의해 젠킨스가 빌드하고...

 

 

 

빌드가 잘 되긴했고

 

 

docker ps로 띄워진 컨테이너 보면.. 잘 띄워져있고

 

 

대충 실행도 잘 되긴함...

 

 

근데.. 배포 실행환경 맞추는게 장난이 아니겠는데..?

 

9. 기타

 

더욱 자동화하고 싶다면..

 

젠킨스 빌드 과정에서 띄워진 컨테이너를 지우는 명령 docker rm -f (컨테이너 이름)을 넣어줄 필요가 있겠

 

docker rm -f /frontend
docker rm -f /server
cd SubPjt2/frontend
docker build -f Dockerfile -t front .
docker run -d -p 3000:3000 --name frontend -u root front
cd ../
cd backend
docker build -f Dockerfile -t back_server .
docker run -d -p 3001:3001 --name server -u root back_server

 

이를 테스트해보는 김에.. 

 

backend Dockerfile에서 파이썬 COPY . . 지우고 해보자고

 

FROM python:3.8

WORKDIR /SubPjt2/backend/

RUN pip install --upgrade pip
RUN pip install tensorflow
RUN pip install CMake
RUN pip install dlib
RUN pip install torch
RUN pip install torchvision

FROM node:16.18

WORKDIR /SubPjt2/backend/

COPY --from=0 . .

COPY . .

RUN npm install

EXPOSE 3001

CMD ["npm", "start"]

 

빌드 잘 된것 같고

 

 

실제 잘 켜져있고..

 

 

 

컨테이너 문제 없이 떠 있고..

 

 

 

COPY . . 빼도 될듯??

 

이 정도 배포 시스템 완성한거면 초보자 치고는 잘 한것 같은데

 

근데 아무튼 배포환경 맞추면서 에러 고쳐나가가지고 진짜 잘 된건지는 그 때 가서 검증 나겠지만..

TAGS.

Comments