Deploy๐ŸŽ

[Docker] AWS EC2 + Docker + RDS ๊ตฌ์ถ•

hae02y 2023. 11. 8. 20:49
๋ฐ˜์‘ํ˜•

๋“ค์–ด๊ฐ€๊ธฐ์ „์—

CI / CD์™€ ๋งž์งฑ๋œจ๋Š” ๋‚˜ (๊ฒจ์šฐ์ด๊น€)

์ด๋ฒˆ์— ์‹œ์ž‘ํ•œ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” Docker๋ฅผ ์ ์šฉํ•ด์„œ CI / CD๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ๋กœ ํ•˜์˜€๋‹ค. ๊ธฐ์กด์—๋Š” Github Action + CodeDeploy + EC2 + RDS ์กฐํ•ฉ์ด์˜€์ง€๋งŒ ์„œ๋ฒ„์ƒ์˜ ๋ฌธ์ œ๊ฐ€ ๊ฝค๋งŽ๊ธฐ๋„ ํ•˜๊ณ  ํ™˜๊ฒฝ๋ณ€์ˆ˜์ ์šฉ์ด๋‚˜ AWS์‚ฌ์šฉ ๋ฐฉ๋ฒ•๋“ฑ ๋‹ค์–‘ํ•œ ๊ฒƒ๋“ค์ด ๋ฐœ๋ชฉ์„ ์žก์•„์„œ ๋‚ด์นœ๊น€์— ๊ณต๋ถ€ํ•ด์„œ Docker๋ฅผ ์ ์šฉํ•ด ๋ณด์•˜๋‹ค. ์ •๋ง ์‚ฝ์งˆ์˜ ์—ฐ์†์ด์˜€์ง€๋งŒ ํ•ด๋ƒˆ์„๋•Œ์˜ ๋ฟŒ๋“ฏํ•จ์ด๋ž€...ใ…Žใ…Ž

 

์ž๊ทธ๋Ÿผ ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.

https://lucas-owner.tistory.com/48

https://velog.io/@9to0/CICD-Github-Action-%EC%82%AC%EC%9A%A9%ED%95%A0-%EB%95%8C-Docker-%ED%99%98%EA%B2%BD%EB%B3%80%EC%88%98-%EC%84%A4%EC%A0%95

 

 

 

 

 

๋ฐฐํฌ ์ „๋žต

 

์ด๋ฒˆ์— ๊ตฌ์„ฑ๋  ๋ฐฐํฌ ์ „๋žต์€ ๊ทธ๋ฆผ๊ณผ ๊ฐ™๋‹ค. ์ˆœ์„œ๋ฅผ ๋‚˜์—ดํ•ด๋ณด๋ฉด

  1. Github์˜ back(branch) ์— Push๋‚˜ PR ์š”์ฒญ์ด ๋ฐœ์ƒ์‹œ
  2. Github Action์ด ๋™์ž‘ํ•˜๊ณ  ๋นŒ๋“œ๋ฅผ ํ†ตํ•ด Jar ํŒŒ์ผ์„ ์ƒ์„ฑํ•œ๋‹ค.
  3. ๋˜ํ•œ build๋ฅผ ์ง„ํ–‰ํ•จ๊ณผ ๋™์‹œ์— Docker Hub์— ๋กœ๊ทธ์ธํ•˜๊ณ  Hub Repository์— ์˜ฌ๋ฆฐ๋‹ค.
  4. Docker Hub์— Push ํ•˜๋Š” ๊ณผ์ •์—์„œ DockerFile์„ ์ฐธ๊ณ ํ•ด ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋“ฑ ์„ค์ •๊ฐ’๋“ค์„ ๋„ฃ์–ด์ค€๋‹ค.
  5. Push๋œ Image๋ฅผ EC2์—์„œ pull ํ•œ๋‹ค. 
  6. EC2 ์—์„œ ํ•ด๋‹น ์ด๋ฏธ์ง€๋ฅผ ์ปจํ…Œ์ด๋„ˆ๋กœ ์‹คํ–‰(run) ์‹œํ‚จ๋‹ค.
  7. ์‹คํ–‰๋˜๋Š” 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๋ฅผ ์ž˜ ๋ณด๊ณ  ์„ค์ •ํ•ด์ฃผ์ž.

 

๋ฐ˜์‘ํ˜•