728x90
서버에서 사용되는 서버 작업 자동화 쉘 스크립트 모음입니다.
start_server.sh
서버 시작을 도와주는 쉘 스크립트로 로그 파일 생성과 PID 관리 기능이 추가되어 있습니다
#!/bin/bash
# 애플리케이션 디렉토리로 이동
cd /root/neonadeuli-backend || { echo "디렉터리를 /root/neonadeuli-backend로 변경하지 못했습니다."; exit 1; }
# Log 디렉토리 설정
LOG_DIR="/root/log"
LOG_FILE="${LOG_DIR}/neonadeuli.log"
mkdir -p "${LOG_DIR}"
echo "Log directory: ${LOG_DIR}"
echo "Log file: ${LOG_FILE}"
# 기존 서버 프로세스 중지
if [ -f /root/log/server_pid.pid ]; then
OLD_PID=$(cat /root/log/server_pid.pid)
if ps -p ${OLD_PID} > /dev/null; then
echo "PID: ${OLD_PID} 가 있는 기존 서버를 중지합니다."
kill ${OLD_PID}
rm /root/log/server_pid.pid
else
echo "PID: ${OLD_PID}로 기존 서버 프로세스를 찾을 수 없습니다..오래된 PID 파일을 제거해주세요."
rm /root/log/server_pid.pid
fi
else
echo "기존 서버 프로세스를 찾을 수 없습니다."
fi
# Uvicorn 서버 시작
nohup uvicorn main:app --host 0.0.0.0 --port 443 \
--ssl-keyfile /etc/letsencrypt/live/neonadeuli.life/privkey.pem \
--ssl-certfile /etc/letsencrypt/live/neonadeuli.life/fullchain.pem \
>> "${LOG_FILE}" 2>&1 &
# 시작된 프로세스 PID 저장
PID=$!
if [ -n "${PID}" ]; then
echo "PID 번호 ${PID}로 서버가 구동되었습니다."
echo "로그는 ${LOG_FILE} 이곳에 작성되었습니다."
# PID를 파일에 저장 (나중에 서버 중지 시 사용 가능)
echo ${PID} > /root/log/server_pid.pid
else
echo "Failed to start the server."
exit 1
fi
stop_server.sh
서버 종료를 도와주는 쉘 스크립트로 PID 관리와 종료 대기, 강제 종료 기능이 추가되어 있습니다.
#!/bin/bash
PID_FILE="/root/log/server_pid.pid"
# PID 파일에서 PID 읽기
if [ -f "$PID_FILE" ]; then
PID=$(cat "$PID_FILE")
else
# Uvicorn 프로세스 찾기
PID=$(pgrep -f "uvicorn main:app")
fi
if [ -z "$PID" ]; then
echo "현재 어떤 유니콘 서버도 동작하고 있지 않습니다."
exit 0
fi
echo "현재 서버를 중지하는 중입니다. PID 번호는 $PID 입니다."
# 일반적인 종료 시도
kill $PID
# 프로세스가 종료될 때까지 대기 (최대 10초)
for i in {1..10}; do
if ! kill -0 $PID 2>/dev/null; then
echo "유비콘 서버가 정상적으로 종료되었습니다."
[ -f "$PID_FILE" ] && rm "$PID_FILE"
exit 0
fi
echo "서버가 종료되기를 기다리는 중입니다. ($i/10)"
sleep 1
done
# 여전히 실행 중이라면 강제 종료
if kill -0 $PID 2>/dev/null; then
echo "서버가 정상적으로 종료되지 않았습니다. 강제 종료를 시도합니다..."
kill -9 $PID
sleep 1
if ! kill -0 $PID 2>/dev/null; then
echo "유비콘 서버가 강제 종료되었습니다."
[ -f "$PID_FILE" ] && rm "$PID_FILE"
else
echo "서버 종료에 실패했습니다. 수동으로 확인해 주세요."
fi
fi
update_and_restart.sh
최신 코드와 라이브러리를 업데이트하고 서버를 재시작하는 쉘 스크립트입니다.
#!/bin/bash
BASE_DIR="/root"
cd ${BASE_DIR}/neonadeuli-backend || { echo "/root/neonadeuli-backend로 디렉토리 변경을 실패했습니다."; exit 1; }
if git pull origin main; then
echo "origin main 브랜치로부터 성공적으로 최신 코드를 pull 받았습니다."
else
echo "최신 코드 pull 받기를 실패했습니다."
exit 1
fi
if pip install -r requirements.txt; then
echo "성공적으로 requirements 설치를 완료했습니다."
else
echo "requirements 설치를 실패했습니다."
exit 1
fi
if ${BASE_DIR}/stop_server.sh; then
echo "성공적으로 server를 중지했습니다."
else
echo "server 중지를 실패했습니다."
exit 1
fi
if ${BASE_DIR}/start_server.sh; then
echo "성공적으로 server를 구동했습니다."
else
echo "server 구동을 실패했습니다."
exit 1
fi
echo "$(date) 시각에 Server를 업데이트하고 재시작을 완료했습니다."
check_server_status.sh
CPU, 메모리 사용량, 최근 로그 15줄을 제공하는 서버 상태 체크 쉘 스크립트입니다.
#!/bin/bash
PID_FILE="/root/log/server_pid.pid"
LOG_FILE="/root/log/neonadeuli.log"
check_server_status() {
PID=$(pgrep -f "uvicorn main:app")
if [ -z "$PID" ]; then
echo "서버가 실행 중이 아닙니다."
else
echo "서버가 실행 중입니다. (PID: $PID)"
echo "CPU 사용량: $(ps -p $PID -o %cpu | tail -1)%"
echo "메모리 사용량: $(ps -p $PID -o %mem | tail -1)%"
echo "최근 로그:"
tail -n 15 "$LOG_FILE"
fi
# PID 파일 확인
if [ -f "$PID_FILE" ]; then
FILE_PID=$(cat "$PID_FILE")
if [ "$FILE_PID" != "$PID" ]; then
echo "경고: PID 파일의 PID ($FILE_PID)가 실제 실행 중인 PID ($PID)와 다릅니다."
fi
else
echo "경고: PID 파일이 존재하지 않습니다."
fi
}
# 함수: 서버 포트 확인
check_server_port() {
if netstat -tuln | grep :443 > /dev/null; then
echo "포트 443이 열려있습니다."
else
echo "포트 443이 닫혀있습니다."
fi
}
# 메인 실행
echo "서버 상태 확인 중..."
check_server_status
echo ""
check_server_port
rotate_logs.sh
로그 파일을 날짜에 따른 생성 및 삭제 관리를 도와주는 쉘 스크립트입니다.
#!/bin/bash
# Log 디렉토리 설정
LOG_DIR="/root/log"
LOG_FILE="${LOG_DIR}/neonadeuli.log"
# 현재 날짜를 이용하여 로그 파일 이름 생성
DATE=$(date +"%Y-%m-%d")
NEW_LOG_FILE="${LOG_DIR}/neonadeuli_${DATE}.log"
# 기존 로그 파일을 새로운 파일로 이동
if [ -f "${LOG_FILE}" ]; then
echo "Rotating log file: ${LOG_FILE} to ${NEW_LOG_FILE}"
mv "${LOG_FILE}" "${NEW_LOG_FILE}"
# 새로운 로그 파일 생성
touch "${LOG_FILE}"
else
echo "Log file not found: ${LOG_FILE}"
fi
# 30일 이상 된 파일 삭제
find ${LOG_DIR} -name "neonadeuli_*.log" -type f -mtime +30 -delete
# 기존 서버 로그와 새로운 로그 파일을 연결
if [ -f /root/log/server_pid.pid ]; then
PID=$(cat /root/log/server_pid.pid)
echo "Sending USR1 signal to PID: ${PID} for log rotation"
kill -USR1 ${PID}
else
echo "Server PID file not found."
fi
더보기
크론탭에 다음과 같이 세팅하여 매일 자정마다 실행되도록 세팅
crontab -l : 예약된 작업리스트
crontab -e : 예약된 작업 수정
crontab -r : 예약된 작업 삭제
crontab -u 사용자명 : 루트관리자는 해당 사용자
crontab 파일을 보거나 삭제, 편집 가능
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h dom mon dow command
0 12 1 * * /user/bin/certbot renew --quiet
# 매일 자정에 로그 회전
0 0 * * * /root/rotate_logs.sh && /root/start_server.sh
# 서버 시작 (필요 시 주석 제거하여 사용, 최초 1회만 실행 필요
@reboot /root/start_server.sh
analyze_logs.sh
가장 최근 로그 파일 탐색 및 에러 분석하는 쉘 스크립트입니다.
#!/bin/bash
LOG_FILE="/root/log"
# 가장 최신의 로그 파일 찾기
LATEST_LOG=$(ls -t ${LOG_FILE}/neonadeuli_*.log | head -n1)
if [ -z "${LATEST_LOG}" ]; then
echo "${LOG_FILE} 이라는 로그 파일이 존재하지 않습니다."
exit 1
fi
echo "${LATEST_LOG} 이라는 로그 파일 분석 중"
echo "Error count in the last hour:"
grep "ERROR" ${LATEST_LOG} | grep -c "$(date -d '1 hour ago' +'%Y-%m-%d %H:')"
echo "Most frequent IP addresses:"
awk '{print $1}' ${LATEST_LOG} | sort | uniq -c | sort -nr | head -5
echo "Recent 404 errors:"
grep "404" ${LATEST_LOG} | tail -5
monitor_resource.sh
서버 CPU, 메모리, 디스크 사용량 분석 쉘 스크립트입니다.
#!/bin/bash
while true; do
echo "-----$(date)-----"
echo "CPU Usage: $(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4}')%"
echo "Memory Usage: $(free -m | awk 'NR==2{printf "%.2f%%", $3*100/$2 }')"
echo "Disk Usage: $(df -h | awk '$NF=="/"{printf "%s", $5}')"
sleep 60
done
security_check.sh
실패한 로그인 시도 기록과 열린 포트, 최근 시스템 업데이트 기록을 확인하는 쉘 스크립트입니다.
#!/bin/bash
echo "Checking for failed login attempts:"
grep "Failed password" /var/log/auth.log | tail -5
echo "Checking for open ports:"
netstat -tuln
echo "Checking for recent system updates:"
apt list --upgradable
backup_server.sh
백업 파일을 생성하는 쉘 스크립트입니다.
#!/bin/bash
BACKUP_DIR="/root/backups"
APP_DIR="/root/neonadeuli-backend"
DATE=$(date +"%Y%m%d_%H%M%S")
mkdir -p $BACKUP_DIR
tar -czf $BACKUP_DIR/app_backup_$DATE.tar.gz $APP_DIR
echo "Backup created: $BACKUP_DIR/app_backup_$DATE.tar.gz"