데이터베이스를 운영환경에서는 AWS RDS 를 사용해야하기 때문에 이전에 작성했던 mysql 부분을 수정을 먼저 해보자.
# .travis.yml
# 언어 (플랫폼) 선택
language: generic
# 관리자 권한 갖기
sudo: required
# 도커 환경 구성
services:
- docker
# 스크립트를 실행할 수 있는 환경 구성
before_install:
# Dockerfile.dev 명시 하기 위해 -f 옵션 사용
- docker build -t supportkim/react-test-app -f ./frontend/Dockerfile.dev ./frontend
# 실행할 스크립트 (테스트 실행)
script:
- docker run -e CI=true supportkim/react-test-app npm run test
# 테스트 성공 후 할일 명시
after_success:
# 각각의 이미지 빌드
- docker build -t supportkim/docker-frontend ./frontend
- docker build -t supportkim/docker-backend ./backend
- docker build -t supportkim/docker-nginx ./nginx
# 도커 허브 로그인
- echo "$DOCKER_HUB_PASSWORD" | docker login -u "$DOCKER_HUB_ID" --password-stdin
# 빌드 된 이미지들을 도커 허브에 PUSH
- docker push supportkim/docker-frontend
- docker push supportkim/docker-backend
- docker push supportkim/docker-nginx
EalsticBeanStalk 은 사실 어떻게 컨테이너를 실행해야하는지 모른다.
정리하면 작업 정의를 등록하려면 Container Definitoin 을 명시해줘야 하고 Container Definition 은 dockerrun.aws.json 에 명시해주며 도커 Daemon 으로 전해진다.
// Dockerrun.aws.json
{
// Dockerrun 버전 지정
"AWSEBDockerrunVersion" : 2,
// 이 안에서 컨테이너들을 정의
"containerDefinitions" : [
{
// 컨테이너의 이름
"name" : "frontend",
// Docker 컨테이너를 구축할 Docker 이미지 이름
"image" : "supportkim/docker-frontend",
// 호스트 이름으로, 이 이름을 이용해서 Docker Compose 를 통해 생성된 다른 컨테이너에서 접근이 가능
"hostname" : "frontend",
// 컨테이너가 실패할 경우 작업을 중지해야 하면 true , 그렇지 않으면 false
"essential" : false,
// 컨테이너용으로 예약할 컨테이너 인스턴스에 있는 메모리 양
"memory" : 128
} ,
{
"name" : "backend",
"image" : "supportkim/docker-backend",
"hostname" : "backend",
"essential" : false,
"memory" : 128
} ,
{
"name" : "nginx" ,
"image" : "supportkim/docker-nginx",
"hostname" : "nginx",
"essential" : true,
// 컨테이너에 있는 네트워크 지점을 호스트에 있는 지점에 매핑
"portMappings" : [
{
"hostPort" : 80,
"containerPort" : 80
}
] ,
// 연결할 컨테이너의 목록으로, 연결된 컨테이너는 서로를 검색하고 안전하게 통신할 수 있다.
"links" : ["frontend" , "backend"],
"memory" : 128
}
]
}
그렇다면 왜 VPC 와 Security Group 을 설정해줘야 할까?
즉 Security Group 이 인바운드와 아웃바운드를 통제해서 트래픽을 열어줄 수 있고 닫아 줄 수도 있다.
그렇다면 어떻게 VPC 와 Security Group 을 이용해서 EB 인스턴스와 RDS 가 서로 통할 수 있게 만들 수 있을까?
# .travis.yml 에 추가
deploy:
# 외부 서비스 표시 (s3 , firebase , eb 등)
provider: elasticbeanstalk
# 현재 사용하고 있는 AWS의 서비스가 위치하고 있는 물리적인 위치
region: "ap-northeast-2"
# 생성된 어플리케이션의 이름
app: "docker-fullstack-app"
# env 이름
env: "DockerFullstackApp-env"
# 해당 EB 를 위한 S3 버켓 이름
bucket_name: "버킷 이름"
# 어플리케이션의 이름과 동일
bucket_path: "app 이름과 동일"
on:
# 어떤 브랜치에 Push 를 할 떄 AWS 에 배포를 할 것인지 설정
branch: main
인증을 위해서는 API Key 가 필요하다.
access_key_id: $AWS_ACCESS_KEY
secret_access_key: $AWS_SECRET_ACCESS_KEY
main 에 push 하면 travis CI 에서 테스트를 진행하고 AWS EB 로 전달되서 업데이트를 하고 나면 정상적으로 실행이 된다.
# deploy.yaml
name: Deploy FullStackApp
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# Travis CI 와 같이 도커에 로그인
- run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
# before_install
- run: docker build -t supportkim/react-test-app -f ./frontend/Dockerfile.dev ./frontend
# 테스트 하는 코드 (script)
- run: docker run -e CI=true supportkim/react-test-app npm test
# after_success
- run: docker build -t supportkim/docker-frontend ./frontend
- run: docker build -t supportkim/docker-nginx ./nginx
- run: docker build -t supportkim/docker-backend ./backend
- run: docker push supportkim/docker-frontend
- run: docker push supportkim/docker-nginx
- run: docker push supportkim/docker-backend
# ElasticBeanStalk 에 전달
- name: Generate deployment package
run: zip -r deploy.zip . -x '*.git*'
- name: Deploy to EB
uses: einaregilsson/beanstalk-deploy@v18
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY }}
aws_secret_key: ${{ secrets.AWS_SECRET_KEY }}
# 바꿔줘야 하는 부분 1
application_name: fullstack-docker-app
# 바꿔줘야 하는 부분 2
environment_name: Fullstack-docker-app-env
# 바꿔줘야 하는 부분 3
existing_bucket_name: elasticbeanstalk-ap-northeast-2-637423586273
region: ap-northeast-2
version_label: ${{ github.sha }}
deployment_package: deploy.zip
# docker-compose.yml
version: "3"
services:
frontend:
image: supportkim/docker-frontend
volumes:
- /app/node_modules
- ./frontend:/app
stdin_open: true
mem_limit: 128m
nginx:
restart: always
image: supportkim/docker-nginx
ports:
- "80:80"
backend:
image: supportkim/docker-backend
container_name: app_backend
volumes:
- /app/node_modules
- ./backend:/app
mem_limit: 128m
environment:
MYSQL_HOST: $MYSQL_HOST
MYSQL_USER: $MYSQL_USER
MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
MYSQL_DATABASE: $MYSQL_DATABASE
MYSQL_PORT: $MYSQL_PORT
RDS 생성
보안 그룹 생성
이렇게 GitAcation 으로 CI/CD 파이프라인을 구축할 수 있다.