EC2를 생성하고 터미널에서 EC2 인스턴스에 접속한다.
sudo chmod 400 <키페어 경로>
ssh ubuntu@<EC2 주소> -i <키페어 경로>
이후 docker를 설치한다.
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
이후 필요한 포트 번호를 모두 열어 준다.
docker pull jenkins/jenkins:lts
명령어를 통해 가장 최신 버전 (lts)의 jenkins Container를 다운로드받는다.
sudo docker run -d -p 9080:8080 -v /jenkins:/var/jenkins_home --name jenkins -u root jenkins/jenkins
-d: 백그라운드 모드 실행
-p: 포트 지정해서 9080으로 띄우기
-v: 볼륨 마운트
jenkins 이미지를 실행시키면 EC2인스턴스:9080에 jenkins 화면이 보인다.
초기화 비밀번호를 알아내기 위해 bash로 접속해야 한다.
docker exec -it jenkins /bin/bash
cat /var/jenkins_home/secrets/initialAdminPassword
다음과 같은 비밀번호가 보이면 성공이다.
아래와 같은 화면에서 로그인하면 된다. 이후 추천해 주는 플러그인들을 다 다운로드받는다.
아이디와 비밀번호를 설정해 주면 젠킨스 초기 설정이 끝난다.
.github → workflows 폴더 밑에 deploy.yml 파일을 작성해 준다.
name: Chatfia Dev CI/CD
on:
pull_request:
types: [closed]
workflow_dispatch: # (2).수동 실행도 가능하도록
jobs:
build:
runs-on: ubuntu-latest # (3).OS환경
if: github.event.pull_request.merged == true # 만약 main에 머지될 때로 하고 싶다면
# && github.event.pull_request.base.ref == 'main'
steps:
- name: Checkout
uses: actions/checkout@v2 # (4).코드 check out
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: 17 # (5).자바 설치
distribution: 'adopt'
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
shell: bash # (6).권한 부여
- name: Build with Gradle
run: ./gradlew clean build -x test
shell: bash # (7).build 시작
- name: Get current time
uses: 1466587594/get-current-time@v2
id: current-time-build
with:
format: YYYY-MM-DDTHH-mm-ss
utcOffset: "+09:00" # (8).build 시점의 시간 확보
- name: Show Current Time
run: echo "CurrentTime=$"
shell: bash # (9).확보한 시간 보여 주기
- name: Test with Gradle
run: ./gradlew --info test # (10).test 시작
- name: Get current time
uses: 1466587594/get-current-time@v2
id: current-time-test
with:
format: YYYY-MM-DDTHH-mm-ss
utcOffset: "+09:00" # (11).test 시점의 시간 확보
- name: Show Current Time
run: echo "CurrentTime=$"
shell: bash # (12).확보한 시간 보여 주기
- name: Generate deployment package
run: |
mkdir -p deploy
cp build/libs/*.jar deploy/application.jar
cp Procfile deploy/Procfile
cp -r .ebextensions deploy/.ebextensions
cp -r .platform deploy/.platform
cd deploy && zip -r deploy.zip .
- name: Beanstalk Deploy
uses: einaregilsson/beanstalk-deploy@v20
with:
aws_access_key: ${{ secrets.AWS_ACTION_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.AWS_ACTION_SECRET_ACCESS_KEY }}
application_name: fithub-prod
environment_name: Fithub-prod-env
version_label: github-action-${{ steps.current-time.outputs.formattedTime }}
region: ap-northeast-2
deployment_package: deploy/deploy.zip
wait_for_environment_recovery: 60
아래와 같은 설정으로 vpc를 만들어 준다.
이후 생성한 vpc에 대해 subnet을 만들어 준다. 이때 elastic beanstalk은 일반적으로 서브넷 두 개 이상을 사용하기 때문에 두 개를 만들어 준다.
새로운 internet gateway를 만들어 준다.
이후 만든 vpc를 연결해 준다.
내가 만든 vpc의 라우팅 테이블에 가 보면 안으로 들어오는 것만 있다. 따라서 밖으로 나가는 것까지 설정해 줘야 한다.
우리가 만든 게이트웨이로 설정해 준다.
이후 서브넷 연결에서 만든 서브넷을 public으로 등록해 줄 수 있다. private으로 하면 고생하니까 둘 다 public으로 해 준다. 일단 private은 돈이 많이 나간다.
이후에 ec2에 올라갈 보안 그룹을 설정한다. default VPC가 아닌 내가 아까 만들었던 VPC로 설정한다.
빈스톡이 자동으로 Ec2도 만들고 할 예정인데, 그 작업이 가능하게 하려면 역할을 줘야 한다.
새로운 역할을 다음과 같이 생성해 준다.
이후 다음과 같이 ec2에 대한 권한을 가진 역할을 만들어 준다.
위 사진에 보면 현재 elasticbeanstalk이 사용할 role인데 ec2 서비스라고 되어 있다. 저 부분을 elasticbeanstalk.amazonaws.com으로 바꿔 준다.
이번에는 ec2에게 권한을 줄 역할을 생성한다.
환경 생성에 접속해서 이름을 정해 준다.
우리의 플랫폼인 자바를 선택한다. 그리고 사전 설정을 custom으로 변경한다.
IAM에서 만든 role을 넣어 준다.
만들어 둔 VPC를 설정하고 public IP를 활성화시킨다. 빈스톡과 ec2가 서로 작업이 잘 마무리되었는지 통신하려면 퍼블릭 ip를 열어 둬야 한다.
이후 다음을 눌러 보안 그룹을 설정해 준다.
이후 용량에서 하나의 인스턴스를 하면 중단 배포가 된다.
하지만 무중단 배포를 하기 위해 인스턴스를 여러 개 두는 방식을 선택한다.
나중에 domain을 만들고서는 https 설정으로 바꿔야 한다.
이후 process의 deafult에서 helath 루트를 추가해 준다.
빈스톡 배포에 문제가 있을 때 이유를 알기 위해 강화됨을 선택해 준다.
이후 추가 배치를 사용한 롤링 옵션을 선택해 무중단 배포가 되도록 한다.
이후 기본 포트를 8080으로 설정해 준다.
action을 사용해 배포할 사용자를 만들어 준다.
정책에 직접 연결하는 것을 선택하고 다음 권한을 준다.
이후 보안 자격 증명 탭으로 간다.
외부에서 진행하는 키를 만든다.
사용자를 생성하면 나오는 Access Key와 Secret을 Github secret에 넣어 준다.
키들이 잘 들어간 모습이다.
내가 실행할 프로젝트 루트 폴더에 다음과 같은 .ebextenstions/00-makeFiles.config를 만든다.
내용은 아래와 같이 채워 준다.
files:
"/sbin/appstart" :
mode: "000755"
owner: webapp
group: webapp
content: |
#!/usr/bin/env bash
JAR_PATH=/var/app/current/application.jar
# run app
killall java
java -Dfile.encoding=UTF-8 -jar $JAR_PATH
이번에는 .platform/nginx.conf 파일을 작성해 준다.
user nginx;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
worker_processes auto;
worker_rlimit_nofile 33282;
events {
use epoll;
worker_connections 1024;
multi_accept on;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
include conf.d/*.conf;
map $http_upgrade $connection_upgrade {
default "upgrade";
}
upstream springboot {
server 127.0.0.1:8080;
keepalive 1024;
}
server {
listen 80 default_server;
listen [::]:80 default_server;
location / {
proxy_pass http://springboot;
proxy_http_version 1.1;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
access_log /var/log/nginx/access.log main;
client_header_timeout 60;
client_body_timeout 60;
keepalive_timeout 60;
gzip off;
gzip_comp_level 4;
# Include the Elastic Beanstalk generated locations
include conf.d/elasticbeanstalk/healthd.conf;
}
}
이후 Procfile을 만들고 내용을 web: appstart로 작성해 준다.
이후 build.gradle에 아래 코드를 추가해 준다.
jar {
enabled: false
}
마지막으로 git에 push하고 main에 머지하면 배포가 완료된다.
많은 것을 배웠습니다, 감사합니다.