CICD 환경을 구축하는 방법은 정말 다양하다.
그래서 처음 시도해볼때, 더 어려웠다. 눈물같던 80커밋 절대 잊지 못해!
내가 본 방법은 크게 3가지였다.
먼저 기존 코드를 Github에서 AWS CodeCommit으로 마이그레이션 한다.
AWS CodeCommit은 AWS에서 호스팅하는 버전 제어 서비스로 클라우드에서 자산을 비공개로 저장하고 관리하는 데 사용한다.
애플리케이션 코드를 빌드하기 위해 CodeBuild를 구성한다.
AWS CodeBuild는 소스 코드를 컴파일하고 테스트를 실행하며 배포 준비가 된 소프트웨어 패키지를 생성하는 완전히 관리된다.
코드를 EC2 서버에 배포한다.
AWS CodeDeploy는 Amazon EC2 인스턴스, 온 프레미스 인스턴스 또는 서버리스 Lambda 기능에 대한 애플리케이션 배포를 자동화하는 배포 서비스이다.
코드를 지속적으로 제공하는 파이프 라인을 구축한다.
AWS CodePipeline은 소프트웨어 배포에 필요한 단계를 모델링, 시각화 및 자동화하는 데 사용할 수 있는 지속적인 제공 서비스이다.
코드를 프로덕션에 전달하기 전에 파이프 라인에 승인 프로세스를 통합한다.
version: 0.0
os: linux
files:
- source: /
destination: /home/ec2-user/app
hooks:
AfterInstall:
- location: scripts/pullDocker.sh
timeout: 300
runas: ec2-user
ApplicationStart:
- location: scripts/runDocker.sh
timeout: 300
runas: ec2-user
ApplicationStop:
- location: scripts/stopDocker.sh
timeout: 60
runas: ec2-user
version: 0.1
phases:
pre_build:
commands:
- 'echo Logging in to Docker Hub...'
- 'docker login --username="<DOCKERHUB_USERNAME>" --password="<DOCKERHUB_PASSWORD>"'
build:
commands:
- 'echo Build started on `date`'
- 'echo Building the Docker image...'
- 'docker-compose -f docker-compose.yml build'
post_build:
commands:
- 'echo Build completed on `date`'
- 'echo Pushing the Docker image...'
- 'docker-compose -f docker-compose.yml push'
artifacts:
files:
- 'appspec.yml'
- 'scripts/*'
- 'docker-compose.yml'
- 'Dockerfile'
- 'dist/*'
- 'node_modules/*'
- 'package.json'
- 'package-lock.json'
- 'buildspec.dev.yml'
- 'nest-cli.json'
- 'tsconfig.build.json'
- 'tsconfig.json'
- 'src/*'
FROM node:14.16.0-alpine3.11 as builder
WORKDIR /app
COPY package*.json ./
COPY ./tsconfig.json ./
RUN npm install
COPY . .
## compile typescript
RUN npm run build
## remove packages of devDependencies
# RUN npm prune --production
# ===================================================
FROM node:14.16.0-alpine3.11 as runtime
WORKDIR /app
# ENV NODE_ENV="development"
# ENV DOCKER_ENV="development"
# ENV PORT=5000
## Copy the necessary files form builder
COPY --from=builder "/app/dist/" "/app/dist/"
COPY --from=builder "/app/node_modules/" "/app/node_modules/"
COPY --from=builder "/app/package.json" "/app/package.json"
EXPOSE 3000
CMD ["npm", "run", "start"]
version: '3'
services:
app:
restart: always
image: <DOCKERHUB_IMAGES>
build:
dockerfile: Dockerfile
context: .
container_name: 'app'
volumes:
- .:/app
- /app/node_modules
ports:
- '3000:3000'
volumes:
node_modules:
docker stop $(docker ps -a -q)
if [ "$DEPLOYMENT_GROUP_NAME" == "dev" ]
then
pwd
# Remove any anonymous volumes attached to containers
docker-compose -f /home/ec2-user/app/docker-compose.yml rm -v
# build images and run containers
docker-compose -f /home/ec2-user/app/docker-compose.yml up --detach --renew-anon-volumes
elif [ "$DEPLOYMENT_GROUP_NAME" == "stage" ]
then
# Remove any anonymous volumes attached to containers
docker-compose -f /deploy/docker-compose.stage.yml rm -v
# build images and run containers
docker-compose -f /deploy/docker-compose.stage.yml up --detach --renew-anon-volumes
elif [ "$DEPLOYMENT_GROUP_NAME" == "production" ]
then
# Remove any anonymous volumes attached to containers
docker-compose -f /deploy/docker-compose.yml rm -v
# build images and run containers
docker-compose -f /deploy/docker-compose.yml up --detach --renew-anon-volumes
fi
# docker login
docker login -u <DOCKERHUB_USERNAME> -p <DOCKERHUB_PASSWORD>
# pull docker image
if [ "$DEPLOYMENT_GROUP_NAME" == "dev" ]
then
pwd
docker-compose -f /home/ec2-user/app/docker-compose.yml pull
elif [ "$DEPLOYMENT_GROUP_NAME" == "stage" ]
then
docker-compose -f /deploy/docker-compose.stage.yml pull
elif [ "$DEPLOYMENT_GROUP_NAME" == "production" ]
then
docker-compose -f /deploy/docker-compose.yml pull
fi