- NodeJS 기반으로 mysvc라는 이름의 서비스를 하나 구축한다.
- 운영체제는 Linux, 웹서버는 Nginx, 저장소는 Git을 사용한다.
STG 환경
-
소스코드가 이미 있다고 가정하고 stg 디렉토리로 코드 pull
mkdir -p ~/stg cd ~/stg git checkout ssh://mysvc@localhost:~/mysvc.git -
STG 구동을 위한 서비스 등록
####/bin/sh NODE_ENV="development" PORT="3000" APP_DIR="~mysvc/stg" NODE_APP="server.js" CONFIG_DIR="$APP_DIR" PID_FILE="/var/run/mysvc_stg.pid" LOG_DIR="/var/log/mysvc" LOG_FILE="$LOG_DIR/stg.log" NODE_EXEC=$(which node) ############### - REDHAT chkconfig header - chkconfig: - 58 74 - description: node-app is the script for starting a node app on boot. ## BEGIN INIT INFO - Provides: node - Required-Start: $network $remote_fs $local_fs - Required-Stop: $network $remote_fs $local_fs - Default-Start: 2 3 4 5 - Default-Stop: 0 1 6 - Short-Description: start and stop node - Description: Node process for app ## END INIT INFO ############### USAGE="Usage: $0 {start|stop|restart|status} [--force]" FORCE_OP=true pid_file_exists() { [ -f "$PID_FILE" ] } get_pid() { echo "$(cat "$PID_FILE")" } is_running() { PID=$(get_pid) ### [ -z "$(ps aux | awk '{print $2}' | grep "^$PID$")" ] } start_it() { mkdir -p "$LOG_DIR" echo "Starting node app ..." PORT="$PORT" NODE_ENV="$NODE_ENV" NODE_CONFIG_DIR="$CONFIG_DIR" $NODE_EXEC "$APP_DIR/$NODE_APP" 1>"$LOG_FILE" 2>&1 & echo $### > "$PID_FILE" echo "Node app started with pid $###" } stop_process() { PID=$(get_pid) echo "Killing process $PID" kill $PID } remove_pid_file() { echo "Removing pid file" rm -f "$PID_FILE" } start_app() { if pid_file_exists then if is_running then PID=$(get_pid) echo "Node app already running with pid $PID" exit 1 else echo "Node app stopped, but pid file exists" if [ $FORCE_OP = true ] then echo "Forcing start anyways" remove_pid_file start_it fi fi else start_it fi } stop_app() { if pid_file_exists then if is_running then echo "Stopping node app ..." stop_process remove_pid_file echo "Node app stopped" else echo "Node app already stopped, but pid file exists" if [ $FORCE_OP = true ] then echo "Forcing stop anyways ..." remove_pid_file echo "Node app stopped" else exit 1 fi fi else echo "Node app already stopped, pid file does not exist" exit 1 fi } status_app() { if pid_file_exists then if is_running then PID=$(get_pid) echo "Node app running with pid $PID" else echo "Node app stopped, but pid file exists" fi else echo "Node app stopped" fi } case "$2" in --force) FORCE_OP=true ;; "") ;; *) echo $USAGE exit 1 ;; esac case "$1" in start) start_app ;; stop) stop_app ;; restart) stop_app start_app ;; status) status_app ;; *) echo $USAGE exit 1 ;; esac
PRD 환경
-
prd 디렉토리 생성 및 stg 환경 복사
mkdir -p ~/prd cd ~/prd git clone ssh://mysvc@localhost:~/stg -
서비스 스크립트 /etc/init.d/prd 작성
####/bin/sh NODE_ENV="production" PORT="5000" APP_DIR="~mysvc/prd" NODE_APP="server.js" CONFIG_DIR="$APP_DIR" PID_FILE="/var/run/mysvc_prd.pid" LOG_DIR="/var/log/mysvc" LOG_FILE="$LOG_DIR/prd.log" NODE_EXEC=$(which node) ############### 1. REDHAT chkconfig header 1. chkconfig: - 58 74 1. description: node-app is the script for starting a node app on boot. ## BEGIN INIT INFO 1. Provides: node 1. Required-Start: $network $remote_fs $local_fs 1. Required-Stop: $network $remote_fs $local_fs 1. Default-Start: 2 3 4 5 1. Default-Stop: 0 1 6 1. Short-Description: start and stop node 1. Description: Node process for app ## END INIT INFO ############### USAGE="Usage: $0 {start|stop|restart|status} [--force]" FORCE_OP=true pid_file_exists() { [ -f "$PID_FILE" ] } get_pid() { echo "$(cat "$PID_FILE")" } is_running() { PID=$(get_pid) ### [ -z "$(ps aux | awk '{print $2}' | grep "^$PID$")" ] } start_it() { mkdir -p "$LOG_DIR" echo "Starting node app ..." PORT="$PORT" NODE_ENV="$NODE_ENV" NODE_CONFIG_DIR="$CONFIG_DIR" $NODE_EXEC "$APP_DIR/$NODE_APP" 1>"$LOG_FILE" 2>&1 & echo $### > "$PID_FILE" echo "Node app started with pid $###" } stop_process() { PID=$(get_pid) echo "Killing process $PID" kill $PID } remove_pid_file() { echo "Removing pid file" rm -f "$PID_FILE" } start_app() { if pid_file_exists then if is_running then PID=$(get_pid) echo "Node app already running with pid $PID" exit 1 else echo "Node app stopped, but pid file exists" if [ $FORCE_OP = true ] then echo "Forcing start anyways" remove_pid_file start_it fi fi else start_it fi } stop_app() { if pid_file_exists then if is_running then echo "Stopping node app ..." stop_process remove_pid_file echo "Node app stopped" else echo "Node app already stopped, but pid file exists" if [ $FORCE_OP = true ] then echo "Forcing stop anyways ..." remove_pid_file echo "Node app stopped" else exit 1 fi fi else echo "Node app already stopped, pid file does not exist" exit 1 fi } status_app() { if pid_file_exists then if is_running then PID=$(get_pid) echo "Node app running with pid $PID" else echo "Node app stopped, but pid file exists" fi else echo "Node app stopped" fi } case "$2" in --force) FORCE_OP=true ;; "") ;; *) echo $USAGE exit 1 ;; esac case "$1" in start) start_app ;; stop) stop_app ;; restart) stop_app start_app ;; status) status_app ;; *) echo $USAGE exit 1 ;; esac -
stg의 코드를 prd로 merge하고 배포하기 위한 스크립트 작성
####/bin/sh cd ~/prd git pull localhost:~/stg npm install service prd restart
Nginx 설정
-
stg, prd에 대한 reverse proxy 설정
server { ... location / { } location /mysvc { proxy_pass http://localhost:5000/mysvc; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; } location /mysvc_stg { proxy_pass http://localhost:3000/mysvc_stg; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; } ... } -
서비스 재구동
sudo service stg restart sudo service prd restart