https://github.com/geonho1943/LFG
GitHub - geonho1943/LFG: "Looking For Group" service
"Looking For Group" service. Contribute to geonho1943/LFG development by creating an account on GitHub.
github.com
만들고 있는 LFG 서비스를 서버에 배포했다
배포하기전에는
새로운 기능을 완성한 프로젝트를
이상이 없는지 확인 후 커밋 하면 끝이었다
하지만 지금은
빌드하고 서버에 빌드파일을 교체, 실행 해줘야 한다
빌드 > FTP 접속 > 빌드 파일 추가 > ssh 접속 >
기존 서비스 로그 확인 > 서비스 프로세스 종료 > 프로세스 종료 확인 >
추가한 빌드 파일 권한 변경 > 추가한 빌드 파일 실행 > 새로운 서비스 로그 확인 > 서비스 정상작동 확인
같은 과정이 반복되다 보니 자동으로 배포가 되도록 구현하고 싶었다
그리고 서비스에 큰 수정사항이 없을때
서버를 갱신할 필요를 느끼지 못했는데
그렇게 갱신하지않을경우 깃허브의 프로젝트 내용과
실제 실행중인 서버의 내용이 다르게 되기때문에
배포 자동화를 도입 하기로 했다
처음시도하는 자동 배포기 때문에
공부에 시간을 아끼지않았다
구글링, 유튜브, 기술 블로그, chatgpt, 공식문서 등등 다양한 방법으로
서칭했고 더블체크 했다
배포자동화를 알게 되면서
CI/CD 에 대해서도 알아봤는데
CI/CD(Continuous Delivery)의 CD와
CD(Continuous Deployment) 의 CD
둘을 구분하고 있었다
배포 deploy가 중요한것이다
나의 경우 어떻게 프로젝트를 만들어나갈지 고민했다
빌드시 자동배포를 우선목표로 하고
자동배포의 경우 분명 실수가 생겨 기능에 문제가 생길수 있으니
test case를 도입하여
좀더 신뢰 할수 있는 환경을 목표로 잡았다
자동배포에 필요한 개념서칭
자동화 툴 선택 - github action
github action 의 사용법 - actions quickstart
원하는 기능구현에 필요한 액션 - ssh-scp-ssh-pipelines
기능 구현 하기
프로잭트 리포지터리 접근
Java JDK 설치
gradlew 로 빌드
ssh 접속
빌드파일 전송
필요 권한으로 빌드파일 백그라운드 실행
배포 자동화 성공
webhook는 외부 클라이언트에 알람을 주는등의
기능으로 별도의 툴이 아니라 push 이벤트의 트리거를 해주는 역할이다
Jenkins 나 CircleCI 를 사용할까 생각했지만
배포만을 위한 외부 서버(인스턴스)가 이상적인 상황이 아니라서
github action이 나에게 가장 적합했다
단점이라면 github 에 public 리포지터리가 있어야
github action을 사용 할수 있다는것이다
나의경우에는 이미 github/public에 올리고 있었기 떄문에 해당사항이 아니다

aws가 이렇게 반갑다니,,
최근에 오라클로 옮겼는대 여기서 aws가 보인다 ㅠㅠ
아쉽지만 직접 워크플로우를 작성해 준다
+ chatgpt를 시도해보았다

chatgpt는 간혹 거짓정보를 알려줄때가 있으니 하나하나 검증하면서 양식을 맞춰가야 한다

oracleLinux8 이라는 단어는 공식문서 자체에도 없도 지원하지않는다..
직접 작성하는것이 빠를것 같아 chatGPT는 다음에 사용하기로 했다
직접 공식문서의 quick start 를 해봤다

첫 Action 성공
https://docs.github.com/en/github-ae@latest/actions/quickstart
Quickstart for GitHub Actions - GitHub AE Docs
Introduction You only need a GitHub repository to create and run a GitHub Actions workflow. In this guide, you'll add a workflow that demonstrates some of the essential features of GitHub Actions. The following example shows you how GitHub Actions jobs can
docs.github.com
이제 배포를 위한 워크플로우를 작성해보자
아래는 내가 사용할 엑션들의 마켓플레이스 래퍼런스 링크다
Get or create an Oracle Cloud Infrastructure Registry (OCIR) repository - GitHub Marketplace
Create or return the URI and OCID for an existing Oracle Cloud Infrastructure Registry (OCIR) repository
github.com
+ 오라클의 권장 연결방법 OCI CLI 시도
아래는 워크플로를 작성하기위한 변수들의 공식문서 안내링크 이다
참고해서 그때그때 적용해주면 된다.

리전 변수 공식문서
https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/clienvironmentvariables.htm
CLI Environment Variables
The CLI respects and applies configurations specified by option, environment variable, or OCI config file entry in the following order of precedence: The value specified in the command option. The value specified in the environment variable. The value spec
docs.oracle.com

이런식으로 변수들을 대입해주면 푸시가 일어 났을때
자동 배포가 진행될것이다
하지만 실패했다
OCI CLI 를 사용 하면 공식 지원하는 자동화 방법 이다 보니
가장 권장되는 방법일것이라 생각했지만
연결에 필요한 작업이 너무 복잡했다
리전부터 테넌시 등등..
기존의 배포 절차와 비슷하게, 간단하게 접근하기위해 다른 방법을 찾아봤다
그래서 다른 방법을 찾았다
우선 github action 의 ssh 연결에 가장 많이 사용하는
appleboy/ssh-action 이다
https://github.com/marketplace/actions/ssh-remote-commands
SSH Remote Commands - GitHub Marketplace
Executing remote ssh commands
github.com
+ appleboy/ssh-action 시도
- name: multiple command
uses: appleboy/ssh-action@v0.1.8
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
script: |
whoami
ls -al
appleboy/ssh-action 의 연결을 위한 주요 스크립트다
uses의 0.1.8 버전은 현재의 최신 버전이며
직접 사용할때는 마켓플레이리스트에서 최신버전과 동일한지 확인 해야 하고
버전별 바뀐 스크립트 규칙을 확인해야 한다
변수를 바인딩하여 ssh 접속의 기본 정보들을 전달 한다
script: | 후에 명령어는 기존 터미널에서 사용하는 셀 명령어 그대로 입력해서
사용하기 매우 편리하다
빌드된 파일을 전송할때도 ftp를 사용하지않고 put으로 해결할수 있다
나는 ftp 를 이용하거나 파일 복붙이 있을시 pbcopy를 사용하는등등 put 을 사용 해본적이 없었고
나에게 익숙하지않아서 일수도 있지만
더 좋은 액션을 찾기로 했다
더 좋은 액션을 찾을수 있었다
https://github.com/marketplace/actions/ssh-scp-ssh-pipelines
ssh-scp-ssh-pipelines - GitHub Marketplace
Pipelines: ssh -> scp -> ssh
github.com
결과적으로 내가 결정하게된 액션으로
ssh 기반의 파일전송 방법인 scp를 기준으로 그 행위의 앞,뒤에 스크립트를 작성할수있다
빌드파일 전송의 앞뒤로 스크립트를 분리 할수있으니
한눈에 어떤 디랙터리에서 무엇을 하는지 알기 쉽다고 판단 했다
또한 이 액션으로 ssh 연결과 빌드파일전송 문제를 해결했다
가장 큰 해결 사항인 서버 인스턴스에 ssh접속과 파일 이동을 성공 했으니
부수적인 사항을 해결하면 배포 자동화가 마무리 된다
- 기능 구현 하기
프로잭트 리포지터리 접근
Java JDK 설치
gradlew 로 빌드
ssh 접속
빌드파일 전송
필요 권한으로 빌드파일 백그라운드 실행
배포 자동화 성공.
- 작성한 셀스크립트 yml 파일 -
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Create Properties
uses: actions/checkout@v3
- run: touch ./src/main/resources/application-awsMariaDB.properties
- run: echo "${{ secrets.APPLICATION_AWSMARIADB_PROPERTIES }}" > ./src/main/resources/application-awsMariaDB.properties
- run: cat ./src/main/resources/application-awsMariaDB.properties
- name: Setup JDK 17
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'
- name: Build with Gradle
run: |
chmod +x gradlew
./gradlew build
- name: ssh connection
uses: cross-the-world/ssh-scp-ssh-pipelines@latest
with:
host: ${{ secrets.HOST }}
port: ${{ secrets.PORT }}
user: ${{ secrets.USER }}
key: ${{ secrets.KEY }}
scp: |
./build/libs/LFG*-SNAPSHOT.jar => /home/support800/server/
last_ssh: |
cd /home/${{ secrets.USER }}/server/
sudo -S sh -c "nohup java -jar LFG*-SNAPSHOT.jar &" <<< "${{ secrets.PW }}"
- name: Create Properties
uses: actions/checkout@v3
로 내 리포지터리를 사용할수 있도록 함과 동시에
문제점인 propertise 파일을 Repository secrets 변수 바인딩으로
해결해야 한다
gitignore 에 의해 유출되면 안되는,누락된 파일을 생성하는 부분이다
- name: Setup JDK 17
uses: actions/setup-java@v3
로 빌드에 필요한 Java 17 JDK 를 설치한다
- name: Build with Gradle
파일은 일반 사용자가 빌드 할수 있도록 권한설정과 함께
gradlew로 빌드 한다
- name: ssh connection
가장 시간이 많이 소모된 부분으로
uses: cross-the-world/ssh-scp-ssh-pipelines@latest 를 사용해
ssh 접속과 빌드된 파일의 이동, 실행 등을 수행하는
가장 중요한 부분이다
이 액션은 yml을 작성할때 github 마켓플레이스 에서 ssh 검색시 최상단에 추천해주는
액션이다
위의 과정을 구현 하는동안 3가지의 큰 문제점이 있었다
1. 프로잭트파일의 노출되어서는 안되는 환경변수들의 하드코딩을 피하기위한
propertise 파일을 gitignore 설정으로 리포지터리에 포함 시키지 않아
필수 정보들의 누락으로 빌드가 불가능한 상황
러너에서 생성된 파일은 스크립트가 끝나면 누군가에게 보여지거나 하지않기때문에
환경변수 파일을 만들어서 빌드하고 러너가 끝날시 버려지는 방식을 선택 했다
2. ssh 접속에 필요한 정보들을 정상적으로 받아올수 없어
ssh접속에 어려움을 겪었다

Actions의 Repository secrets 를 사용했어야 하는데
Codespaces의 변수를 설정해서 한동안 고생 했다
UI 가 비슷해서 햇갈린것 같다..
수정된 파일의 경우 푸시를 통해서만 러너 실행이 가능 해서
하루에 2,30번 푸시를 하는경우도있었다
스크립트를 작성할때 미리 시도해볼수 있는 환경이었다면
더욱 과감하게 이것저것 시도 할수 있을것이라 생각했다
커밋,푸시 횟수의 기록이 남는다는것은 부담스러웠지만
연연하지않고 다수의 시도 끝에 배포 자동화에 성공 했다
3. 일반 사용자계정으로 tomcat 기본 포트(80)을 정상적으로 실행할수 없다
러너의 스크립트가 일반 사용자로 루트 권한을 이용해 빌드파일을 실행하는 방법으로 해결했다

이번 배포 자동화를 하면서 오린시간이 소요되었다
리눅스 명령어를 오래 사용하면서
자주사용하는 명령어만 사용하다보니
셀스크립트를 작성할때 다소 딜레이가 있었다
이번에 좋은 경험을 했다고 생각한다
계속해서 다양한 셀스크립트를 만들어본다면,
충분히 지금구현한 배포 자동화를 더 개선할수 있을것이라 생각한다
'걸어서 개발 속으로' 카테고리의 다른 글
| 내 서비스에 로그 적용 (1) | 2023.05.06 |
|---|---|
| 로그 남기기 (0) | 2023.05.03 |
| 오라클 인스턴스 생성 기록 (0) | 2023.03.25 |
| LFG서버 배포 (0) | 2023.03.11 |
| ChatGPT 에게 물어본 생성자 VS get/set (0) | 2023.03.02 |
댓글