Skip to content

Commit

Permalink
feat(cd): lock master branch & renew cd to staging
Browse files Browse the repository at this point in the history
  • Loading branch information
astorverse committed Jul 23, 2024
1 parent 053d739 commit 47aa805
Showing 1 changed file with 116 additions and 42 deletions.
158 changes: 116 additions & 42 deletions .github/workflows/deploy-to-staging.yml
Original file line number Diff line number Diff line change
@@ -1,80 +1,154 @@
name: Deploy to Staging
name: Deploy to Production

on:
push:
branches:
- staging
- master

jobs:
deploy:
build_and_push:
runs-on: ubuntu-latest

env:
ECR_URL: ${{ secrets.AWS_STAGING_ECR_URL }}
HOSTS: ${{ secrets.AWS_STAGING_HOSTS }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_STAGING_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_STAGING_SECRET_ACCESS_KEY }}
AWS_PROFILE: production
ACCOUNT: 'ubuntu'
DOCKER_TAG: 'latest'
SERVICE_NAME: 'blccu'

steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v2
uses: actions/setup-node@v4
with:
node-version: '21' # 필요한 Node.js 버전으로 설정
node-version: '21.7.2'

- name: Install dependencies
run: npm install

- name: Build project
run: npm run build

- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
- name: Create PEM file
run: echo "${{ secrets.BLCCU_STAGING_RSA_PEM }}" > deploy_key.pem

- name: Set PEM file permissions
run: chmod 400 deploy_key.pem

- name: Install AWS CLI
uses: unfor19/install-aws-cli-action@v1
with:
aws-access-key-id: ${{ secrets.AWS_STAGING_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_STAGING_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
version: 2

- name: Configure AWS CLI
run: |
aws configure set aws_access_key_id ${{ env.AWS_ACCESS_KEY_ID }}
aws configure set aws_secret_access_key ${{ env.AWS_SECRET_ACCESS_KEY }}
aws configure set region ${{ env.AWS_DEFAULT_REGION }}
- name: Test AWS Credentials
run: aws sts get-caller-identity

- name: Login to ECR
run: aws ecr get-login-password --region ${{ secrets.AWS_REGION }} | docker login --username AWS --password-stdin ${{ secrets.AWS_STAGING_ECR_URL }}
- name: Log in to ECR
run: |
aws ecr get-login-password --region ${{ env.AWS_DEFAULT_REGION }} | docker login --username AWS --password-stdin ${{ env.ECR_URL }}
- name: Build and push Docker image
run: |
echo "Service Name: ${{ env.SERVICE_NAME }}"
echo "Docker Tag: ${{ env.DOCKER_TAG }}"
echo "ECR URL: ${{ env.ECR_URL }}"
docker buildx build --platform linux/amd64 -t ${{ env.SERVICE_NAME }} . --load
docker tag ${{ env.SERVICE_NAME }}:${{ env.DOCKER_TAG }} ${{ env.ECR_URL }}/${{ env.SERVICE_NAME }}:${{ env.DOCKER_TAG }}
docker push ${{ env.ECR_URL }}/${{ env.SERVICE_NAME }}:${{ env.DOCKER_TAG }}
- name: Build Docker image
run: docker buildx build --platform linux/amd64 -t blccu-ecr . --load
deploy_to_servers:
runs-on: ubuntu-latest

needs: build_and_push

- name: Tag Docker image
run: docker tag blccu-ecr:latest ${{ secrets.AWS_STAGING_ECR_URL }}:staging-latest
env:
ECR_URL: ${{ secrets.AWS_STAGING_ECR_URL }}
HOSTS: ${{ secrets.AWS_STAGING_HOSTS }}
AWS_DEFAULT_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_STAGING_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_STAGING_SECRET_ACCESS_KEY }}
AWS_PROFILE: production
ACCOUNT: 'ubuntu'
DOCKER_TAG: 'latest'
SERVICE_NAME: 'blccu'
BLUE_PORT: '3000'
GREEN_PORT: '3001'
NGINX_CONFIG: '/etc/nginx/nginx.conf'

- name: Push Docker image to ECR
run: docker push ${{ secrets.AWS_STAGING_ECR_URL }}:staging-latest
steps:
- name: Create PEM file
run: echo "${{ secrets.BLCCU_STAGING_RSA_PEM }}" > deploy_key.pem

- name: Create PEM file from secret
run: echo "${{ secrets.BLCCU_STAGING_RSA_PEM }}" > blccu-staging-rsa.pem
- name: Set PEM file permissions
run: chmod 400 deploy_key.pem

- name: Deploy to server
- name: Deploy to servers
run: |
chmod 400 blccu-staging-rsa.pem
ssh -o StrictHostKeyChecking=no -i blccu-staging-rsa.pem ubuntu@${{ secrets.BLCCU_STAGING_HOST }} << 'EOF'
set -e
NEW_PORT=3001
CURRENT_PORT=$(grep 'server localhost:' /etc/nginx/nginx.conf | awk '{print $2}' | cut -d ':' -f 2 | sed 's/;//')
if [ "$CURRENT_PORT" = "3001" ]; then
NEW_PORT=3000
IFS=',' read -r -a HOST_ARRAY <<< "$HOSTS"
if [ ${#HOST_ARRAY[@]} -eq 0 ]; then
HOST_ARRAY=("$HOSTS")
fi
for HOST in "${HOST_ARRAY[@]}"; do
SERVER=$ACCOUNT@$HOST
CURRENT_PORT=$(ssh -i deploy_key.pem -o StrictHostKeyChecking=no $SERVER "grep 'server localhost:' ${{ env.NGINX_CONFIG }} | awk '{print \$2}' | cut -d ':' -f 2 | sed 's/;//'")
if [ "$CURRENT_PORT" = "${{ env.BLUE_PORT }}" ]; then
NEW_PORT=${{ env.GREEN_PORT }}
elif [ "$CURRENT_PORT" = "${{ env.GREEN_PORT }}" ]; then
NEW_PORT=${{ env.BLUE_PORT }}
else
echo "서버의 blue green 포트 확인 실패 on $HOST"
exit 1
fi
docker pull ${{ secrets.AWS_STAGING_ECR_URL }}:staging-latest
docker run --env-file .env.staging -d --memory="512m" --cpus="0.5" -p $NEW_PORT:3000 --name blccu-ecr-$NEW_PORT -e TZ=Asia/Seoul ${{ secrets.AWS_STAGING_ECR_URL }}:staging-latest
NEW_SERVICE_NAME=${{ env.SERVICE_NAME }}-$NEW_PORT
OLD_SERVICE_NAME=${{ env.SERVICE_NAME }}-$CURRENT_PORT
ssh -i deploy_key.pem $SERVER "aws ecr get-login-password --region ${{ env.AWS_DEFAULT_REGION }} | docker login --username AWS --password-stdin ${{ env.ECR_URL }}"
ssh -i deploy_key.pem $SERVER "docker pull ${{ env.ECR_URL }}/${{ env.SERVICE_NAME }}:${{ env.DOCKER_TAG }}"
ssh -i deploy_key.pem $SERVER "docker run --env-file /home/${{ env.ACCOUNT }}/upload/.env.prod -d -p $NEW_PORT:3000 --name $NEW_SERVICE_NAME -e TZ=Asia/Seoul ${{ env.ECR_URL }}/${{ env.SERVICE_NAME }}:${{ env.DOCKER_TAG }}"
for i in {1..20}; do
HEALTH_CHECK=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:$NEW_PORT/health)
HEALTH_CHECK=$(ssh -i deploy_key.pem $SERVER "curl -v -s -o /dev/null -w '%{http_code}' http://localhost:$NEW_PORT/health || true")
echo "http://localhost:$NEW_PORT/health"
echo "HTTP Status Code: $HEALTH_CHECK"
if [ "$HEALTH_CHECK" -eq 200 ]; then
echo -e "\n 헬스체크 성공 on $HOST \n"
break
fi
echo -e "\n 헬스체크 시도 $i/20 실패. 5초 후 재시도 on $HOST... \n"
sleep 5
done
if [ "$HEALTH_CHECK" -ne 200 ]; then
docker stop blccu-ecr-$NEW_PORT && docker rm blccu-ecr-$NEW_PORT
ssh -i deploy_key.pem $SERVER "docker stop $NEW_SERVICE_NAME && docker rm $NEW_SERVICE_NAME"
exit 1
fi
sudo sed -i "s/server localhost:$CURRENT_PORT;/server localhost:$NEW_PORT;/g" /etc/nginx/nginx.conf
sudo systemctl restart nginx
docker stop blccu-ecr-$CURRENT_PORT && docker rm blccu-ecr-$CURRENT_PORT
docker images --format "{{.ID}} {{.Repository}}:{{.Tag}}" | grep -v ':staging-latest' | awk '{print $1}' | xargs -r docker rmi
yes | sudo docker system prune -a
EOF
- name: Remove PEM file
run: rm blccu-staging-rsa.pem
ssh -i deploy_key.pem $SERVER "sudo sed -i 's/server localhost:$CURRENT_PORT;/server localhost:$NEW_PORT;/g' ${{ env.NGINX_CONFIG }}"
ssh -i deploy_key.pem $SERVER "sudo systemctl restart nginx"
ssh -i deploy_key.pem $SERVER "sudo docker stop $OLD_SERVICE_NAME"
ssh -i deploy_key.pem $SERVER "sudo docker rm $OLD_SERVICE_NAME"
ssh -i deploy_key.pem $SERVER "docker images --format \"{{.ID}} {{.Repository}}:{{.Tag}}\" | grep -v ':latest' | awk '{print \$1}' | xargs -r docker rmi"
ssh -i deploy_key.pem $SERVER "sudo docker system prune -a -f"
echo "배포 완료 on $HOST. $NEW_SERVICE_NAME"
done
- name: Cleanup PEM file
run: rm deploy_key.pem
if: always()

0 comments on commit 47aa805

Please sign in to comment.