[yebalja.com] 프론트 서버 docker로 이전 (진행중)

이태혁·2021년 1월 22일
0
update기록
2021-01-22 도커 이전 시작
2021-01-24 리눅스 설정 및 예발자 노드 서버 깃 클론
2021-01-26 nginx 설치 및 리버스 프록시 서버 생성

다음 할일: GCP에 도커 빌드 및 배포

👀 docker를 배웠지만 실제 프로젝트에 써먹지는 않았다.
팀원들과 함께 개발한 yebalja.com 서버를 하나둘씩 차차 도커화(dockerize)를 시도해 보기로한다.
지금 yebalja.com은 프론트, 백, 데이터베이스 이렇게 총 3개의 서버가 각각 돌아가고 있다.
먼저 프론트서버부터 적용해볼 예정이다.
이후 모든 서버의 도커화를 마치면 쿠버네티스를 적용해보고 싶다.

도커 기본 명령어

docker ps //실행 중인 컨테이너 목록
docker ps -a  //모든 컨테이너 목록
docker images //생성된 이미지 보기
exit, ctrl+d //실행중인 컨테이너 종료
ctrl+p,q //실행중인 컨테이너를 종료하지 않고 접속 해제, 추후에 attach로 다시 접속 가능

도커 실행 관련 명령어

docker build -t 컨테이너이름 빌드할경로  //도커파일과 경로에 있는 리소스를 바탕으로 이미지 생성
명령어 예시)docker build -t yebalja .

docker run 이미지이름 // 이미지를 통해서 새로운 컨테이너 생성(여러 옵션필요, 아래에서 자세히 설명)

docker start 컨테이너 이름  //위에서 생성한 컨테이너 시작
docker attach 컨테이너 이름 //실행중인 컨테이너에 접속

docker exec -it // 현재 실행중인 컨테이너에 명령어 전달
//보통 attach하면 sheel창이 나오는데 attach없이 명령어를 쓸때 사용하는 듯 하다.

도커 파일 이동 관련 명령어

//컨테이너 -> 로컬
docker cp 컨테이너이름:컨테이너속파일경로 복사될호스트경로
docker cp yebaljaFront:/etc/nginx/nginx.conf ~/docker
//로컬 -> 컨테이너
docker cp 복사할호스트파일경로 컨테이너이름:컨테이너속복사될파일경로
docker cp ~/docker yebaljaFront:/etc/nginx/nginx.conf 

1. ubuntu docker 다운받기

1) 도커 우분투 이미지 받기

현재 GCP에서 yebalja.com이 돌아가고 있는 우분투 버전을 확인하고 같은 이미지 파일을 받기로 한다.


(gcp에 VM 인스턴스 세부정보탭에서 확인한 리눅스 버전정보, 보통 18.04 LTS나 16.04 LTS를 많이 쓰는 것 같다.)

docker search ubuntu // 이미지 검색해보기
docker pull ubuntu:16.04 // 뒤에 버전을 명시하지 않으면 최신버전을 다운받는다.✅


새로운 이미지를 다운받은것을 확인할 수 있다. (16.04버전이라 수정이 안일어날것 같은데 9시간전에 수정이 일어났다 보다)

2 도커파일 만들기

도커를 처음배울때는 일단 도커로 만든 컨테이너안에서 이것저것 명령어를 다 실행해보고 되는지 확인한 다음에 마지막에 도커파일을 만들었는데 이번에는 도커 컨테이너안에서 명령어가 되는지 확인하고 바로바로 Dockerfile에 넣을 예정이다.

1) 다운받은 이미지를 바탕으로 첫 도커 파일 만들기

#Dockerfile
FROM ubuntu:16.04

위 Dockerfile이 있는 폴더에서 docker build -t 태그이름 .하면 도커파일에 담겨진 명령어들을 바탕으로 도커 이미지가 빌드된다.

위에서 만든 도커 이미지에 접속하기

docker run -it -p 80:80 -p 443:443 -p 3000:3000 --name yebaljaFromImage yebalja

-it 옵션: 도커안에 만들어진 가상환경을 터미널로 접속, 제어하게 해주는 명령어
이 옵션을 쳐야 컨테이너에 자동으로 접속한다. 이 옵션을 안치면 추후에 attach로 접속해야 하는 것 같다.
-p 옵션: 도커와 도커가 실행중인 실제 컴퓨터(서버)와의 포트를 연결해주는 부분

  • "호스트 포트: 컨테이너 포트" 형식
  • 호스트: 도커가 실행되는 컴퓨터
  • 컨테이너: 도커가 만든 가상의 컴퓨터
  • 80: http포트
  • 443: https포트
  • 3000: 실제 프론트 서버는 3000포트에서 작동돼서 추가했다.
  • yebaljaFromImage-> 만들어질 컨테이너 이름, 원하는 이름으로 정하면 된다.
  • yebalja-> 위에서 build할때 정한 태그이름과 일치해야한다. 해당 이미지를 바탕으로 실행(run)하라는 명령어이다.

💡 도커파일에 명령어를 추가해서 이미지를 빌드한다고 컨테이너가 갱신되지 않는다. 컨테이너를 갱신하려면 위에 docker run 명령어를 통한 다시 컨테이너를 생성해야 한다. 이렇게 작업하면 번거롭다는 단점이 있다.
따라서 컨테이너에 1)명령어를 하나씩 입력해보고 잘 실행되면 2)Dockerfile에 해당 명령어를 추가하고 3)docker build하는식으로 도커파일을 작성해 나갈 것이다.

2) 리눅스 첫 설정해주기

apt-get update, 노드 설치 등등

처음에는 예전에 작성해 놓은 ubuntu에 node 실행환경 만들기 글을 참조하면서 그대로 Dockerfile에 옮겼다.

그랬더니 몇가지 에러가 생겼는데

  • 이상하게 gcp에서는 vim, curl이 기본 패키지에 있었는데 도커에서 받은 우분투에는 없다.
  • sudo명령어를 치니깐 sudo commands not found라고 해서 이상했는데 알고보니 sudo도 패키지로 다운받아서 설치할 수 있었다.

sudo 설치하는법 Stack Overflow참고글

다시 작성한 Dockerfile은 다음과 같다.

FROM ubuntu:16.04

MAINTAINER taelee "taelee@student.42seoul.kr"

#패키지 목록 업데이트, sudo 설치
RUN apt-get update
RUN apt-get -y install sudo
#파일 편집을 위한 vim 에디터 설치
RUN apt-get -y install vim

#필수 패키지 설치
RUN apt-get install -y build-essential

#curl 설치
RUN apt-get install -y curl

#노드 파일 다운 및 설치
RUN curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
RUN apt-get install -y nodejs

3) 깃헙에서 프론트서버 다운받아서 실행하기

...
#npm 최신버전으로 업데이트 및 서버 유지를 위한 pm2설치
RUN npm i -g npm
RUN npm i -g pm2

RUN apt-get install -y git

RUN git clone https://github.com/FiveEat42/yebalja.com.git yebalja.com && cd yebalja.com && git checkout ab65974

RUN cd /yebalja.com/front && npm i && npm run build && npm run deploy

깃헙에서 서버관련 파일을 다운받았다.
최신 커밋은 아직 개발중인 사항이라 지난 배포 커밋으로 checkout하였다.
프론트는 react와 next를 사용하는데 build와 배포 명령어를 미리 package.json파일에 정리해두어서 npm run build와 npm run deploy명령어를 사용하면 프론트 서버 빌드 및 배포가 이루어진다.
package.json파일 script 파트

...
  "scripts": {
    "start": "NODE_ENV=production next start",
    "build": "next build",
    "deploy": "NODE_ENV=production pm2 start npx --name 'front-server' -- next start",
    "stop": "pm2 kill"
  },
...

사실 이렇게 되면 서버가 실행되어야 하는데 컨테이너에 접속해도 호스트의 인터넷 브라우저에서 localhost:3000으로 접속해도 아무것도 뜨지 않는다.
이미지를 빌드후 컨테이가 종료되어 내부에 있는 서버또한 죽기 때문이다. 이 현상을 방지하기 위해 빌드 후 컨테이너가 살아있도록 블록킹이 필요하다.
또한 예발자는 프론트 서버가 열려있는 3000포트말고도 80포트와 443포트를 통해 nginx가 리버스 프록시 서버가 존재한다. (http나 https의 접속을 3000포트로 연결해주는 기능을 한다.)
이제 컨테이너가 죽지 않도록 하는 블록킹과 nginx설치를 추가할 예정이다.

주의) 컨테이너를 멈췄다가 다시 실행할때(start, attach)

  • 전날 중지해놓은 컨테이너를 다시 실행하려고 docker start 컨테이너 docker attach 컨테이너명령어로 접속하는데 너무 오래걸렸다.
  • 👆👆👆 위 화면에서 30분 기다렸다.
  • 👇👇👇원래는 아래 화면이 나와야 한다.

이상하다 싶어 글자를 쳐보니깐 바로 아래화면으로 바뀌었다. 접속이 되었는데 프롬프트창만 안뜨는것 같다.
혹시 attach후에 저런 상황일때 기다리지 마시고 글자를 치기 바랍니다!!

4) nginx 적용하기

💡 위의 설정으로 node서버는 3000포트에서 돌아간다.
이후에 적용할 SSL(HTTPS=보안 HTTP)을 위해 3000포트의 앞에 nginx로 만든 리버스 프록시 서버를 둔다.
이 nginx의 역할은 80포트(포트없이 URL을 기입했을 때 들어오는 주소)와 443포트(HTTPS로의 접속)을 전부 3000포트로 돌려주는 역할을 한다.
이때 이 리버스 프록시 서버를 node로도 만들 수 있다고 하는데 nginx가 더 간단하게 적용할 수 있고 빠르다고 알고 있다.
그래서 리버스 프록시 서버로 nginx를 적용한다.

먼저 dockerfile에 nginx설치 명령어를 추가한다.

dockerfile
...

RUN apt-get install -y nginx

설치를 하면 컨테이너속 /etc/nginx/nginx.conf에 nginx관련 설정 파일이 생긴다. 그곳에 있는 파일을 호스트로 복사하자

docker cp yebaljaFront:/etc/nginx/nginx.conf 도커파일이있는호스트경로

위 명령어로 호스트 파일로 가져왔다.

열어서 중간에

	include /etc/nginx/conf.d/*.conf;
	include /etc/nginx/sites-enabled/*

요 문구 바로 밑에 아래 리다이렉션 코드를 입력해준다.

server {
	server_name test.yebalja.com;
	location / {
		proxy_set_header HOST $host;
		proxy_pass http://127.0.0.1:3000;
		proxy_redirect off;
	}
}

nginx로 test.yebalja.com의 url로 접속시 같은 서버의 3000포트로 연결해주는 프록시 코드이다.

위 내용을 적용한 파일을 다시 컨테이너에 적용시켜 줘야한다.
이때 docker cp 명령어로 다시 전달해주면된다.

docker cp 호스트의nginx.conf의위치 yebaljaFront:/etc/nginx/

도커파일을 업데이트 하기전에 실행중인 컨테이너에서 파일이 잘바뀌었는지 확인해보자

service nginx start 명령어로 nginx를 실행시키고
yebalja.com/front 폴더에 들어가서
npm run deploy로 프론트 서버를 실행시키자

크롬에 들어가서 localhost로 들어갔을 때 Welcome to nginx가 나오고
localhost:3000으로 들어갔을 때 예발자닷컴이 나오면 성공이다.

사실 프록시 서버가 성공한지는 알 수 없다.
test.yebalja.com으로 들어왔을때만 nginx가 3000포트로 연결을 해주기 때문이다.
이제 도커파일을 GCP에 올려서 도커를 빌드하고 컨테이너를 만들어서 배포까지 해볼예정이다.
이부분은 한번도 해본적이 없어서 많이 떨리지만 구글링을 통해 한번 도전해보자

오늘 추가된 도커파일 코드는 다음과 같다.

RUN apt-get install -y nginx

COPY ./nginx.conf /etc/nginx/nginx.conf
RUN cd /yebalja.com/front && npm run deploy
RUN service nginx start

현재까지의 만든 도커파일 전체 내용

FROM ubuntu:16.04

MAINTAINER taelee "taelee@student.42seoul.kr"

#패키지 목록 업데이트, sudo 설치
RUN apt-get update
RUN apt-get -y install sudo
#파일 편집을 위한 vim 에디터 설치
RUN apt-get -y install vim

#필수 패키지 설치
RUN apt-get install -y build-essential

#curl 설치
RUN apt-get install -y curl

#노드 파일 다운 및 설치
RUN curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
RUN apt-get install -y nodejs

#npm 최신버전으로 업데이트 및 서버 유지를 위한 pm2설치
RUN npm i -g npm
RUN npm i -g pm2

#git 설치
RUN apt-get install -y git

#yebalja.com 프론트 코드 깃 클론
RUN git clone https://github.com/FiveEat42/yebalja.com.git yebalja.com && cd yebalja.com && git checkout ab65974

#yebalja관련 node 패키지 설치, 서버 빌드(next사용)
#배포, 하지만 컨테이너가 종료되면서 서버도 죽음
RUN cd /yebalja.com/front && npm i && npm run build && npm run deploy


#nginx설치
RUN apt-get install -y nginx

#nginx설정파일에 리버스 프록시 내용추가
COPY ./nginx.conf /etc/nginx/nginx.conf
#nginx 시작
RUN service nginx start

5) GCP에 배포하기

이 부분은 GCR(google container repository)에 이미지를 올리고 cloud shell을 이용해서 제어하는 것 같다.

profile
back-end, cloud, docker, web의 관심이 있는 예비개발자입니다.

0개의 댓글