Docker

코끼릭·2022년 8월 20일
0

IT

목록 보기
13/24
post-thumbnail

docker

로컬 환경이 아닌 별도의 가상환경을 구성하는 방법이었던 하이퍼바이저를 사용하여 그 위에 게스트 OS를 올리는 방식의 단점을 개선하면서 등장하게된 프로세스 가상화 방식으로 docker는 별도의 게스트 OS 없이 docker 엔진 위에 가상환경 구동에 필요한 라이브러리와 실행파일만 가지고 있어 기존 방식보다 향상된 성능을 가진 것이 특징이다.

docker Image vs Container

도커 이미지는 가상 환경이 구성되기 위한 실행 파일과 라이브러리를 가진 것으로 docker hub에서 미리 정의되어 있는 이미지를 가져와서 사용하거나 직접 DockerFile을 작성하여 생성한 이미지를 docker hub에 업로드하는 것이 가능하다.

도커 컨테이너는 정의된 도커 이미지를 바탕으로 실제 메모리가 할당되어 가상환경이 실행하고 있는 상태로 이미지와 컨테이너의 관계는 프로그램과 프로세스의 관계와 유사하다.

docker-compose

하나의 프로젝트를 구동하기 위해 여러가지 가상환경(JDK 컨테이너, MySQL 컨테이너, Redis 컨테이너)이 필요할 때 사용하게 되는 명령어로 docker-compose.yaml에 기록한 각 컨테이너의 이미지와 환경설정 정보를 바탕으로 여러 컨테이너를 구동할 수 있게 한다.

version: "3.7"
services:
  web:
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - "6000:5000"
    container_name: flask
    volumes:
      - .:/app
    working_dir: /app
    command: >
      bash -c "pip install pandas numpy flask tensorflow nltk konlpy && python server.py"
    restart: always
    

ports

로컬 환경의 포트와 컨테이너 내부의 포트를 서로 연결시켜주는 포트포워딩 작업으로
"로컬포트":"컨테이너포트"를 작성하게 되면 로컬 포트로 들어오게 되는 작업이 연결된 컨테이너로 전달될 수 있게 된다.

volumes

로컬 환경의 디렉터리와 컨테이너 내부의 디렉터리를 마운트하는 설정으로 로컬 디렉터리:컨테이너 내부 디렉터리로 작성하게 되면 로컬 디렉터리 환경을 컨테이너도 접근할 수 있게 한다.

command

컨테이너가 구동을 실행하게 되면 동작시킬 수 있는 명령어 모음을 설정할 수 있다.

depends_on

컨테이너가 구동을 실행하기 전에 먼저 구동되어야 되는 컨테이너를 설정할 수 있다.

docker & spring project

로컬 환경에서 스프링 프로젝트 구동에 필요한 컨테이너 환경 구성은 다음과 같이 구성할 수 있다. 실제 프로젝트에서 작성한 docker-compose.yml으로 로컬 환경과 다르게 스프링 프로젝트 구동 환경도 별도의 컨테이너로 띄워진 상태라면 application.yaml에 설정한 컨테이너 데이터베이스 연결 주소를 localhost:3306이 아닌 컨테이너이름:컨테이너포트로 해야 된다.

version: "3.7"
services:
  web1:
    image: openjdk:11
    ports:
      - "8080:8080"
    volumes:
      - .:/app
    working_dir: /app
    command: >
      bash -c "./gradlew build && ./gradlew bootRun"
    restart: on-failure
    container_name: web1
    depends_on:
      - db
      - web2

  web2:
    build:
      context: .
      dockerfile: ./flask/Dockerfile
    ports:
      - "6000:5000"
    container_name: web2
    volumes:
      - ./flask:/app
    working_dir: /app
    command: >
      bash -c "pip install pandas numpy flask tensorflow nltk konlpy && python server.py"
    restart: on-failure

  db:
    platform: linux/x86_64
    image: mysql:5.7
    restart: always
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      - MYSQL_DATABASE=project01
      - MYSQL_ROOT_PASSWORD=samho101
      - TZ=Asia/Seoul
    command:
      - --lower_case_table_names=1
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    volumes:
      - /Users/miridih/miridih/project01/mysql:/var/lib/mysql

docker & CI/CD

docker는 배포 환경에서도 동일한 환경을 가져다가 세팅할 수 있는 장점을 가지고 있기 때문에 CI/CD에서도 많이 사용되고 있는데 그 과정은 다음과 같다.

  1. 서버에서 구동되는 container 환경을 docker-compose.yml에 설정한다. Github actions를 사용해서 빌드가 된 jar를 서버의 컨테이너 환경에서 구동만 시키게 하는 것을 목적으로 수정하고 컨테이너와 마운팅한 볼륨도 서버 디렉터리 환경으로 반영한다.

    
    version: "3.7"
    services:
    web1:
      image: openjdk:11
      ports:
        - "8080:8080"
      volumes:
        - .:/app
      working_dir: /app
      command: >
        bash -c "nohup java -jar build/libs/project01-0.0.1-SNAPSHOT.jar"
      restart: always
      container_name: web1
      depends_on:
        - db
        - web2
    
    web2:
      build:
        context: .
        dockerfile: ./flask/Dockerfile
      ports:
        - "6000:5000"
      container_name: web2
      volumes:
        - ./flask:/app
      working_dir: /app
      command: >
        bash -c "pip install pandas numpy flask tensorflow nltk konlpy && python server.py"
      restart: on-failure
    
    db:
      platform: linux/x86_64
      image: mysql:5.7
      restart: always
      container_name: mysql
      ports:
        - "3306:3306"
      environment:
        - MYSQL_DATABASE=project01
        - MYSQL_ROOT_PASSWORD=samho101
        - TZ=Asia/Seoul
      command:
        - --lower_case_table_names=1
        - --character-set-server=utf8mb4
        - --collation-server=utf8mb4_unicode_ci
      volumes:
        - /home/ubuntu/project01/mysql:/var/lib/mysql
  2. Github에 push가 되면 파일을 빌드하고 빌드된 프로젝트를 ssh를 통해 서버에 복사해서 옮긴 후 docker-container를 구동할 수 있도록 Github actions workflows를 작성한다.

    
    name: CI/CD using Docker
    on: [push]
    jobs:
    build:
      name: CI/CD
      runs-on: ubuntu-latest
      steps:
      - name: checkout
        uses: actions/checkout@master
    
      - name: Set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'temurin'
          
      - name: Execution permission for gradlew
        run: chmod +x gradlew
        shell: bash
        
      - name: Build with Gradle
        run: ./gradlew build
        shell: bash
      
      - name: create remote directory
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.KEY }}
          script: mkdir -p /home/ubuntu/project01
    
      - name: copy file via ssh password
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.KEY }}
          port: ${{ secrets.PORT }}
          source: "."
          target: "/home/ubuntu/project01"
        
      - name: executing remote ssh commands using password
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ${{ secrets.USERNAME }}
          key: ${{ secrets.KEY }}
          script: |
            sh chmod +x /home/ubuntu/project01/deploy.sh
            sh /home/ubuntu/project01/deploy.sh

docker-compose
docker를 활용한 CI/CD 1
docker를 활용한 CI/CD 2
도커를 활용한 CI/CD 프로젝트 예시

profile
ㅇㅅㅇ

0개의 댓글