배경
슬랙봇을 서버에서 항상 돌리고 싶었다. 원래는 도커파일 작성해서 올리려고 했는데 마감이 코앞이라 거기까진 못할 것 같고 이번엔 rsync 접속을 사용해보기로 했다. 그리고 rsync 접속은 안 해본 거기도 하니까.
Naver Cloud, Git Action(Appleboy, butnett01 사용)
Naver Cloud 서버 만들기
서버부터 생성해준다.
인증키가 없으면 '새로운 인증키 생성'으로 하면 된다.
포트 포워딩 설정을 해준다.
사용할 포트 번호를 입력하고 여기서 서버 접속용 공인 IP를 기록해둔다. 사용해야 하니까.
추가버튼 누르고 밑에 적용까지 눌러야 한다.
서버 관리 및 설정 변경에서 관리자 비밀번호 탭에 들어가서 아까 인증키를 넣으면 비밀번호가 나온다.
이 비밀번호도 기록해둔다. 로그인해야 한다.
Xshell이나 putty를 사용하여 서버에 접속한다.
user 생성
sudo adduser <user_name>
adduser 명령 시 password 설정이 뜨는데 이때 password는 필수적으로 입력해준다. 나중에 에러가 생길 수도 있다.
login <user_name>
만든 user_name으로 로그인해주고
mkdir <directory_name>
나중에 코드를 저장할 디렉토리를 하나 생성해준다.
Git Action 설정하기
Github Repository > Settings > Secrets > Actions에서 Repository secrets 생성
HOST > 내 서버 주소 또는 공인 IP
USER > 서버에서 로그인할 user name
PASSWORD > user의 비밀번호
PORT > 서버에 접속할 때 사용할 포트 번호
Git Action 작성
ssh 접속을 위해서 appleboy/ssh-action을 사용할 것이다.
https://github.com/appleboy/ssh-action
Deploy.yml 작성
name: Deploy to Naver Cloud
on:
push:
branches: # 현재 사용중인 브랜치에 push 들어오면(테스트용이라서 이렇게 해둠)
- feat/88
jobs:
Deploy:
name: Deploy
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- name: checkout
uses: actions/checkout@main
# 필요한 파일 생성
- name: create token
run: |
npm ci
echo "${{ secrets.TOKEN }}" > ./token
ls -al
# 서버에 로그인
- name: check login to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
password: ${{ secrets.PASSWORD }}
port: ${{ secrets.PORT }}
script: |
echo "login success"
나는 토큰 파일이 필요해서 만들어주었다.
Secret에 등록한 키들을 ${{ secrets.XX }}의 변수로 사용할 수 있다.
접속 성공
rsync 접속
rsync 접속은 burnett01을 사용한다.
https://github.com/Burnett01/rsync-deployments
ssh-key 생성
rsync 접속은 ssh 키가 필요하다. 없는 경우, 서버에 접속해서 ssh key를 생성해주자.
ssh-keygen
생성 완료. ssh-keygen 명령 후 엔터로 모두 넘겨주었다.
.ssh 디렉토리 생성된 것 확인
.ssh 디렉토리로 들어가서 id_rsa, id_rsa.pub 파일 생긴 것 확인.
key 생성 완료 후 id_rsa 내부에 있는 비밀키를 git secret에 등록한다. 이 비밀키는 절대 공개되어선 안 된다.
-----BEGIN RSA PRIVATE KEY-----
KEY
-----END RSA PRIVATE KEY-----
전부 등록
Deploy.yml 작성
name: Deploy to Naver Cloud
on:
push:
branches:
- feat/88
jobs:
Deploy:
name: Deploy
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- name: checkout
uses: actions/checkout@main
- name: create token
run: |
npm ci
echo "${{ secrets.TOKEN }}" > ./token
ls -al
- name: check login to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
password: ${{ secrets.PASSWORD }}
port: ${{ secrets.PORT }}
script: |
echo "login success"
- name: copy source via ssh key
uses: burnett01/rsync-deployments@4.1
with:
switches: -avzr --delete
remote_path: /home/slack/server/ #코드가 들어갈 path
remote_host: ${{ secrets.HOST }} # 서버 주소
remote_user: ${{ secrets.USER }} # 서버 유저이름
remote_key: ${{ secrets.KEY }} # RSA 키
remote_port: ${{ secrets.PORT }} # 접속 포트
remote_path에 아까 만들었던 디렉토리 위치를 저장한다.
혹시나 접속할 때 root계정으로 접속하거나 root디렉토리를 path로 지정하는 일은 없길 바란다.
왜냐면 내가 어제 그렇게 하고 내 6시간을 없었던 것으로 만들어버렸기 때문..ㅎ
서버에 아래 설정을 등록해준다. 필! 수!
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
이렇게 하고 action을 작동시키면 또로롱
서버에 접속해서 확인해보면 코드가 copy 되었다. action에서 생성해준 token 파일도 함께 들어간 것까지 확인.
행복하다,,^^
npm 실행
나는 여기서 npm을 실행시키는 것까지가 할 일이다.
서버에 nodejs 설치가 안 되었을 경우 nodejs부터 설치해야 한다.
2022.12.10 - [인프라] - [Ubuntu] Ubuntu에 npm 설치
Action을 수정해서 npm 실행까지 스크립트로 만든다.
name: Deploy to Naver Cloud
# main에 PR시 액션 시작
on:
pull_request:
branches:
- main
jobs:
Deploy:
name: Deploy
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- name: checkout
uses: actions/checkout@v2
# workflow에 token 생성
- name: create token
run: |
npm ci
echo "${{ secrets.TOKEN }}" > ./token
ls -al
# server에 접속하여 실행중인 node 프로세스 삭제
- name: login to server and stop bot
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
password: ${{ secrets.PASSWORD }}
port: ${{ secrets.PORT }}
script: |
echo "login success"
pkill -9 -ef node
# 서버 /slack/server/위치에 workflow 전체 카피
- name: copy source
uses: burnett01/rsync-deployments@4.1
with:
switches: -avzr --delete
remote_path: /home/slack/server/
remote_host: ${{ secrets.HOST }}
remote_user: ${{ secrets.USER }}
remote_key: ${{ secrets.KEY }}
remote_port: ${{ secrets.PORT }}
# 서버에서 npm start하고 액션 종료
- name: execute slack-bot
uses: appleboy/ssh-action@master
env:
RUNNER_TRACKING_ID: ""
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
password: ${{ secrets.PASSWORD }}
port: ${{ secrets.PORT }}
script: |
cd server
npm install
nohup npm start >> nohup.out 2>&1 &
후기
이번 프로젝트에서 역대급이었다. 트러블 슈팅했을 때의 짜릿함이란..😊
이것 말고도 서버(우분투)랑 로컬의 파이썬 버전, 노드 버전 차이 같은 문제들도 있었는데 그거는 너무 정신없어서 사진을 하나도 못 찍었다.
그래서 아쉽게도 올리지 못한다ㅠㅠ
참고
https://abc2080.tistory.com/entry/ssh-%EB%93%B1%EB%A1%9D
https://juneyoung.io/devops-deploy-gatsby-digital-ocean-droplet-with-actions-220427
https://bakyeono.net/post/2015-05-05-linux-kill-process-by-name.html