레포에 앞단 뒷단 레포가 다 있었음.
이거 가지고 깃헙 액션을 사용하여 브랜치별로 앞단은 s3로 보내서 정적 웹사이트로 쓰고,
뒷단은 ec2로 보내서 java를 구동해도 됨.
난 좀 다르게 생각 했음
상기 상황에서 나는 아에 ec2에 앞단 뒷단 다 올리고 2개 서버를 구동한 뒤에
3000번 포트만 보안그룹에서 오픈 해주면 되지 않을까 생각했다.
즉
이용자 -> 앞단(3000) -> 뒷단 (localhost:8080) -> db (aws rds)
이 경우 ec2만 https로 감싸주면 나쁘지 않은 배포가 될 것 같았다.
어차피 큰 규모의 프로젝트도 아니고 용량도 얼마 안하는데 이정도야 뭐...
이미지 파일도 s3 버킷을 써 먹을거니까 괜찮은 생각 같았음.
뭐 엄밀히 보자면 앞단 뒷단이 강하게 붙으니까 개발 할 때 문제가 생길 수 있는데, 어차피 앞단 분들 테스트는 내 컴퓨터에 직접 들어와서 하고, 뒷단 api가 어느정도 개발이 된 상태여서 커밋 푸시가 활발하지 않으므로 괜찮아 보였다.
워낙 많은 자료가 있으니까 굳이 스샷을 붙이진 않겠음.
나는 중간에 IAM 프로파일이 꼬여서 2번을 만들었다. 왜 IAM 프로파일이 2개 붙어있다는 에러를 뱉었는지 ㅡㅡ
정책 권한은 다음과 같음.
내가 aws에 익숙치 않아서 이것 저것 다 박은 느낌
codeDeployRole이 2개나 있는데 하난 없애도 되지 않을까? ㅋㅋㅋㅋ
아직 테스트 중이기 때문에 포트는 3000, 8080을 다 열어놨다. 보안에 취약한 상태
s3 버킷을 만들어 준다.
얘는 그냥 만들면 되니까 스킵. 그래도 주소는 잘 봐두자
github action에서 workflow yml파일을 작성한다.
앞단, 뒷단 모두 들어가야 하기 때문에 꽤 길다.
name: Java CI with Gradle
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
permissions:
contents: read
env:
S3_BUCKET_NAME: ${{ secrets.AWS_BUCKET_NAME }}
application: ${{ secrets.APPLICATION }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
- run: mkdir ./back/src/main/resources
- run: touch ./back/src/main/resources/application.yml
- run: echo "${{env.application}}" > ./back/src/main/resources/application.yml
- name: Grant execute permission for gradlew
run: chmod +x gradlew
working-directory: ./back/
- name: Build with Gradle
run: ./gradlew build
working-directory: ./back/
- name: Setup Node.js environment
uses: actions/setup-node@v3.4.1
with:
node-version: '16.17.0'
- name: npm install
run: npm install
working-directory: ./front/
- name: npm build
run: npm run build
working-directory: ./front/
- name: Make zip file
run: zip -r ./full-deploy.zip .
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2
- name: Upload to S3
run: aws s3 cp --region ap-northeast-2 ./full-deploy.zip s3://$S3_BUCKET_NAME/full-deploy.zip
- name: Code Deploy
run: >
aws deploy create-deployment --application-name parking-go
--deployment-config-name CodeDeployDefault.AllAtOnce
--deployment-group-name parking-go-deploy
--s3-location bucket=$S3_BUCKET_NAME,bundleType=zip,key=full-deploy.zip
application.yml을 직접 때려박아 줬다.
뒷단 개발자라고 해봐야 나 포함 2명이니까 메신저로 그냥 공유하면 됨
굳이 암호화 하면서 깃 레포에 올릴 필요 없이 통으로 ignore 때려 버렸다.
그래서 mkdir로 폴더 만들고
touch 로 파일 만들고
깃헙 액션 시크릿에 저장된 yml 설정을 고대로 때려 박아줌.
- run: mkdir ./back/src/main/resources
- run: touch ./back/src/main/resources/application.yml
- run: echo "${{env.application}}" > ./back/src/main/resources/application.yml
(다시는 내 귀찮이즘을 무시하지 마라)
그 뒤로 뭐 npm 하고 빌드 하고 뭐 압축했음.
일단 귀찮으니까 다 압축함.
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-2
aws IAM 키를 박아준다. 이 역시 시크릿을 이용함.
그리고 s3에 업로드 하고, code Deploy를 발동시킨다.
이러면 깃헙 액션 부분은 끝임 여기서 고칠게 생기면 고치면 된다.
뼈대는 완성이 돼 있으니 수정이야 뭐 일도 아니지
잘 올라감
code deploy 설정 역시 웹에 깔려 있다.
일단 ec2에 설치를 잘 해야한다.
다만 IAM롤이 꼬이거나 인스턴스 재시작할 경우 ec2 내부 Code Deploy agent가 맛이 갈 수 있다. 이 땐 agent 재시작을 하면 된다.
sudo service codedeploy-agent status
sudo service codedeploy-agent start
sudo service codedeploy-agent restart
sudo service codedeploy-agent stop
status랑 restart만 알아도 될 듯.
아직 s3에서 ec2로 안퍼와진다. 당연하게도 appspec.yml 파일을 만들어줘야 하기 때문
프로젝트 가장 최상위 디렉토리에
appspec.yml을 만들어주자
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/action
overwrite: yes
file_exists_behavior: OVERWRITE
permissions:
- object: /
pattern: "**"
owner: ubuntu
group: ubuntu
hooks:
ApplicationStart:
- location: scripts/deploy.sh
timeout: 60
runas: ubuntu
파일을 가져와서 home/ubuntu/action 에 넣어줌
이건 선택임 찾기 쉬운 아무데나 넣어도 될 거다.
만약 file이 이미 있으면 덮어쓰기 옵션 추가함.
그리고 마지막으로 ApplicationStart로 scripts/deploy.sh를 발동하게 했다.
내 마지막 난관이 저거 였다. 솔직히 이 윗 과정은 곰방했는데 저 deploy.sh에서 실수 하나 하니까 그거 잡는다고 엄청 고생함.
#!/bin/bash
BUILD_JAR=$(ls /home/ubuntu/action/back/build/libs/parking-go-0.0.1-SNAPSHOT.jar)
JAR_NAME=$(basename $BUILD_JAR)
echo "> 현재 시간: $(date)" >> /home/ubuntu/action/deploy.log
echo "> build 파일명: $JAR_NAME" >> /home/ubuntu/action/deploy.log
echo "> build 파일 복사" >> /home/ubuntu/action/deploy.log
DEPLOY_PATH=/home/ubuntu/action/
cp $BUILD_JAR $DEPLOY_PATH
echo "> 현재 실행중인 애플리케이션 pid 확인" >> /home/ubuntu/action/deploy.log
CURRENT_PID=$(pgrep -f $JAR_NAME)
if [ -z $CURRENT_PID ]
then
echo "> 현재 구동중인 애플리케이션이 없으므로 종료하지 않습니다." >> /home/ubuntu/action/deploy.log
else
echo "> kill -15 $CURRENT_PID" >> /home/ubuntu/action/deploy.log
sudo kill -15 $CURRENT_PID
sleep 5
fi
DEPLOY_JAR=$DEPLOY_PATH$JAR_NAME
echo "> DEPLOY_JAR 배포" >> /home/ubuntu/action/deploy.log
sudo nohup java -jar $DEPLOY_JAR >> /home/ubuntu/deployBe.log 2>/home/ubuntu/action/deploy_err.log &
BUILD_FRONT=/home/ubuntu/action/front/build/
echo "> 현재 실행중인 리액트 pid 확인" >> /home/ubuntu/action/deploy.log
REACT_PID=$(pgrep -f node)
if [ -z $REACT_PID ]
then
echo "> 현재 구동중인 노드가 없으므로 종료하지 않습니다." >> /home/ubuntu/action/deploy.log
else
echo "> kill -15 $REACT_PID" >> /home/ubuntu/action/deploy.log
sudo kill -15 $REACT_PID
sleep 5
fi
echo "> 프론트 서버 배포" >> /home/ubuntu/action/deploy.log
sudo ln -s /home/ubuntu/.nvm/versions/node/v16.17.1/bin/node /usr/bin/node
sudo ln -s /home/ubuntu/.nvm/versions/node/v16.17.1/bin/npm /usr/bin/npm
sudo nohup /home/ubuntu/.nvm/versions/node/v16.17.1/bin/serve -s $BUILD_FRONT >> /home/ubuntu/deployFe.log 2> /home/ubuntu/deploy_Fe_err.log &
echo "> ============== 끝 ==============" >> /home/ubuntu/action/deploy.log
일단 나는 node는 얕게 알고 있음. 아니 java는 그냥 쉘에서 java 때리면 먹는데 node는 왜 안먹는 거야 ㅠㅠㅠ
쨋든 심볼릭 링크를 만들고 넘겼다. (마지막에서 ln -s 명령어 친구들)
문제는 저 심볼릭 링크에 변동사항 (node 버전 변경)이 생길 경우 수동으로 지워야 한다. 이미 존재할 경우엔 덮어 쓰는게 아니라 안만들어줌.
만약 node 버전을 잘 못 깐 뒤에 심볼릭 링크를 만들었다면 수동으로 지우고 깔아줘야 한다. 이미 만들어져 있으므로 저 쉘에선 이제 지워도 될 것으로 보임. 근데 귀찮으니까 걍 냅두고 있다.
내가 가장 오래 걸린 친구가 앞단 리액트 서버 동작인데 왜인지 자꾸 serve를 하면 경로가 2개 이상이 떴다.
이게 머선 일인가 싶어서 보니까 $BUILD_FRONT 변수를 잘못 만들어 놨었다.
컴파일 에러가 뜨는 친구가 아니다보니 사소한 실수 하나가 치명적이게 되는 듯.
쨋든 앞단 뒷단 둘 다 ec2에 성공적으로 업로드 했다.