[따라하며 배우는 도커와 CI 환경] 복잡한 어플 실제로 배포해보기 (테스트 & 배포 부분)

Jimin Lim·2022년 7월 5일
0

Docker

목록 보기
9/9
post-thumbnail

✅ 전체적인 과정

이전과 다르게, Travis CI에서 이미지 생성 후 Docker Hub로 전달하도록 하여 이미지를 한 번만 빌드하도록 한다.

🔗 DB 정리

로컬 환경과 다르게 운영 환경은 RDS를 사용하기에 Docker-compose.yml의 MySQL 부분을 삭제해준다. 이후, backend의 db.js에서 DB연결 부분은 RDS에 맞게 수정해주도록 한다.

🔗 Github 업로드

Github repository를 판 후, 아래 명령을 실행해준다.

git init - git add - git commit -m "커밋할 메시지" - git remote add origin <원격 저장소명> - git push origin <브랜치명>

이대로 올리면 front-end 폴더에 .git 파일이 포함되어있어 같이 안올라간다. 따라서 .git 파일을 삭제하고 git rm -r --cached . 명령을 통해 캐시 삭제 후 다시 add, commit, push 를 해준다.

✅ Travis CI

🔗 .travis.yml 파일 작성

#언어 플랫폼 설정
language: generic

#sudo 권한 부여
sudo: required 

#도커 환경
services: 
  - docker

#구성된 도커환경에서 Dockerfile.dev를 이용해 도커 이미지 생성, -f 명령 통해 dockerfile 명시 
before_install:
  - docker build -t jym3263/react-test-app -f ./frontend/Dockerfile.dev ./frontend

#build된 이미지 명을 이용해 docker run
script:
  - docker run -e CI=true jym3263/react-test-app npm run test

#테스트 성공 후 이미지 빌드 후 도커 허브에 push
after_success:
  - docker build -t jym3263/docker-frontend ./frontend
  - docker build -t jym3263/docker-backend ./backend
  - docker build -t jym3263/docker-nginx ./nginx

  - echo "$DOCKER_HUB_PASSWORD" | docker login -u "$DOCKER_HUB_ID" --password-stdin

  - docker push jym3263/docker-frontend
  - docker push jym3263/docker-backend
  - docker push jym3263/docker-nginx

이 과정까지 완료한 후, 깃허브에 push하면 도커허브까지 push 되어있는 것을 확인할 수 있다.

✅ EB 배포

Dockerfile이 여러 개인 경우, EB이 어떤 파일을 먼저 실행하고 어떤 행동을 해야하는지 프로세스를 취하기 어려워 Dockerrun.aws.json 파일을 작성해준다. 즉, 어떻게 다중 컨테이너를 작동시킬지 알려준다.

🔗 Dockerrun.aws.json 파일 작성

여러 개의 객체로 구성되어 있는데, 각 객체에 하나의 컨테이너를 정의할 수 있다.

{
    "AWSEBDockerrunVersion": 2,
    "containerDefinitions": [
        {
            "name": "frontend",
            "image": "jym3263/docker-frontend",
            "hostname": "frontend",
            "essential": false,
            "memory": 128
        },
        {
            "name": "backend",
            "image": "jym3263/docker-backend",
            "hostname": "backend",
            "essential": false,
            "memory": 128
        },
        {
            "name": "nginx",
            "image": "jym3263/docker-nginx",
            "hostname": "nginx",
            "essential": true,
            "portMappings": [
                {
                    "hostPort": 80,
                    "containerPort": 80
                }
            ],
            "links": ["frontend", "backend"],
            "memory": 128
        }
    ]
}
  • Container Definition: 작업 정의
  • name: 컨테이너 이름
  • hostname: 도커 컴포즈를 이용해 생성된 다른 컨테이너에서 접근 가능
  • essential: 컨테이너가 실패할 경우 작업을 중지해야 하면 true, 여기서 nginx는 웹 서버로, 죽으면 다른 작업도 할 수 없기에 true로 둔다.
  • memory: 인스턴스에 있는 메모리 양
  • portMappings: 컨테이너에 있는 네트워크 지점을 호스트와 매핑
  • links: 연결할 컨테이너의 목록, 연결된 컨테이너는 안전하게 통신이 가능

🔗 EB 생성

  • 🤔 Elastic Beanstalk: EC2, Security 등 다양한 환경을 컨트롤해주며 또한 트래픽이 많아진다면 로드 밸런서를 통해서 분산시켜준다.

Docker 선택 후, multi-container를 선택해준다.

🔗 VPC, Security Group

🤔 VPC (Amazon Virtual Private Cloud)

AWS에 만든 서비스들을 나의 아이디에서만 접근 가능하도록 논리적으로 격리된 네트워크에서 생성이 되게 해준다. 만약 인스턴스, RDS를 생성하면 같은 지역 내에서 VPC가 생성되도록 한다.

🤔 Security Group

  • inbound: 외부에서 EC2인스턴스로 요청을 보내는 트래픽, (HTTP, HTTPS, SSH 등)
  • outbound: EC2에서 나가는 트래픽

Security Group이 inbound와 Outbound를 통제해 트래픽을 열고, 닫아줄 수 있다.

🤔 EB 인스턴스와 RDS가 서로 통할수 있게 하기 위해서는?

같은 VPC안에 있는 AWS 서비스 간에는 트래픽을 모두 허용할 수 있게 Security Group을 허용해준다.

🔗 Security Group 생성 및 적용

보안 그룹 생성 후, inbound 규칙을 편집해 3306(MySQL 포트)과 생성한 보안 그룹을 선택해준다. 또한 RDS, EB 각각 생성한 보안 그룹을 적용해 준다.

  • RDS
    DB 인스턴스 수정 이동 후, 아래와 같이 수정해준다.

  • EB
    인스턴스 편집으로 이동 후, 인스턴스 보안 그룹을 수정해준다.

🔗 EB, RDS 소통을 위한 환경 변수 설정

EB의 구성 - 소프트웨어 편집으로 이동해, 환경 속성을 지정해준다.

  backend:
    build: 
      dockerfile: Dockerfile.dev
      context: ./backend
    container_name: app_backend
    volumes:
      - /app/node_modules
      - ./backend:/app 
    environment: 
      MYSQL_HOST: mysql
      MYSQL_USER: root 
      MYSQL_ROOT_PASSWORD: <password>
      MYSQL_DATABASE: <db 이름>
      MYSQL_PORT: 3306   
const mysql = require("mysql");
const pool = mysql.createPool({
    connectionLimit: 10,
    host: process.env.MYSQL_HOST,
    user: process.env.MYSQL_USER,
    password: process.env.MYSQL_ROOT_PASSWORD,
    database: process.env.MYSQL_DATABASE,
    port: process.env.MYSQL_PORT
});
exports.pool = pool;

✅ Travis CI를 이용한 Deploy

🔗 AWS 접근을 위한 API KEY 생성

Travis CI에서 AWS에서 전달은 AWS에서 제공하는 엑세스 키, 시크릿 키를 이용해 인증한다. IAM 유저를 생성한 후, 특정 권한만 부여한 후 사용하도록 한다.

IAM - 사용자 - 사용자 추가 클릭 후, 기존 정책 직접 연결을 통해 IAM 유저를 생성해준다.

생성 후 travis CI로 이동해 받은 엑세스 키, 시크릿 키를 환경 변수에 추가해준다.
(More Options -> Settings)

🔗 Deploy 과정 작성

.travis.yml 파일에서 deploy 부분을 추가해주도록 한다.

deploy:
  provider: elasticbeanstalk #외부 서비스
  region: "ap-northeast-2" #region 설정
  app: "docker-fullstack-app" #생성된 app 이름
  env: "Dockerfullstackapp-env" 
  bucket_name: elasticbeanstalk-ap-northeast-2-174472627916 #s3 버킷 이름
  bucket_path: "docker-fullstack-app" #app이름과 동일 
  on:
    branch: master #master에 push될 때 배포
  
  access_key_id: $AWS_ACCESS_KEY
  secret_access_key: $AWS_SECRET_ACCESS_KEY

profile
💻 ☕️ 🏝 🍑 🍹 🏊‍♀️

0개의 댓글