์ด์ ์ Travis CI + S3 + CodeDeploy ๋ฅผ ํตํด ์คํ๋ง๋ถํธ ํ๋ก์ ํธ๋ฅผ EC2 ์ธ์คํด์ค์ ๋ฐฐํฌํ๋ ๊ณผ์ ๊น์ง ์งํํ์๋ค.
๋๋ ๋์ปค๋ฅผ ํตํ ๋ฐฐํฌ๋ฅผ ์ํด์ ๊ตฌ๊ธ๋ง์ ํด๋ณด๊ธด ํ๋๋ฐ, ๋๋ถ๋ถ "EC2 ํ๊ฒฝ์ ํ๋ก์ ํธ๋ฅผ ์ฌ๋ฆฌ๊ณ , ์ ์คํฌ๋ฆฝํธ๋ฅผ ์ฌ์ฉํด ๋์ปค ์ด๋ฏธ์ง ๋น๋ ํ ์ปดํฌ๋ํธ๋ฅผ ์คํํ๋ ๋ฐฉ์"
์ผ๋ก ๋ด๊ฐ ์ํ๋ ๊ณผ์ ์ด ์๋์๋ค..
์ฐธ๊ณ ๋ฅผ ๋ง์ด ํ๋ ๋ธ๋ก๊ทธ
https://devlog-wjdrbs96.tistory.com/317
๋ด๊ฐ ์ํ ๋ฐฉ์์ ๋์ปคํ๋ธ๋ฅผ ๊ฐ์ด ์ด์ฉํ๋ ๋ฐฉ๋ฒ์ด์์.
๊ทธ๋์ ์๊ฐํ ๋ฐฉ๋ฒ์ Travis CI ํ๊ฒฝ์์ ์ด๋ฏธ์ง ํ์ผ์ ๋น๋ํ์ฌ ๋์ปค ํ๋ธ์ Push, EC2์์ ์ด๋ฏธ์งํ์ผ์ Pull ํด์์ ์ปจํ
์ด๋๋ฅผ ์คํ
์ํค๋ ๋์์ผ๋ก ์ํฌํ๋ก์ฐ๋ฅผ ์์ฑํด๋ณด๊ธฐ๋ก ํ์๋ค.
- Git Hub ์ปค๋ฐ
- Travis CI ์ด๋ฏธ์ง ๋น๋ ๋ฐ ํธ์
- 2-1) SpringBoot .jarํ์ผ์ ๋ง๋ค๊ธฐ ์ํด gradle build
- 2-2) ๋์ปค ํ๋ธ์ ํ๋ก์ ํธ ์ด๋ฏธ์ง Push (SpringBoot .jar๋ก ์ด๋ค์ง)
- 2-3) Nginx์ conf ํ์ผ์ ์ด์ฉํ์ฌ Nginx ์ด๋ฏธ์ง ํ์ผ ๋์ปคํ๋ธ์ Push
- Travis CI Deploy
- 3-1) AWS S3์ [์ ์คํฌ๋ฆฝํธ, ๋์ปค ์ปดํฌ์ฆ ํ์ผ, Appspec ํ์ผ]์ ์์ถํ์ฌ ์ ๋ก๋
- 3-2) CodeDeploy๋ฅผ ํตํด EC2์ ํด๋น ์์ถ ํ์ผ์ ์์ถํด์ ํ์ฌ ๋ฐฐํฌ
- EC2์์ appspecํ์ผ์ ์ ์คํฌ๋ฆฝํธ ํธ๋ฆฌ๊ฑฐ ๋์
- 4-1) ์คํ ์ค์ธ ๋์ปค ์ปจํ ์ด๋ ํ์ธ -> ์ข ๋ฃ
- 4-2) ๋์ปค ์ต์ ์ด๋ฏธ์ง Pull
- 4-3) Pullํ ์ต์ ์ด๋ฏธ์ง๋ก ๋์ปค ์ปจํ ์ด๋ ์คํ
์๋ ์ฐฌ์ฐฌํ ๋ฏ์ด์ ์ค๋ช ํ๋๋ก ํ๊ฒ ๋ค.
branches:
only:
- master
services:
- docker
jobs:
include:
- stage: SpringBoot gradle build & Build Gradle Docker Image
language: java
jdk:
- openjdk11
#cache:
# directories:
# - '$HOME/ .m2/repository'
# - '$HOME/ .gradle'
before_install:
- chmod +x gradlew
script:
- ./gradlew clean build
- docker build -t $SPRING_REPO -f ./Dockerfile .
- echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
- docker push $SPRING_REPO
- stage: Build Nginx Docker image
sudo: required
language: generic
script:
- docker build -t $NGINX_REPO -f ./Dockerfile-nginx .
- echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin
- docker push $NGINX_REPO
- stage: Deploy Stage
language: generic
before_deploy:
- zip -r "s3์ ๋ฑ๋กํ ํ์ผ ์ด๋ฆ" ./docker-compose.yaml ./appspec.yml
- mkdir -p deploy -- ๋ฐฐํฌ์ ์ฐธ์กฐํ ๋๋ ํฐ๋ฆฌ
- mv "s3์ ๋ฑ๋กํ ํ์ผ ์ด๋ฆ".zip deploy/prac-built.zip
after_success:
- wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
- chmod +x send.sh
- ./send.sh success $WEBHOOK_URL
deploy:
- provider: s3
access_key_id: $AWS_ACCESS_KEY
secret_access_key: $AWS_ACCESS_SECRET
bucket: s3 ๋ฒํท์ด๋ฆ
region: ap-northeast-2
skip_cleanup: true
acl: private
local_dir: deploy -- ๋ฐฐํฌ์ ์ฐธ์กฐํ ๋๋ ํฐ๋ฆฌ
wait-until-deployed: true
- provider: codedeploy
access_key_id: $AWS_ACCESS_KEY
secret_access_key: $AWS_ACCESS_SECRET
bucket: s3 ๋ฒํท์ด๋ฆ
key: s3์ ๋ฑ๋ก๋ ํ์ผ ๊ฐ์ฒด ํค ๊ฐ
bundle_type: zip
application: ์ฝ๋ ๋ํ๋ก์ด ์ฑ ์ด๋ฆ
deployment_group: ์ฝ๋ ๋ํ๋ก์ด ๊ทธ๋ฃน ์ด๋ฆ
region: ap-northeast-2
wait-until-deployed: true
branches: only: - master services: - docker
- branches: Travis CI๊ฐ github์ ์ด๋ค ๋ธ๋ ์น์ ์ปค๋ฐ์ด ๋ฐ์ํ์ ๋ ํด๋น travis ํ์ผ์ ์คํํ ์ง ์ ํจ.
- services: Travis ํ๊ฒฝ์์ ์คํํ ์๋น์ค
docker build -t ์ด๋ฏธ์ง์ด๋ฆ:latest -f ./๋์ปคํ์ผ . // -f : ํน์ ๋์ปคํ์ผ์ ์ง์ ํ ๋ ์ฐ๋ ์ต์ // ์ด๋ฏธ์ง์ด๋ฆ : ํ๋ธ์ ์ ์ฅ๋ ์ ์ ๋ค์/๋ ํฌ์ด๋ฆ ์ด๋ ๊ฒ๋ ์ธ์์์ // . : ๋์ปคํ์ผ์ด ์๋ ํ์ฌ ๋๋ ํ ๋ฆฌ
language: ์ฌ์ฉํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ ํ๋ ์ ์ํฌ๋ฅผ ์ง์ ํ๋ ๋ถ๋ถ. ex) language: java -> ์๋ฐ๋ก ์ค์ , language: generic
https://docs.travis-ci.com/user/job-lifecycle/
https://docs.travis-ci.com/user/build-stages/
jobs: include: - stage:
- jobs: ๋จ๊ณ๋ณ ์์ ์ ์คํํ๊ธฐ ์ํ ๋ธ๋ญ. jobs ๋ธ๋ก์ ์ ์๋ ์์ ์ ์์๋๋ก ์คํ๋๋ฉฐ, ๊ฐ ์์ ์ด ์ด์ ์์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์ด์ผ๋ง ์คํ
- include: ์์ ์ ์ธ์ ์ ์๋ฅผ ์ํ ๋ธ๋ญ
- stage: ์->์๋๋ก ์งํ๋๋ ๋จ๊ณ๋ณ ์์ , ์ด๋ฆ์ ๋ถ์ฌํ๊ณ , Travis CI์ ๋น๋ ์คํ ์ด์ง์์ ์ด๋ฅผ ํ์ธ ๊ฐ๋ฅํจ.
jobs: include: - stage: SpringBoot gradle build & Build Gradle Docker Image language: java jdk: - openjdk11 #cache: # directories: # - '$HOME/ .m2/repository' # - '$HOME/ .gradle' before_install: - chmod +x gradlew script: - ./gradlew clean build - docker build -t $SPRING_REPO -f ./Dockerfile . - echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin - docker push $SPRING_REPO
- SpringBoot ํ๋ก์ ํธ๋ฅผ gradle ํ์ผ์ ์ด์ฉํด ๋น๋ํ๊ณ ,
- ๋น๋๋ .jarํ์ผ์ ์ด์ฉํด ๋์ปค ์ด๋ฏธ์งํ์ผ์ ๋น๋ํ๊ณ ๋์ปคํ๋ธ์ ํธ์ฌ.
- .jarํ์ผ์ ๋น๋ ํ์๋ง์ ๋์ปค ์ด๋ฏธ์ง ํ์ผ์ ๋น๋ํ ์ด์ ๋ ๋ ์์ ์ ๋ถ๋ฆฌํ์ฌ stage๋ฅผ ์์ฑํ ์์ ๊ฐ stage๋ ์๋ก ๋ค๋ฅธ vm ํ๊ฒฝ์์ ์คํ๋์ด์ ๋์ปค ์ด๋ฏธ์ง ๋น๋์ .jarํ์ผ์ ์ฐพ์์ ์๊ธฐ ๋๋ฌธ..
ํธ๋ฌ๋ธ ์ํ
- stage: Build Nginx Docker image sudo: required language: generic script: - docker build -t $NGINX_REPO -f ./Dockerfile-nginx . - echo $DOCKER_PASS | docker login -u $DOCKER_USER --password-stdin - docker push $NGINX_REPO
- SpringBoot์ ๋ฆฌ๋ฒ์ค ํ๋ก์๋ฅผ ํตํด ํฌํธํฌ์๋ฉ์ ํด์ค nginx ๋์ปค ์ด๋ฏธ์ง ์์ฑ ํ ๋์ปค ํ๋ธ์ ํธ์
- stage: Deploy Stage language: generic before_deploy: - zip -r "s3์ ๋ฑ๋กํ ํ์ผ ์ด๋ฆ" ./docker-compose.yaml ./appspec.yml - mkdir -p deploy -- ๋ฐฐํฌ์ ์ฐธ์กฐํ ๋๋ ํฐ๋ฆฌ - mv "s3์ ๋ฑ๋กํ ํ์ผ ์ด๋ฆ".zip deploy/prac-built.zip after_success: - wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh - chmod +x send.sh - ./send.sh success $WEBHOOK_URL deploy: - provider: s3 access_key_id: $AWS_ACCESS_KEY secret_access_key: $AWS_ACCESS_SECRET bucket: s3 ๋ฒํท์ด๋ฆ region: ap-northeast-2 skip_cleanup: true acl: private local_dir: deploy -- ๋ฐฐํฌ์ ์ฐธ์กฐํ ๋๋ ํฐ๋ฆฌ wait-until-deployed: true - provider: codedeploy access_key_id: $AWS_ACCESS_KEY secret_access_key: $AWS_ACCESS_SECRET bucket: s3 ๋ฒํท์ด๋ฆ key: s3์ ๋ฑ๋ก๋ ํ์ผ ๊ฐ์ฒด ํค ๊ฐ bundle_type: zip application: ์ฝ๋ ๋ํ๋ก์ด ์ฑ ์ด๋ฆ deployment_group: ์ฝ๋ ๋ํ๋ก์ด ๊ทธ๋ฃน ์ด๋ฆ region: ap-northeast-2 wait-until-deployed: true
before_deploy: ๋ฐฐํฌ์ ํ ๋์์ ์คํฌ๋ฆฝํธ ๋์์ ์ ์
- ๋ฐฐํฌํ ํ์ผ์ s3์ ๋ฑ๋กํ๊ธฐ ์ํด zipํ์ผ์ ๋ด์.
- ๋ฐฐํฌ๋ฅผ ์ฐธ์กฐํ ๋๋ ํ ๋ฆฌ๋ก ์์ฑ
- ๋ฐฐํฌํ ํ์ผ์ ํด๋น ์ฐธ์กฐ ๋๋ ํ ๋ฆฌ๋ก ์ด๋
after_success: ๋ฐฐํฌ ์ฑ๊ณต ํ ๋์
- ์น ํ ์ ํตํด Travis CI ์ ์์ ๊ฒฐ๊ณผ๋ฅผ ์ ์กํ๋ค.
https://github.com/DiscordHooks/travis-ci-discord-webhookdeploy: ๋ฐฐํฌํ๋ ๋์์ ์ ์ํ๋ ๋ธ๋ญ
provider: s3: ๋ฒํท์ ํ์ผ์ ์ ๋ก๋ํ๊ธฐ ์ํ ์ค์ ์ ์ ์
access_key_id ๋ฐ secret_access_key: AWS ๊ณ์ ์ ์ก์ธ์ค ํค ID ๋ฐ ๋น๋ฐ ์ก์ธ์ค ํค๋ฅผ ์ค์
bucket: S3 ๋ฒํท์ ์ด๋ฆ์ ์ง์
region: AWS ๋ฆฌ์ ์ ์ง์
skip_cleanup: ๋น๋ ํ์ ์์ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ ๋ฆฌํ์ง ์๋๋ก ์ค์
acl: S3 ๊ฐ์ฒด์ ๋ํ ์ก์ธ์ค ์ ์ด๋ฅผ ์ค์ ํฉ๋๋ค (์ฌ๊ธฐ์๋ private์ผ๋ก ์ค์ ).
local_dir: ๋ฐฐํฌ์ ์ฌ์ฉํ ๋ก์ปฌ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ง์ (์ด ๋๋ ํฐ๋ฆฌ์ ํ์ผ๋ค์ S3๋ก ์ ๋ก๋).
wait-until-deployed: ๋ฐฐํฌ๊ฐ ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด์ง ์ฌ๋ถprovider: codedeploy: AWS CodeDeploy๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐฐํฌ๋ฅผ ์ํํ๊ธฐ ์ํ ์ค์
access_key_id ๋ฐ secret_access_key: AWS ๊ณ์ ์ ์ก์ธ์ค ํค ID ๋ฐ ๋น๋ฐ ์ก์ธ์ค ํค๋ฅผ ์ค์
bucket: CodeDeploy์์ ์ฌ์ฉํ S3 ๋ฒํท์ ์ด๋ฆ์ ์ง์
key: S3 ๋ฒํท์ ๋ฑ๋ก๋ ํ์ผ ๊ฐ์ฒด์ ํค ๊ฐ
bundle_type: ๋ฐฐํฌํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฒ๋ค ํ์ ์ ์ง์ (์ฌ๊ธฐ์๋ zip).
application: CodeDeploy ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด๋ฆ์ ์ง์
deployment_group: CodeDeploy ๋ฐฐํฌ ๊ทธ๋ฃน์ ์ด๋ฆ์ ์ง์
region: AWS ๋ฆฌ์
wait-until-deployed: ๋ฐฐํฌ๊ฐ ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆด์ง ์ฌ๋ถ๋ฅผ ์ค์
FROM openjdk:11
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar", "-Dspring.profiles.active=${active}", "-Duser.timezone=Asia/Seoul", "/app.jar"]
FROM nginx
COPY nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf
version: "3"
services:
web:
image: adultkim/jpa-nginx:latest
container_name: nginx
restart: always
ports:
- "80:80"
spring:
build: .
image: adultkim/jpapractice:latest
container_name: server
expose:
- 8081
ports:
- "8081:8081"
environment:
active: prod
version: 0.0
os: linux
files:
- source: /
destination: /home/ubuntu/app/docker/zip
overwrite: yes
hooks:
AfterInstall:
- location: docker-hub.sh
timeout: 300
runas: root
https://jinmay.github.io/2020/05/13/aws/run-shell-script-aws-code-deploy/
https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/reference-appspec-file.html
#!/bin/bash
container_id=$(docker ps -qa)
if [ -z ${container_id} ]
then
echo "ํ์ฌ ์คํ์ค์ธ ์ปจํ
์ด๋ X"
else
echo "ํ์ฌ ์คํ์ค์ธ ์ปจํ
์ด๋: ${container_id}"
echo "์ปจํ
์ด๋ ์ค์ง"
sudo docker stop ${container_id}
echo "์ปจํ
์ด๋ ์ญ์ "
sudo docker rm -f ${container_id}
sleep 3
fi
echo "์ด๋ฏธ์ง ํ์ผ Pull"
sudo docker pull adultkim/jpapractice:latest
sudo docker pull adultkim/jpa-nginx:latest
echo "์ปจํ
์ด๋ ์ฌ ์์"
docker-compose -f /home/ubuntu/app/docker/zip/docker-compose.yaml up -d
๋ฐฐํฌ ๊ณผ์
๊ณผ ๋์ปค ์ด๋ฏธ์ง/์ปจํ
์ด๋ ์ ์ฐจ์ด
์ ๋ํ ์ ๋ฐ์ ์ธ ํ๋ฆ์ ๋ํ ์ดํด๊ฐ ๋ถ์กฑํ์์ง๋ง ๋ชจ๋ ๊ณผ์ ์ ํ๋ฉด์ ์๊ฒ ๋ ์ฌ์ค๋ค์ ์ ์ด ๋ณด์๋ค..
GPT ๋์์ ๋ง์ด ๋ฐ์..ใ
ใ
ํด๋น ํ๋ก์ ํธ์์ TravisCI ์ ์ญํ ์ GitHub์ ์ปค๋ฐ๋ฉ์์ง๋ฅผ ๋ณด๋ด์๋ง์ ๋ณ๊ฒฝ์ฌํญ์ ํตํฉํ๊ณ , ๋ฐฐํฌํ๊ธฐ ์ํ ์ ํด์ง ์ผ๋ จ์ ์์ ๋ค์ ์งํํ๋ ๊ฒ์ด๋ค. (๋น์ทํ ์๋ก๋ GitHub Action ๋ ์กด์ฌํจ)
S3๋ Travis CI์์ ๋น๋๋ ํ์ผ๊ณผ ์ปดํฌ๋ํธ๋ฅผ ์คํํ๊ธฐ ์ํ ํ์ผ, ์ด๋ฏธ์งํ์ผ์ Pullํ๊ณ ์ปดํฌ๋ํธ๋ฅผ ์คํํ ์ ์คํฌ๋ฆฝํธ ๋ฑ EC2์์ ํ์ํ ํ์ผ๋ค์ ๋ฐฐํฌํ๊ธฐ์ ์ ์ ์ฅํด๋๋ ์ธ๋ถ ์ ์ฅ์ ์ญํ ์ ํ ๊ฒ์ด๋ค.
CodeDeploy๋ S3์ ์ ์ฅ๋ ํ์ผ๋ค์ EC2์ธ์คํด์ค์ ๋ฐฐํฌํ๋ ์ญํ ์ ํ๋ค.
๋๋ ์ฒ์์ ์ด๋ฏธ์ง๋ผ๋ ๊ฐ๋ ์ด ๋๋ฌด ์์ํ๊ณ , ์ด๋ป๊ฒ ๋ฐ์๋ค์ฌ์ผ ํ ์ง ๋ชฐ๋๋ค.
ํ์ง๋ง ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๊ธฐ ์ํ ๋ชจ๋ ์ค์ ์ด ๋ชจ๋ ๋๋ ํจํค์ง๋ผ๋ ๋ง์ ๋ณด๊ณ , ๊ทธ๋ฅ ์คํํ๊ธฐ ์ ๋น๋ ์๋ฃ๋ ํ๋ก๊ทธ๋จ์ผ๋ก ์ฝ๊ฒ ์๊ฐํ๋ฉด ๋๊ฒ ๋ค๊ณ ๋๋..
๋ ๋ฐฐํฌํ๋ ๊ณผ์ ์์ ๋์ปคํ์ผ์ด SpringBoot ํ๋ก์ ํธ์์ ์ด๋ฏธ์งํ์ผ์ ๋ง๋๋ ๊ธฐ์ค์ ํด๋น ํ๋ก์ ํธ์ .jarํ์ผ์ ๊ฐ์ง๊ณ ์งํํ์๊ธฐ ๋๋ฌธ์ ๋น๋๊ฐ ์๋ฃ๋๊ณ ์คํํ ์ ์๋ ์ฝ๊ธฐ ์ ์ฉ ํ์ผ์ด๊ตฌ๋ ๋ผ๊ณ ๋๋ผ๊ฒ ๋์๋ค.
ex) .jarํ์ผ, Ubuntu ์ด๋ฏธ์ง ํ์ผ
- ์ปจํ ์ด๋๋ ๋ง์นจ๋ด ์ด๋ฏธ์งํ์ผ์ ํ๋์ ์ธ์คํด์ค๋ก ์คํํ๊ฒ ๋๋ค๊ณ ํ๋ค.
- ์ปจํ ์ด๋๋ผ ํจ์ ์ฐ๋ฆฌ๊ฐ ๊ฐ์๋จธ์ ์ ์ด์ฉํด์ ํ OS์์ ์ฌ๋ฌ OS๋ฅผ ๋๋ฆฌ๋ฏ์ด, ์ด๋ฏธ์ง ํ์ผ์ด ๊ฒฉ๋ฆฌ๋ ๊ณต๊ฐ์ ๋ ๋ฆฝ๋ ํ๋ก์ธ์ค๋ก์ ๋์๊ฐ๊ฒ๋๋ค.
- ์ฆ ๋์ปค์์ ํ๋ก์ ํธ๋ฅผ ์ด๋ฏธ์ง ํ์ผ๋ก ๋น๋ํ ํ, ์ปจํ ์ด๋๋ฅผ ํตํด ์คํํ๋ ๊ฒ!