Docker 도입 성공

박선우·2022년 7월 11일
0

Docker

목록 보기
2/2
post-thumbnail

느낌점을 토대로 작성하는 나만의 Docker 개념 (점차 공부해 나가겠음!!)

🐾 도커(Docker)를 도입하게된 계기

  • ubuntu(Linux) 와 Mac 개발환경 때문에 서버에서 오류가남..

  • node 최신버전을 사용하니 npm install 후 reify fsevents 프리징이 걸려 먹통이 되었다

  • 구글링을 해서 찾아보니 node 버전이 14 로 다운 그레이드 하니 오류를 해결 할 수 있었다..

  • 서버 베포문제만 2~3시간 날린것 같다 …

  • Mac 환경과 Linux 환경이 달라서 설치 할수 없다고 한다..

  • 노드 버전을 로컬환경과 맞춰주는 방법도 있지만 추가 인스턴스를 생성할 때마다 맞춰줘야하는 번거로움 발생

  • 그래서 생각한게 Docker였다. Linux 와 Mac 개발환경이 달라도 Docker를 이용하면 문제를 해결 할 수 있다.

    • 로컬환경의 도커 이미지를 생성해 인스턴스에서 실행

🚢 DockerFile vs Docker-Compoes 차이점!!

  • DockerFile 이미지를 실행하면서 특정 작업까지 같이 처리하게 해주는 도구고

  • Docker-Compose는 다수의 컨테이너를 쉽게 실행할 수 있게 도와주는 도구이다.

  • Docker-Compose로 컨테이너를 자동 생성한 후, DockerFile로 생성한 컨테이너 안에 자동으로 세팅

  • Docker-Compose를 이용할 경우 nginx,jenkins,redis,등 여러개의 컨테이너를 설정 하고 그것을 통한 무중력 배포를 가능 하게 한다.

  • 아직은 공부가 부족해 어려운 개념까지는 구현 하지 못했지만 Docker를 왜 쓰이고 있고, 어떻게 쓰이는지 이해할 수 있었다.!!

😂 우리는 github Action => Docker hub에 Dockerfile을 빌드해 ubuntu(EC2) => 자동화배포(CD)를 구축하였다.(여러개의 컨테이너를 다룰 능력 부족 ... Docker-compose도 쓰고 싶다..ㅜ)

😎 DockerFile CD => 트러블 슈팅 정리

DockerFile 로직변경 순서

  • DockerFile(1차)

FROM node:16-alpine // 버전정의

WORKDIR /app // 컨테이너안에 경로 app를 찾고, 없으면 만든다

COPY ["package.json", "package-lock.json*","./"] 
// 우리가 쓰고있는 lib들을 복사 한다

RUN npm install
// 복사안 lib파일을 install

RUN npm install -g nodemon
// nodemone을 실행 하기 위해 설치

COPY . . // 우리 전체 소스파일 복제!

CMD ["nodemon","-L","start"] // nodemon으로 서버가 꺼지지 않게 배포 할려고 생각
  • Github Action (1차)
name: ci-cd-pipeline
​
on:
  push:
    branches:
      - dev
​
jobs:
  build-image:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@master
        
      - name: Checkout
        uses: actions/checkout@v2
​
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1
​
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
​
      - name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_NAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
       
      - name: Image digest
        run: echo ${{ steps.docker_build.outputs.digest }}cd-pipeline:
    needs: build-image
    name: continuos deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - name: copy file via ssh password
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.PASSWORD }}
          port: ${{ secrets.PORT }}
          source: 'docker-compose.yaml'
          target: '/home/ubuntu/BE/'
      - name: executing remote ssh commands using password
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.PASSWORD }}
          port: ${{ secrets.PORT }}
          script: |
            cd /home/ubuntu/BE/
            docker-compose pull && docker-compose up -d

😫 1차 Docker CD 문제점 다수 발견!!!

  • github에 .env파일을 올리지 못하니까 Dockerfile을 이미지화 해서 bulid 할때 .env파일이 이미지화 되지 않음

  • docker-compose.yaml 파일을 처음에 써서 CD 했지만 githube에 있는 변경 소스들을 자동화 배포가 되지 않는 문제 ubuntu에서 github에 변경사항을 pull 해야 자동으로 적용되는 문제?( 이건 내가 아직 잘 못쓰는 것 같다 크흠..)

  • ubuntu에 image가 쌓여 디스크 용량이 없어 실패 하는 문제

  • nodemon으로 실행 하면 ubuntu를 항시 켜놓고 있어야 하는 문제!

😅 1차 문제점을 보완!!
1. env 파일을 build 할때 생성해서 같이 이미지화 시키기
2. nodemon => pm2
3. 디스크 용량이 작기때문에 imges , container 삭제후 다시 서버 배포!!
docker rm -f $(docker ps -aq) && docker image rm -f $(docker image ls -q)
4. Docker-compose => Dockerfile 단일 배포!!

  • DockerFile(2차)

FROM node:16-alpine // 버전정의

WORKDIR /app // 컨테이너안에 경로 app를 찾고, 없으면 만든다

COPY ["package.json","package-lock.json*","./"] 
// 우리가 쓰고있는 lib들을 복사 한다

RUN npm install
// 복사안 lib파일을 install

RUN npm install -g pm2
// pm2를 실행 하기 위해 설치

COPY . . // 우리 전체 소스파일 복제!

CMD ["pm2","start","server"] // pm2로 서버가 꺼지지 않게 배포!
  • Github Action (2차)
name: ci-cd-pipeline
​
on:
  push:
    branches:
      - dev
​
jobs:
  build-image:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@master
        
      - name: Checkout
        uses: actions/checkout@v2
​
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1
​
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
​
      - name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_NAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        
        env:
            KAKAO_REST_API: ${{ secrets.KAKAO_REST_API }}
            NAVER_ID: ${{ secrets.NAVER_ID }}
            NAVER_SECRET: ${{ secrets.NAVER_SECRET }}
            GOOGLE_ID: ${{ secrets.GOOGLE_ID }}
            GOOGLE_SECRET: ${{ secrets.GOOGLE_SECRET }}
        with:
          push: true
          tags: ${{ secrets.DOCKER_NAME }}/paper:test
          
      - name: Image digest
        run: echo ${{ steps.docker_build.outputs.digest }}cd-pipeline:
    needs: build-image
    name: continuos deploy
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@master
      - name: copy file via ssh password
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.PASSWORD }}
          port: ${{ secrets.PORT }}
          source: 'docker-compose.yaml'
          target: '/home/ubuntu/BE/'
      - name: executing remote ssh commands using password
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.PASSWORD }}
          port: ${{ secrets.PORT }}
          script: |
            cd /home/ubuntu/BE/
            docker rm -f $(docker ps -aq) && docker image rm -f $(docker image ls -q)
            docker pull ${{ secrets.DOCKER_NAME }}/paper:test && docker run -i -p 8000:8000 ${{ secrets.DOCKER_NAME }}/paper:test

😱 2차 문제점 발견!

  • 아직도 env 파일이 이미지화 되지않음..

  • pm2로 서버를 올리는 순간 바로 kill되는 현상

  • docker-compose.yaml을 읽을 수 없는 문제

  • 해결을 못해서 올려본 슬랙 질문방....

😴 2차 문제점 보안!!

  • env 파일을 ubuntu안에 .env 파일 만들어서 run 할때 --env-file 경로 /.env 커맨드 추가
  • pm2 => Docker로 pm2 쓸려면 => pm2-runtime 써야 한다.
  • docker-compose.yaml 지움..(맴찢..)
// pm2.json 이걸 만들어서 cluster 모드로 서버 실행
{
  "apps": [
    {
      "name": "test",
      "script": "server.js",
      "instances": 0,
      "exec_mode": "cluster"
    }
  ]
}
  • DockerFile(3차)

FROM node:16-alpine // 버전정의

WORKDIR /app // 컨테이너안에 경로 app를 찾고, 없으면 만든다

COPY ["package.json","pm2.json","package-lock.json*","./"] 
// 우리가 쓰고있는 lib들을 복사 한다 (pm2.json도 같이!!)

RUN npm install
// 복사안 lib파일을 install

RUN npm install -g pm2
// pm2를 실행 하기 위해 설치

COPY . . // 우리 전체 소스파일 복제!

CMD ["pm2-runtime","start","pm2.json"] // pm2로 서버가 꺼지지 않게 배포!
  • Github Action (3차)
name: ci-cd-pipeline
on:
  push:
    branches:
      - dev
jobs:
  build-image:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      - name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_NAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Build and push
        id: docker_build
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: ${{ secrets.DOCKER_NAME }}/paper:test
      - name: Image digest
        run: echo ${{ steps.docker_build.outputs.digest }}
  cd-pipeline:
    needs: build-image
    name: continuos deploy
    runs-on: ubuntu-latest
    steps:
      - name: executing remote ssh commands using password
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.PASSWORD }}
          port: ${{ secrets.PORT }}
          script: |
            cd /home/ubuntu/
            docker rm -f $(docker ps -aq) && docker image rm -f $(docker image ls -q)
            docker pull ${{ secrets.DOCKER_NAME }}/paper:test && docker run --env-file /home/ubuntu/.env -i -p 8000:8000 ${{ secrets.DOCKER_NAME }}/paper:test

😵 3차 문제점 발견!!

  • 위에 보이는 사진처럼 Githube Action을 통해 CD를 구현 했으나 Githube Action이 끝나지 않는 문제 ....(어디까지 날 .. 살려줘 ㅜㅜ)

🤣 3차 문제점 보안!!

docker pull ${{ secrets.DOCKER_NAME }}/paper:test && docker run --env-file /home/ubuntu/.env -d -i -p 8000:8000 ${{ secrets.DOCKER_NAME }}/paper:test
  • 마지막 .env 뒤에 -d 옵션을 써주면

  • 드디어 성공!!!!!

😶 아직 해결 하지 못한 문제

  • 디스크 용량 때문에 image와 container를 지우고 다시 배포를 하고 있다

  • image와 container를 지우는(아주 잠깐이지만...) 시간에 서버가 내려간다는 사실...

  • Docker blue green 배포를 구현 하고 싶음!!!

그럴려면 NGINX... (공부하자!!)

🤑 참고한 사이트

Docker 배포
Docker EC2 server 배포
github action CD 구축
Docker 디스크 삭제후 설치!
Docker 권한 설정
Docker pm2 monit 하는 방법
무중단 배포 !

profile
코린이 열심히 배우자!

0개의 댓글