일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- nodejs
- 노드버전
- 호스팅영역
- 클라우드
- GPT3.5
- nvmrc
- 웹소켓연결
- Github
- 웹소켓연결끊김
- 웹소켓재시작
- 클래스
- gitlab
- aws
- ChatGPT
- javascript
- Express
- 패키지설치에러
- git
- 자바
- class
- Database
- gptapi
- aiapi
- java
- db
- gpt3.5turbo
- 버킷생성
- iam사용자
- openaiapi
- chatGPTAPI
Archives
- Today
- Total
IT's Jenna
배포 프로세스 정리 - 실무 본문
내가 일하면서 보려고 만든 배포 프로세스 정리
CI/CD란?
CI (Continuous Integration) : 애플리케이션의 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 repository에 통합되는 것을 의미합니다.
CD (Continuous Delivery OR Continuous Deployment) : 공유 repository에 자동으로 release 하고, production level까지 자동으로 deploy 하는 것을 의미합니다.
즉, CI가 새로운 소스코드의 빌드, 테스트, 병합까지를 의미하고 CD는 개발자 환경을 넘어 고객용 production 환경까지 release되는것 이라고 생각할 수 있습니다.
CI/CD 프로세스
1. pre-setup.sh
#!/usr/bin/env bash
#update instance
# sudo apt-get update && sudo apt-get -y upgrade
sudo apt-get update
# install packages
sudo apt-get install docker.io -y
sudo usermod -a -G docker $USER
sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# sudo chown -R $USER:$(id -gn $USER) /home/ubuntu/.config
sudo usermod -a -G docker $USER
# awscli install
sudo apt install awscli
# bcrypt pre install python
# sudo apt-get install -y build-essential python
- 배포를 위해서 가장 먼저 설정되어야 하는 단계들 입니다.
- 위 내용은 자동으로 실행되는 것이 아닌 개발자가 인스턴스에 접속 후에 직접 한 줄씩 실행해주어야 하는 코드의 모음입니다.
- apt-get (Advanced Packageing Tool, APT) : 우분투를 포함한 리눅스 계열에서 사용하는 패키지 관리 툴입니다. 터미널을 통해서 간편하게 소프트웨어를 설치, 업데이트 및 제거하는 기능을 지원합니다.
- sudo apt-get update : 운영체제에서 사용할 패키지들과 그 버전에 대한 정보를 업데이트하는 명령어입니다. 실제 패키지들을 각각 업데이트하는 것이 아닌 패키지 리스트 정보를 업데이트한다는 점에 유의하시기 바랍니다!
- sudo apt-get install docker.io -y : 도커를 설치합니다. -y를 덧붙이면 설치 시 확인이 필요한 모든 사항에 yes가 자동으로 선택됩니다.
- sudo usermod -a -G docker $USER : 여기서 $USER는 ubuntu입니다. -G로 docker라는 그룹을 생성하고 그 안에 ubuntu라는 계정을 생성합니다. 해당 계정이 sudo 권한을 가지도록 합니다.
- curl (command line tool) : 명령줄에 URL을 이용해서 데이터 전송을 할 수 있도록 합니다.
- sudo curl -L https://github.com/docker/compose/releases/download/1.21.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose : docker다운로드 URL을 전달해서 특정 경로에 docker를 다운로드합니다.
- sudo chmod +x /usr/local/bin/docker-compose : docker가 설치된 경로에 권한을 줍니다.
- 위 세줄은 동시에 실행 가능합니다.
- sudo apt install awscli : awscli를 설치합니다.
- awscli (Amazon Command Line Interface) : awscli는 아마존 명령줄 인터페이스입니다. 명령줄 셀에서 명령을 사용하여 AWS와 상호작용할 수 있는 오픈소스 도구입니다. aws cli를 사용하면 터미널의 명령 프롬프트에서 브라우저 기반 AWS management console에서 제공하는 것과 동일한 기능을 구현 가능합니다. (AWS가 자체적으로 보유하고 있는 모듈입니다)
- 다시 한번 강조하지만, 위 동작들은 모두 인스턴스 내에서 행해져야 합니다. 즉 인스턴스 내부에 도커 및 모듈들을 설치하는 과정입니다.
2. gitlab-ci.yml
variables:
AWS_DEFAULT_REGION: ap-northeast-2
IMAGE_NAME: ******
REGISTRY_URL: ******
DOCKER_HOST: tcp://docker:2375
DOCKER_DRIVER: overlay2
stages:
- push-image
- deploy
# cache:
# paths:
# - node_modules/
push-image:
stage: push-image
image:
name: amazon/aws-cli
entrypoint: ['']
services:
- docker:dind
before_script:
- amazon-linux-extras install docker
- aws --version
- docker --version
- aws configure set region $AWS_DEFAULT_REGION
- aws configure set aws_access_key_id $AWS_ACCESS_KEY
- aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
- aws s3 cp s3://******/.env ./
- aws configure set aws_access_key_id $EC2_AWS_ACCESS_KEY --profile ec2
- aws configure set aws_secret_access_key $EC2_AWS_SECRET_ACCESS_KEY --profile ec2
script:
- docker build -t $IMAGE_NAME .
- aws ecr get-login-password --profile ec2 | docker login --username AWS --password-stdin $REGISTRY_URL
- docker tag $IMAGE_NAME:latest $REGISTRY_URL
- docker push $REGISTRY_URL
only:
- master
deploy:
image: docker:latest
stage: deploy
script:
- fid=$(mktemp)
- echo "$DEPLOY_KEY" > "$fid"
- chmod 400 "$fid"
- scp -v -o StrictHostKeyChecking=no -i "$fid" ./docker-compose.yml "$DEPLOY_USER@$DEPLOY_HOST":/home/ubuntu
- scp -v -o StrictHostKeyChecking=no -i "$fid" ./scripts/deploy-stage.sh "$DEPLOY_USER@$DEPLOY_HOST":/home/ubuntu
- scp -v -o StrictHostKeyChecking=no -i "$fid" ./scripts/custom.conf "$DEPLOY_USER@$DEPLOY_HOST":/home/ubuntu
- ssh -o "StrictHostKeyChecking=no" -i "$fid" "$DEPLOY_USER@$DEPLOY_HOST" aws configure set aws_access_key_id $EC2_AWS_ACCESS_KEY
- ssh -o "StrictHostKeyChecking=no" -i "$fid" "$DEPLOY_USER@$DEPLOY_HOST" aws configure set aws_secret_access_key $EC2_AWS_SECRET_ACCESS_KEY
- ssh -o "StrictHostKeyChecking=no" -i "$fid" "$DEPLOY_USER@$DEPLOY_HOST" aws configure set region $AWS_DEFAULT_REGION
- ssh -o "StrictHostKeyChecking=no" -i "$fid" "$DEPLOY_USER@$DEPLOY_HOST" sh deploy-stage.sh
- rm -rf "$fid"
only:
- master
- gitlab 내에서 자동으로 실행될 명령어 모음 스크립트입니다. 별표 표시는 보안상의 이유로 대체된 부분입니다.
- variables: 배포에 필요한 ecr 관련 정보들을 선언해 둡니다. 아마존에서 생성한 ecr 이미지명 그리고 URL 정보를 입력합니다.
- stages: 배포 실행 단계를 의미합니다. 같은 stage의 동작들은 병렬로 실행되고 각 stage 간에는 직렬로 실행됩니다.
- push-image:
- stage : push-image 단계에서 실행됩니다.
- image : push 할 이미지명을 입력합니다. 위 코드에서는 aws-cli이미지를 push 합니다.
- before_script : script 동작 실행 전에 설정되어야 할 부분을 입력합니다. 해당 정보는 이미지에 등록돼서 push 됩니다.
- 미리 aws에서 생성해둔 s3 access key/secret key 그리고 ec2 access key/secret key를 설정합니다.
- s3에 미리 .env 파일을 업로드해두고 해당 경로를 지정해두면 일일이 변수를 설정할 필요 없이 사용 가능합니다. 해당 파일은 docker가 빌드되는 시점에 불러와집니다. 위 코드에서 .env 파일에는 DB정보를 저장해서 업로드해두었습니다.
- 해당 코드의 위쪽 variables에서 지정되지 않은 변수들은 gitlab의 settings - CI/CD - Variables에 미리 지정해 두었습니다. 아래 그림 참고 가능합니다.
- script : 도커를 빌드합니다. aws에서 생성한 ecr 등록 URL에 빌드한 도커를 push 합니다.
- deploy:
- image : 배포할 이미지를 선택합니다. 위 코드에서 docker의 가장 최신 버전을 배포합니다.
- echo "$DEPLOY_KEY" > "$fid" : pem키를 등록합니다. pem키 전체 내용을 gitlab Variables DEPLOY_KEY에 넣어줍니다.
- chmod 400 "$fid" : 사용자만 키파일을 읽을 수 있도록 키페어에 권한을 설정합니다.
- scp : 특정 파일들을 복사해서 ec2로 업로드 합니다.
- ssh : push-image에서 ecr로 올린 이미지를 연결하기 위해 설정하는 단계입니다.
- sh deploy-stage.sh : gitlab에서 가장 마지막으로 돌아가는 script입니다. 가장 최신 버전의 docker 이미지를 pull해서 사용합니다.
- rm -rf "$fid" : 키파일을 삭제합니다.
3. deploy-stage.sh
#!/bin/bash
BACKEND_URL=******:latest
# ADMIN_FRONTEND_URL=******:latest
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${BACKEND_URL}
docker pull ${BACKEND_URL}
# docker pull ${ADMIN_FRONTEND_URL}
docker-compose -f docker-compose.yml -p server up -d --remove-orphans
docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
- gitlab에서 가장 마지막으로 돌아가는 script라고 언급했던 deploy-stage입니다.
- URL : ecr의 가장 최신버전을 받아옵니다.
- docker pull : 승인된 링크를 통해 docker 이미지를 pull 합니다.
- docker-compose -f docker-compose.yml -p server up -d --remove-orphans : docker-compose를 실행합니다.
- docker rmi $(docker images --filter "dangling=true" -q --no-trunc) : 사용하지 않는 이미지를 삭제합니다. 삭제할 이미지가 없는 경우 배포 과정에서 에러가 발생할 수 있지만 배포 과정에 문제 되지 않습니다.
4. docker-compose.yml
version: '3.6'
services:
test_api:
image: ******:latest
restart: always
environment:
- VIRTUAL_HOST=******
- VIRTUAL_PORT=2000
- LETSENCRYPT_HOST=******
- LETSENCRYPT_EMAIL=******
- TZ=Asia/Seoul
- NODE_ENV=development
networks:
- nginx-proxy
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- 80:80
- 443:443
restart: always
volumes:
- /nginx/certs:/etc/nginx/certs
- /nginx/vhost.d:/etc/nginx/vhost.d
- /nginx/html:/usr/share/nginx/html
- /var/run/docker.sock:/tmp/docker.sock:ro
- /home/ubuntu/custom.conf:/etc/nginx/conf.d/custom.conf
labels:
- com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy
networks:
- nginx-proxy
letsencrypt-nginx-proxy:
image: jrcs/letsencrypt-nginx-proxy-companion
restart: always
volumes:
- /nginx/certs:/etc/nginx/certs
- /nginx/vhost.d:/etc/nginx/vhost.d
- /nginx/html:/usr/share/nginx/html
- /var/run/docker.sock:/var/run/docker.sock:ro
- /nginx/acme:/etc/acme.sh
networks:
- nginx-proxy
# volumes:
# data/redis:
networks:
nginx-proxy:
name: nginx-proxy
# redis-connect:
# driver: bridge
- docker-compose파일은 도커 내에서 다중 컨테이너를 사용할 수 있게끔 설정하는 파일입니다. docker-compose파일을 구성할 때는 공백 간격도 반영되기 때문에 띄어쓰기에 주의를 요합니다.
- services : 하나의 컨테이너를 생성합니다.
- image : ecr의 가장 최신 버전을 가져옵니다.
- environment : 서비스 환경 정보를 입력합니다.
- nginx-proxy : proxy 서버를 생성합니다.
지금까지 배포를 위한 기본적인 script 구조와 절차에 대하여 알아보았습니다. 구조화된 deploy 코드를 바탕으로 ec2, s3, ecr, DB를 새로 구성할 때마다 변경해주면서 사용할 수 있습니다.
'서버배포 > docker' 카테고리의 다른 글
Proxy & NginX (0) | 2021.03.18 |
---|---|
DevOps - Docker & ECR (0) | 2021.03.18 |
Comments