๋ค์ด๊ฐ๊ธฐ์ ์
์ด๋ฒ์ ์์ํ ํ๋ก์ ํธ์์๋ Docker๋ฅผ ์ ์ฉํด์ CI / CD๋ฅผ ๊ตฌํํ๊ธฐ๋ก ํ์๋ค. ๊ธฐ์กด์๋ Github Action + CodeDeploy + EC2 + RDS ์กฐํฉ์ด์์ง๋ง ์๋ฒ์์ ๋ฌธ์ ๊ฐ ๊ฝค๋ง๊ธฐ๋ ํ๊ณ ํ๊ฒฝ๋ณ์์ ์ฉ์ด๋ AWS์ฌ์ฉ ๋ฐฉ๋ฒ๋ฑ ๋ค์ํ ๊ฒ๋ค์ด ๋ฐ๋ชฉ์ ์ก์์ ๋ด์น๊น์ ๊ณต๋ถํด์ Docker๋ฅผ ์ ์ฉํด ๋ณด์๋ค. ์ ๋ง ์ฝ์ง์ ์ฐ์์ด์์ง๋ง ํด๋์๋์ ๋ฟ๋ฏํจ์ด๋...ใ ใ
์๊ทธ๋ผ ํ๋์ฉ ์์๋ณด๋๋ก ํ์.
https://lucas-owner.tistory.com/48
๋ฐฐํฌ ์ ๋ต
์ด๋ฒ์ ๊ตฌ์ฑ๋ ๋ฐฐํฌ ์ ๋ต์ ๊ทธ๋ฆผ๊ณผ ๊ฐ๋ค. ์์๋ฅผ ๋์ดํด๋ณด๋ฉด
- Github์ back(branch) ์ Push๋ PR ์์ฒญ์ด ๋ฐ์์
- Github Action์ด ๋์ํ๊ณ ๋น๋๋ฅผ ํตํด Jar ํ์ผ์ ์์ฑํ๋ค.
- ๋ํ build๋ฅผ ์งํํจ๊ณผ ๋์์ Docker Hub์ ๋ก๊ทธ์ธํ๊ณ Hub Repository์ ์ฌ๋ฆฐ๋ค.
- Docker Hub์ Push ํ๋ ๊ณผ์ ์์ DockerFile์ ์ฐธ๊ณ ํด ํ๊ฒฝ๋ณ์ ๋ฑ ์ค์ ๊ฐ๋ค์ ๋ฃ์ด์ค๋ค.
- Push๋ Image๋ฅผ EC2์์ pull ํ๋ค.
- EC2 ์์ ํด๋น ์ด๋ฏธ์ง๋ฅผ ์ปจํ ์ด๋๋ก ์คํ(run) ์ํจ๋ค.
- ์คํ๋๋ JAR ํ์ผ์ Docker ์์์ ๋์ํ๋ฉฐ ์ค์ ๊ฐ๋๋ก ์ง์ ๋ RDS๋ฅผ DB๋ก ์ฌ์ฉํ ๊ฒ์ด๋ค.
์ด๊ณผ์ ์ CI / CD ๋ฅผ ํตํด์ ์๋ํ ์ํฌ๊ฒ์ด๋ค.
์ ์ฉ ๊ณผ์
EC2 ์ค์
์ผ๋จ EC2 ์๋ฒ ์ค์ ์ ์๋ตํ์.
RDS ์ค์
RDS ์ธํ ๊น์ง๋ ๋ฏธ๋ฆฌ ๋์์ด์ผ ํ๋ค.
Github Action ์ธํ
๊นํ์ก์ ์ ๋์์ํค๊ธฐ ์ํด์ ๋ค์ํ ์ค์ ๋ฐฉ๋ฒ์ด ์์ง๋ง ๋ด๊ฐ ํ๋ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํด์ ์ ์ด๋ณด๊ฒ ๋ค.
1. .github / workflows / cicd.yml ์ค์
##
name: Java CI with Gradle
on: # (1) on์ค์ ์ ํตํด ์ธ์ github Action์ ์คํ์ํฌ์ง ์ ํ๋ค. ํด๋น๋ธ๋์น์ yml ํ์ผ์ด ์์ด์ผํ๋ค.
pull_request:
branches: [ back ] # PR์ด ์ ์ฉ๋ ๋ธ๋์น
push:
branches: [ back ] # Push๊ฐ ์ ์ฉ๋ ๋ธ๋์น
jobs:
build:
runs-on: ubuntu-latest
env:
working-directory: ./server #cicd๊ฐ ์ ์ฉ๋ ํ๊ฒฝ์ env๋ก ์ ์ฉ
steps:
- uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'zulu'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
working-directory: ${{env.working-directory}}
- name: Build with Gradle
run: ./gradlew clean build --warning-mode all --scan -x test # clean build ์ ์ฉ
working-directory: ${{env.working-directory}}
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }} #docker Username ์ง์
password: ${{ secrets.DOCKER_HUB_PASSWORD }} #docker Password / Key ์ง์
- name: Build and push register app # docker์ repository๋ ์๋ฌธ์๋ก ํด์ผํ๋ค.
run: |
docker build -t newstudyground -f ./server/Dockerfile . #๋์ปคํ์ผ ์์น ์ง์
docker tag newstudyground ${{ secrets.DOCKER_HUB_USERNAME }}/newstudyground:${GITHUB_SHA::7} #๋์ปค ํ๊ทธ์ค์
docker push ${{ secrets.DOCKER_HUB_USERNAME }}/newstudyground:${GITHUB_SHA::7} #๋ง๋ค์ด์ง ์ด๋ฏธ์ง๋ฅผ ์
๋ก๋
env:
GITHUB_SHA: ${{ github.sha }} #github์์ ์๋์ผ๋ก ๋ง๋ค์ด์ง๋๊ฐ. ๋ฐ๋ก ํ๊ฒฝ๋ณ์ ์ง์ ์ํด์ค๋ ๋๋ค.
- name: Configure AWS credentials #์ฌ๊ธฐ๋ถํฐ AWS ๋ก๊ทธ์ธ (์์ค์ ํด์ฃผ์)
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: Start Session Manager session
run: aws ssm start-session --target ${{ secrets.AWS_INSTANCE_ID }}
- name: Deploy to Server # EC2 ์๋ฒ์ ๋ฐฐํฌ
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
AWS_REGION: ap-northeast-2
run: |
aws ssm send-command \
--instance-ids ${{ secrets.AWS_INSTANCE_ID }} \
--document-name "AWS-RunShellScript" \
--parameters "commands=[
'if sudo docker ps -a --format \\'{{.Names}}\\' | grep -q \'^server$\\'; then',
' sudo docker stop server', # ๊ธฐ์กด ์๋ฒ๋ฅผ ์คํ์ํค๊ณ
' sudo docker rm server', # ์ง์์ค๋ค์
'fi',
'sudo docker pull hae02y/newstudyground:${GITHUB_SHA::7}', #dockerhub์์ ์ด๋ฏธ์ง๋ฅผ ๋ก๊ฒจ์จ๋ค.
'sudo docker tag hae02y/newstudyground:${GITHUB_SHA::7} newstudyground', #ํ๊ทธ๊น์ง ์ง์ ํด์ค๋ค์
'sudo docker run -e TZ=Asia/Seoul -d --name server -p 8080:8080 newstudyground' #์คํ์ํจ๋ค.
]" \
--output text
๊ทธ๋๋ก ๋ณต๋ถํด์ ์ฌ์ฉํ๋ฉด ์๋ฌ๊ฐ ๋ ๊ฒ์ด๋ค. ์ฃผ์๋๋ถ๋ถ์ ์ ๊ฑฐํ์ ์ฌ์ฉํ๋๊ฒ์ด ์ข์๊ฒ๊ฐ๋ค. ์ค๋ช ๋๋ก ๋ฐ๋ผ์ ์ง์ ํด์ฃผ๋ฉด ๋๋ค. ๋ค์์ผ๋ก Dokerfile์ ์ธํ ํด๋ณด์.
2. /server/Dockerfile ์ค์
FROM openjdk:11-jdk
# โญ 'ARG' ์์ฝ์ด๋ฅผ ํตํด ์ธ์๋ก ์ ๋ฌ ๋ฐ์์ผ ํ๋ค.
ARG ADMIN_EMAIL \
AWS_ACCESS_KEY \
AWS_SECRET_KEY \
EMAIL_PASSWORD \
JWT_SECRET_KEY \
KAKAO_CLIENT_ID \
KAKAO_CLIENT_SECRET \
RDS_USERNAME \
RDS_PASSWORD
# โญ 'ENV' ์์ฝ์ด๋ฅผ ํตํด ์ ๋ฌ๋ฐ์ ๊ฐ์ ์ค์ ๊ฐ๊ณผ ๋งค์นญ์์ผ์ผ ํ๋ค.
ENV ADMIN_EMAIL=${ADMIN_EMAIL} \
AWS_ACCESS_KEY=${AWS_ACCESS_KEY} \
AWS_SECRET_KEY=${AWS_SECRET_KEY} \
EMAIL_PASSWORD=${EMAIL_PASSWORD} \
JWT_SECRET_KEY=${JWT_SECRET_KEY} \
KAKAO_CLIENT_ID=${KAKAO_CLIENT_ID} \
KAKAO_CLIENT_SECRET=${KAKAO_CLIENT_SECRET} \
RDS_USERNAME=${RDS_USERNAME} \
RDS_PASSWORD=${RDS_PASSWORD}
# (2) COPY์์ ์ฌ์ฉ๋ ๊ฒฝ๋ก ๋ณ์
ARG JAR_FILE=/server/build/libs/*.jar
# (3) jar ๋น๋ ํ์ผ์ ๋์ปค ์ปจํ
์ด๋๋ก ๋ณต์ฌ
COPY ${JAR_FILE} app.jar
# (4) jar ํ์ผ ์คํ
ENTRYPOINT ["java", "-Dspring.profiles.active=docker", "-jar", "app.jar"]
(2)์์ ๋ณด๋ฉด copyํ ๋์ ๊ฒฝ๋ก๊ฐ ๋์์ผํ๋๋ฐ ์ด๋ถ๋ถ์์ ํ์ฐธ ์ ๋จน์๋ค. target Folder๋ฅผ ์ ๋ณด๊ณ ์ค์ ํด์ฃผ์.