들어가며
어제 막 블로그 아키텍처를 한 차례 업데이트했는데, 오늘 아침에 일어나 보니 서버가 만료되면서 사이트가 완전히 다운되어 있었다. 만료 알림 메일조차 오지 않았다.
원래는 만료되면 더 이상 연장하지 않을 계획이었는데, 막상 만료된 뒤에는 서버에 연결조차 할 수 없어 데이터를 꺼낼 방법이 없었다. 다행히 평소에 백업 습관이 잘 잡혀 있어 정기적으로 데이터를 OneDrive에 백업해 두었다. 자세한 내용은 이 글을 참고하면 된다.
그런데 곤란하게도 데이터만 백업했을 뿐 배포 환경 변수는 백업해 두지 않았다. 그 때문에 몇 가지 문제가 생겼는데, 기록해 둘 만한 가치가 있다고 생각한다.
백엔드 배포
이전 배포 글과 동일하다. 유일하게 주의할 점이자 이번 배포에서 문제를 일으켰던 부분은 .env 파일 작성이다. ALLOWED_ORIGINS에는 도메인만 적으면 된다. https://xxu.do처럼 적으면 안 된다.
JWT_SECRET=XXXXXX #随便填写,长度在 16-32 之间
ALLOWED_ORIGINS=xxu.do #这里需要注意的是,仅填写域名即可,不要填写 https://xxu.do,这会导致前端无法连接
ENCRYPT_ENABLE=false
ENCRYPT_KEY=
프론트엔드 배포
이번 배포 방식은 GitHub Action으로 Shiroi를 빌드한 다음 원격 서버에 배포하는 방법이다. 주로 이 글을 참고했다.
먼저 서버에서 다음 작업을 수행한다.
Nodejs와unzip설치
# 安装 unzip
sudo apt update && sudo apt install -y unzip
# 安装 NVM (Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# 重新进行 SSH 连接或者 source .bashrc 来生效
nvm install node
node -v
npm -v
Node.js,npm,pnpm,pm2,sharp설치
npm i -g sharp pm2 pnpm
- 서버의 홈 디렉터리에
shiro디렉터리를 만든 다음,.env를 새로 만들어 환경 변수를 입력한다.
cd && mkdir shiro && cd $_
vi .env
- 그다음 해당 환경 변수를 입력한다. 단일 도메인이라면
NEXT_PUBLIC_API_URL과NEXT_PUBLIC_GATEWAY_URL을 아래처럼 적으면 된다.GH_TOKEN은 여기에서 새로 발급할 수 있으며, 권한은 repo만 체크하면 된다.
NEXT_PUBLIC_API_URL=http://localhost:2333
NEXT_PUBLIC_GATEWAY_URL=http://localhost:2333
TMDB_API_KEY=
GH_TOKEN=
- 프로젝트를 Fork한 뒤
Settings -> Secrets and variables -> Actions -> Repository secrets에 다음 내용을 추가한다.
HOST서버 주소USER서버 사용자 이름PASSWORD서버 비밀번호PORT서버 SSH 포트KEY서버 SSH Key(선택, 비밀번호와 key 중 하나만)GH_PATShiroi 저장소에 접근할 수 있는 Github Token
여기서 GHPAT은 위의 `GHTOKEN`과 동일하게 설정해도 된다.
Fork한 저장소의 Action에서 workflow를 활성화한다. build_hash 파일을 아무렇게나 수정하면 workflow가 실행된다. 실행에 성공했다면 서버의
/root/shiro폴더에 빌드된 파일이 있는지 확인하면 된다. 처음에는 실행에 실패했는데, 나중에 원인을 확인해 보니 pm2가 배포되어 있지 않았기 때문이었다. 참고로 남겨 둔다.Action 주기 실행: Github에 Fork한 프로젝트에 들어가
.github/workflows/deploy.yml파일을 수정해서schedule:과-corn: '0 3 * * *'두 줄의 주석을 해제하면 된다.
Nginx 리버스 프록시
단일 도메인 기준 예시:
## xxu.do
server {
listen 80;
server_name xxu.do;
rewrite ^(.*)$ https://$host$1 permanent;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name xxu.do; # 替换为你的域名
index index.html;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
ssl_certificate /etc/pki/xxu.do/server.crt;
ssl_certificate_key /etc/pki/xxu.do/server.key;
ssl_stapling on;
ssl_session_timeout 1d;
ssl_protocols TLSv1.2 TLSv1.3;
location /socket.io {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_buffering off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:2333/socket.io;
}
## API 地址
location /api/v2 {
proxy_pass http://127.0.0.1:2333/api/v2;
}
## 简读 render 地址
location /render {
proxy_pass http://127.0.0.1:2333/render;
}
## Kami 地址
location / {
proxy_pass http://127.0.0.1:2323;
}
## 后台地址
location /proxy {
proxy_pass http://127.0.0.1:2333/proxy;
}
location /qaqdmin {
proxy_pass http://127.0.0.1:2333/proxy/qaqdmin;
}
## RSS 地址
location ~* \/(feed|sitemap|atom.xml) {
proxy_pass http://127.0.0.1:2333/$1;
}
}
마무리
이번에 프론트엔드 배포 방식을 새로 도입하면서 메모리 점유율이 과도하게 높던 문제를 확실히 해결할 수 있었다.
또한 한 가지 교훈을 얻었다. .env 파일은 반드시 잘 백업해 두자. 재배포할 때 그렇게 하면 많은 번거로움을 피할 수 있다.