๊ฐ๋ฐ ๋ฐ ์ด์ ์ค ๋ฐ์ํ ์ ์๋ ๋ชจ๋ ๋ฌธ์ ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํ ์์ ๊ฐ์ด๋
- ๐ ๋ฐฐํฌ ๊ด๋ จ ๋ฌธ์
- ๐๏ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ๋ฌธ์
- ๐ง ๊ฐ๋ฐ ํ๊ฒฝ ๋ฌธ์
- โ๏ธ PM2 ๊ด๋ จ ๋ฌธ์
- ๐ ๋คํธ์ํฌ ๋ฐ ์ ์ ๋ฌธ์
- ๐ค GitHub Actions ๋ฌธ์
- ๐พ ๋ฉ๋ชจ๋ฆฌ ๋ฐ ์ฑ๋ฅ ๋ฌธ์
- ๐ ์ธ์ฆ ๋ฐ ๋ณด์ ๋ฌธ์
- ๐ ๋ชจ๋ํฐ๋ง ๋ฐ ๋ก๊ทธ
- ๐ ์๊ธ ๋ณต๊ตฌ ์ ์ฐจ
- GitHub Actions ์ํฌํ๋ก์ฐ๊ฐ ์คํจํจ
- "SSH connection failed" ์๋ฌ
- "Permission denied" ์๋ฌ
1. GitHub Secrets ํ์ธ
# GitHub ๋ ํฌ์งํ ๋ฆฌ์์ ํ์ธ
Settings โ Secrets and variables โ Actions
# ํ์ํ Secrets:
EC2_KEY # SSH ํค ํ์ผ ์ ์ฒด ๋ด์ฉ
EC2_HOST # 15.164.176.168
EC2_USER # ec2-user2. SSH ํค ํ์ ํ์ธ
# ์ฌ๋ฐ๋ฅธ ํ์:
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA...
(ํค ๋ด์ฉ)
...
-----END RSA PRIVATE KEY-----
# ์๋ชป๋ ํ์:
- ๊ณต๋ฐฑ์ด๋ ์ค๋ฐ๊ฟ ๋๋ฝ
- ํค๋/ํธํฐ ๋๋ฝ
- ๋ค๋ฅธ ํค ํ์ (OpenSSH ๋ฑ)3. EC2 ๋ณด์๊ทธ๋ฃน ํ์ธ
# SSH ํฌํธ 22๋ฒ ์ด๋ ค์๋์ง ํ์ธ
Source: 0.0.0.0/0 (๋ชจ๋ IP ํ์ฉ)
๋๋ GitHub Actions IP ๋์ญ- SSH ํค ์ ๊ธฐ์ ๊ฐฑ์
- GitHub Secrets ๋ฐฑ์
- ๋ฐฐํฌ ์คํฌ๋ฆฝํธ ํ ์คํธ
- git pull ์คํจ
- npm install ์ค๋ฅ
- pm2 restart ์คํจ
1. Git ๊ด๋ จ ์ค๋ฅ
# ๋ก์ปฌ ๋ณ๊ฒฝ์ฌํญ ์ถฉ๋
git stash
git pull origin main
git stash pop
# ๊ฐ์ ์
๋ฐ์ดํธ (์ฃผ์!)
git fetch origin
git reset --hard origin/main2. ๊ถํ ๋ฌธ์
# ํ์ผ ๊ถํ ํ์ธ
ls -la /home/ec2-user/on-air-mate
# ๊ถํ ์์
sudo chown -R ec2-user:ec2-user /home/ec2-user/on-air-mate
chmod -R 755 /home/ec2-user/on-air-mate3. ๋์คํฌ ๊ณต๊ฐ ๋ถ์กฑ
# ๋์คํฌ ์ฌ์ฉ๋ ํ์ธ
df -h
# ๋ถํ์ํ ํ์ผ ์ ๋ฆฌ
sudo yum autoremove # Amazon Linux
# ๋ก๊ทธ ํ์ผ ์ ๋ฆฌ
pm2 flush
sudo journalctl --vacuum-time=7dError: connect ETIMEDOUTError: Access denied for userError: Unknown database 'onairmate'
1. ์ฐ๊ฒฐ ์ ๋ณด ํ์ธ
# ํ๊ฒฝ๋ณ์ ํ์ธ
grep -E "(DATABASE_URL|DB_)" .env
# ์ฌ๋ฐ๋ฅธ ํ์:
DATABASE_URL="mysql://admin:on-air-mate@onairmate-db-seoul.cviw844m2ex4.ap-northeast-2.rds.amazonaws.com:3306/onairmate"2. ๋คํธ์ํฌ ์ฐ๊ฒฐ ํ ์คํธ
# RDS ์ฐ๊ฒฐ ํ
์คํธ
telnet onairmate-db-seoul.cviw844m2ex4.ap-northeast-2.rds.amazonaws.com 3306
# DNS ํ์ธ
nslookup onairmate-db-seoul.cviw844m2ex4.ap-northeast-2.rds.amazonaws.com3. RDS ๋ณด์๊ทธ๋ฃน ํ์ธ
# AWS Console์์ ํ์ธ:
# RDS โ onairmate-db-seoul โ Connectivity & security โ Security groups
# Inbound rules: MySQL/Aurora (3306)
# Source: EC2 ๋ณด์๊ทธ๋ฃน ๋๋ EC2 private IP4. Prisma ์ฐ๊ฒฐ ํ ์คํธ
# Prisma ์ฐ๊ฒฐ ํ์ธ
npx prisma db pull
# ์คํค๋ง ๋๊ธฐํ
npx prisma generate- Migration failed
- Schema drift detected
- Connection pool timeout
1. ๋ง์ด๊ทธ๋ ์ด์ ์ํ ํ์ธ
# ๋ง์ด๊ทธ๋ ์ด์
ํ์คํ ๋ฆฌ ํ์ธ
npx prisma migrate status
# ์คํจํ ๋ง์ด๊ทธ๋ ์ด์
ํ์ธ
npx prisma migrate resolve --rolled-back migration_name2. ์คํค๋ง ๋ฆฌ์ (๊ฐ๋ฐํ๊ฒฝ๋ง)
# โ ๏ธ ์ฃผ์: ๋ชจ๋ ๋ฐ์ดํฐ ์ญ์ ๋จ
npx prisma migrate reset
# ์๋ก ๋ง์ด๊ทธ๋ ์ด์
npx prisma migrate dev --name init3. ์๋ ๋ง์ด๊ทธ๋ ์ด์
# SQL ์ง์ ์คํ
npx prisma db execute --file ./migration.sql
# ๋๋ MySQL ํด๋ผ์ด์ธํธ๋ก ์ ์
mysql -h onairmate-db-seoul.cviw844m2ex4.ap-northeast-2.rds.amazonaws.com -u admin -p onairmatenpm ERR! peer dep missingnpm ERR! code EACCESnpm ERR! network timeout
1. npm ์บ์ ์ ๋ฆฌ
# npm ์บ์ ํ์ธ
npm cache verify
# ์บ์ ์ ๋ฆฌ
npm cache clean --force
# node_modules ์์ ์ฌ์ค์น
rm -rf node_modules package-lock.json
npm install2. ๊ถํ ๋ฌธ์
# npm ๊ถํ ์ค์ (๊ธ๋ก๋ฒ)
sudo chown -R $(whoami) ~/.npm
# ๋๋ nvm ์ฌ์ฉ ๊ถ์ฅ
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
nvm install 20
nvm use 203. ๋คํธ์ํฌ ๋ฌธ์
# npm ๋ ์ง์คํธ๋ฆฌ ํ์ธ
npm config get registry
# ๋ ์ง์คํธ๋ฆฌ ๋ณ๊ฒฝ (๊ตญ๋ด)
npm config set registry https://registry.npmjs.org/
# ํ์์์ ์ฆ๊ฐ
npm config set timeout 60000error TS2307: Cannot find moduleerror TS2345: Argument of type is not assignableerror TS2532: Object is possibly 'undefined'
1. ํ์ ์ ์ ํ์ธ
# ํ์
์ ์ ์ค์น
npm install --save-dev @types/node @types/express
# tsconfig.json ํ์ธ
cat tsconfig.json2. ๋ชจ๋ ํด๊ฒฐ ๋ฌธ์
// tsconfig.json ์์
{
"compilerOptions": {
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true
}
}3. ํ์ ์ฒดํฌ ๋ฌด์ (์์)
// ์์ ํด๊ฒฐ์ฑ
(๊ถ์ฅํ์ง ์์)
// @ts-ignore
const result = problematicCode();
// ๋ ๋์ ๋ฐฉ๋ฒ
const result = problematicCode() as any;PM2: Process failed to startPM2: Application has thrown an uncaught exceptionPM2: EADDRINUSE: address already in use :::3000
1. ํฌํธ ์ถฉ๋ ํ์ธ
# ํฌํธ ์ฌ์ฉ ํ์ธ
sudo ss -tulpn | grep :3000
sudo lsof -i :3000
# ํ๋ก์ธ์ค ์ข
๋ฃ
sudo kill -9 PID_NUMBER
# ๋๋ ํฌํธ ๋ณ๊ฒฝ
export PORT=30012. PM2 ์์ ์ด๊ธฐํ
# ๋ชจ๋ PM2 ํ๋ก์ธ์ค ์ ์ง
pm2 stop all
pm2 delete all
pm2 kill
# PM2 ์ฌ์์
pm2 start npm --name "onairmate-api" -- run start
pm2 save3. PM2 ์ค์ ํ์ผ ์ฌ์ฉ
// ecosystem.config.js ์์ฑ
module.exports = {
apps: [{
name: 'onairmate-api',
script: 'npm',
args: 'start',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production',
PORT: 3000
}
}]
};# ์ค์ ํ์ผ๋ก ์์
pm2 start ecosystem.config.js- ์๋ฒ ์ฌ๋ถํ ํ ์ ํ๋ฆฌ์ผ์ด์ ์ด ์์๋์ง ์์
pm2 startup์คํจ
1. Startup ์คํฌ๋ฆฝํธ ์ฌ์ค์
# ๊ธฐ์กด startup ์ ๊ฑฐ
pm2 unstartup
# ์๋ก ์ค์
pm2 startup
# ์ถ๋ ฅ๋ ๋ช
๋ น์ด ์คํ (sudo ๊ถํ ํ์)
# ํ์ฌ ํ๋ก์ธ์ค ์ ์ฅ
pm2 save2. ์์คํ ์๋น์ค ํ์ธ
# ์๋น์ค ์ํ ํ์ธ
sudo systemctl status pm2-ec2-user
# ์๋น์ค ์ฌ์์
sudo systemctl restart pm2-ec2-user
# ๋ถํ
์ ์๋ ์์ ํ์ฑํ
sudo systemctl enable pm2-ec2-user3. ์๋ ํ ์คํธ
# ์๋ฒ ์ฌ๋ถํ
sudo reboot
# ์ฌ์ ์ ํ ํ์ธ
ssh -i your-key.pem ec2-user@15.164.176.168
pm2 statuscurl: (7) Failed to connect to 15.164.176.168 port 3000: Connection refusedThis site can't be reached
1. ์๋ฒ ์ํ ํ์ธ
# PM2 ์ํ ํ์ธ
pm2 status
# ํฌํธ ๋ฐ์ธ๋ฉ ํ์ธ
sudo ss -tulpn | grep :3000
# ๋ก์ปฌ ์ ์ ํ
์คํธ
curl http://localhost:3000/health2. ๋ณด์๊ทธ๋ฃน ์ค์ ํ์ธ
# AWS Console โ EC2 โ Security Groups
# onairmate-sg ๊ท์น ํ์ธ:
Inbound Rules:
Type: Custom TCP
Port: 3000
Source: 0.0.0.0/0
Type: SSH
Port: 22
Source: 0.0.0.0/0 (๋๋ ํน์ IP)3. ๋ฐฉํ๋ฒฝ ํ์ธ (Amazon Linux)
# iptables ํ์ธ
sudo iptables -L
# ๋ฐฉํ๋ฒฝ ๋นํ์ฑํ (์์)
sudo systemctl stop iptables
# ์๊ตฌ ๋นํ์ฑํ (๊ฐ๋ฐํ๊ฒฝ๋ง)
sudo systemctl disable iptablesAccess to fetch at 'http://15.164.176.168:3000/api/users'
from origin 'http://localhost:3000' has been blocked by CORS policy
1. CORS ์ค์ ํ์ธ
// src/app.ts์์ CORS ์ค์ ํ์ธ
const corsOptions = {
origin: [
'http://localhost:3000',
'http://localhost:3001',
'https://your-frontend-domain.com',
'https://onairmate.vercel.app'
],
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization']
};
app.use(cors(corsOptions));2. ๊ฐ๋ฐํ๊ฒฝ์์ ์์ ํด๊ฒฐ
// ๋ชจ๋ origin ํ์ฉ (๊ฐ๋ฐ์ฉ๋ง)
app.use(cors({
origin: true,
credentials: true
}));Error: Permission denied (publickey)Host key verification failed
1. SSH ํค ์ฌํ์ธ
# ๋ก์ปฌ์์ SSH ํค ํ์ธ
cat ~/.ssh/your-key.pem
# GitHub Secrets์ EC2_KEY์ ์์ ํ ๋์ผํ์ง ํ์ธ
# ๊ณต๋ฐฑ, ์ค๋ฐ๊ฟ, ํค๋/ํธํฐ ๋ชจ๋ ํฌํจ2. SSH ํธ์คํธ ํค ๋ฌธ์
# .github/workflows/deploy.yaml ์์
- name: Deploy to EC2
run: |
echo "${{ secrets.EC2_KEY }}" > private_key
chmod 600 private_key
ssh-keyscan -H ${{ secrets.EC2_HOST }} >> ~/.ssh/known_hosts
ssh -o StrictHostKeyChecking=no -i private_key ${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} '
cd /home/ec2-user/on-air-mate &&
git pull origin main &&
npm ci &&
npm run build &&
pm2 restart onairmate-api
'npm ERR! code ELIFECYCLEnpm ERR! errno 1ESLint errors found
1. ๋ก์ปฌ์์ ๋ฏธ๋ฆฌ ํ ์คํธ
# ๋ก์ปฌ์์ ๋น๋ ํ์ธ
npm run format
npm run build
# ์๋ฌ ์์ ํ ์ปค๋ฐ
git add .
git commit -m "[fix] ESLint ์๋ฌ ์์ "
git push origin main2. ๋น๋ ์๋ฌ ๋ฌด์ (์์)
# .github/workflows/deploy.yaml
- name: Run ESLint
run: npm run lint
continue-on-error: true # ์์๋ก ์๋ฌ ๋ฌด์PM2: Process failed due to memory limitJavaScript heap out of memory
1. ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ํ์ธ
# ์์คํ
๋ฉ๋ชจ๋ฆฌ ํ์ธ
free -h
# PM2 ํ๋ก์ธ์ค๋ณ ๋ฉ๋ชจ๋ฆฌ
pm2 monit
# ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ ์์ธ
ps aux --sort=-%mem | head2. ์ค์ ํ์ผ ์ค์
# 1GB ์ค์ ์์ฑ
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
# ์๊ตฌ ์ ์ฉ
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab3. PM2 ๋ฉ๋ชจ๋ฆฌ ์ ํ ์ค์
// ecosystem.config.js
module.exports = {
apps: [{
name: 'onairmate-api',
script: 'npm',
args: 'start',
max_memory_restart: '500M', // 500MB ์ด๊ณผ์ ์ฌ์์
node_args: '--max-old-space-size=512' // Node.js ํ ํฌ๊ธฐ ์ ํ
}]
};- API ์๋ต์ด 5์ด ์ด์ ๊ฑธ๋ฆผ
- ํ์์์ ์๋ฌ ๋ฐ์
1. ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง
# CPU ์ฌ์ฉ๋ฅ ํ์ธ
htop
# ๋คํธ์ํฌ ์ฐ๊ฒฐ ์ํ
ss -s
# ๋์คํฌ I/O ํ์ธ
iostat -x 12. ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ํ ์ต์ ํ
// src/db.config.ts
export const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
connectionLimit: 10, // ์ฐ๊ฒฐ ์ ์ ํ
acquireTimeout: 60000, // ์ฐ๊ฒฐ ๋๊ธฐ ์๊ฐ
timeout: 60000, // ์ฟผ๋ฆฌ ํ์์์
reconnect: true, // ์๋ ์ฌ์ฐ๊ฒฐ
queueLimit: 0
});JsonWebTokenError: invalid tokenTokenExpiredError: jwt expired
1. JWT Secret ํ์ธ
# ํ๊ฒฝ๋ณ์ ํ์ธ
grep JWT_SECRET .env
# ์๋ฒ์ ํด๋ผ์ด์ธํธ ๋์ผํ secret ์ฌ์ฉํ๋์ง ํ์ธ2. ํ ํฐ ํ์ ํ์ธ
// ์ฌ๋ฐ๋ฅธ ํ ํฐ ํ์
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
// ์๋ชป๋ ํ์
Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... // Bearer ๋๋ฝ3. ํ ํฐ ๋ง๋ฃ ์๊ฐ ์กฐ์
// src/auth/jwt.ts
export const generateToken = (user: { id: string; nickname: string }) => {
return jwt.sign(user, JWT_SECRET, {
expiresIn: '7d', // 7์ผ๋ก ์ฐ์ฅ
});
};1. ์ ํ๋ฆฌ์ผ์ด์ ๋ก๊ทธ
# PM2 ๋ก๊ทธ ์ค์๊ฐ ํ์ธ
pm2 logs onairmate-api
# ์๋ฌ ๋ก๊ทธ๋ง
pm2 logs onairmate-api --err
# ํน์ ์ค ์๋ง
pm2 logs onairmate-api --lines 100
# ๋ก๊ทธ ํ์ผ ์ง์ ํ์ธ
tail -f ~/.pm2/logs/onairmate-api-out.log
tail -f ~/.pm2/logs/onairmate-api-error.log2. ์์คํ ๋ก๊ทธ
# ์์คํ
๋ก๊ทธ
sudo journalctl -u pm2-ec2-user -f
# ๋ถํ
๋ก๊ทธ
sudo journalctl -b
# ์๊ฐ ๋ฒ์๋ณ ๋ก๊ทธ
sudo journalctl --since "1 hour ago"3. ์น์๋ฒ ์ ๊ทผ ๋ก๊ทธ
# Nginx ๋ก๊ทธ (์ฌ์ฉ์)
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log1๋จ๊ณ: ๋น ๋ฅธ ์ง๋จ
# EC2 ์ ์ ํ์ธ
ssh -i your-key.pem ec2-user@15.164.176.168
# ๊ธฐ๋ณธ ์ํ ํ์ธ
pm2 status
curl http://localhost:3000/health
free -h
df -h2๋จ๊ณ: ์๋น์ค ์ฌ์์
# PM2 ๊ฐ์ ์ฌ์์
pm2 restart onairmate-api --force
# ์คํจ ์ ์์ ์ฌ์์
pm2 delete onairmate-api
pm2 start npm --name "onairmate-api" -- run start
pm2 save3๋จ๊ณ: ๋ฐฑ์ ์์ ๋ณต๊ตฌ
# ์ฝ๋ ๋ฐฑ์
์์ ๋ณต๊ตฌ
cd /home/ec2-user
git clone https://github.com/ON-AIR-mate/Node.js.git on-air-mate-backup
cd on-air-mate-backup
# ํ๊ฒฝ๋ณ์ ๋ณต์ฌ
cp ../on-air-mate/.env .
# ์์กด์ฑ ์ค์น ๋ฐ ์์
npm install
npm run build
pm2 start npm --name "onairmate-api-backup" -- run start1. ์์ ๋์ ์๋น์ค
// ์์ ์๋ต์ ์ํ Mock API
app.get('/api/*', (req, res) => {
res.status(503).json({
success: false,
error: {
code: 'DATABASE_MAINTENANCE',
message: '๋ฐ์ดํฐ๋ฒ ์ด์ค ์ ๊ฒ ์ค์
๋๋ค. ์ ์ ํ ๋ค์ ์๋ํด์ฃผ์ธ์.'
}
});
});2. RDS ์ฌ์์
# AWS CLI๋ก RDS ์ฌ์์ (๊ถํ ํ์)
aws rds reboot-db-instance --db-instance-identifier onairmate-db-seoul
# ๋๋ AWS Console์์ ์๋ ์ฌ์์1. ์๋ ๋ฐฐํฌ๋ก ์ ํ
# EC2์์ ์ง์ ๋ฐฐํฌ
cd /home/ec2-user/on-air-mate
git pull origin main
npm ci
npm run build
pm2 restart onairmate-api2. ๋กค๋ฐฑ
# ์ด์ ์ปค๋ฐ์ผ๋ก ๋กค๋ฐฑ
git log --oneline -10
git reset --hard COMMIT_HASH
npm run build
pm2 restart onairmate-api- AWS RDS ๋ฌธ์: https://docs.aws.amazon.com/rds/
- PM2 ๊ณต์ ๋ฌธ์: https://pm2.keymetrics.io/docs/
- Prisma ๋ฌธ์: https://www.prisma.io/docs/
# ์๋ฒ ์ํ ๋ชจ๋ํฐ๋ง (Uptime Robot ๋ฑ)
curl -X POST "https://api.uptimerobot.com/v2/getMonitors" \
-d "api_key=YOUR_API_KEY" \
-d "format=json"# ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฑ์
mysqldump -h onairmate-db-seoul.cviw844m2ex4.ap-northeast-2.rds.amazonaws.com \
-u admin -p onairmate > backup_$(date +%Y%m%d).sql
# ์ฝ๋ ๋ฐฑ์
tar -czf backup_$(date +%Y%m%d).tar.gz /home/ec2-user/on-air-mate- PM2 ํ๋ก์ธ์ค ์ํ ํ์ธ (
pm2 status) - ์ ํ๋ฆฌ์ผ์ด์
๋ก๊ทธ ํ์ธ (
pm2 logs onairmate-api) - ์์คํ
๋ฆฌ์์ค ํ์ธ (
free -h,df -h) - ๋คํธ์ํฌ ์ฐ๊ฒฐ ํ์ธ (
curl localhost:3000/health) - ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ํ์ธ (
npx prisma db pull) - ๋ณด์๊ทธ๋ฃน ์ค์ ํ์ธ (AWS Console)
- ํ๊ฒฝ๋ณ์ ํ์ธ (
grep -E "(DATABASE_URL|JWT_SECRET)" .env) - GitHub Actions ์ํฌํ๋ก์ฐ ํ์ธ (Actions ํญ)
- ํฌ์ค์ฒดํฌ ์ ์ ์๋ต (
curl http://15.164.176.168:3000/health) - API ๋ฌธ์ ์ ๊ทผ ๊ฐ๋ฅ (http://15.164.176.168:3000/api-docs)
- PM2 ์๋ ์์ ์ค์ (
pm2 startup,pm2 save) - ๋ก๊ทธ ๋กํ ์ด์ ์๋ ํ์ธ
- ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ ์ ๋ฒ์
- ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ ์์ ์ฑ
# PM2 ํด๋ฌ์คํฐ ๋ชจ๋ (๋ฉํฐ์ฝ์ด ํ์ฉ)
pm2 start ecosystem.config.js// ecosystem.config.js
module.exports = {
apps: [{
name: 'onairmate-api',
script: 'npm',
args: 'start',
instances: 'max', // CPU ์ฝ์ด ์๋งํผ ์ธ์คํด์ค ์์ฑ
exec_mode: 'cluster'
}]
};// ๋ฉ๋ชจ๋ฆฌ ๋์ ๋ฐฉ์ง
process.on('exit', () => {
console.log('Process exiting...');
});
process.on('SIGINT', () => {
console.log('SIGINT received, shutting down gracefully');
process.exit(0);
});// ์ฐ๊ฒฐ ํ ์ต์ ํ
export const pool = mysql.createPool({
connectionLimit: 10,
acquireTimeout: 60000,
timeout: 60000,
reconnect: true
});๐จ Remember: ๋ฌธ์ ๋ฐ์ ์ ๋นํฉํ์ง ๋ง๊ณ ์ฒด๊ณ์ ์ผ๋ก ์ ๊ทผํ์ธ์!
- ๋ก๊ทธ ํ์ธ โ 2. ์ํ ์ง๋จ โ 3. ๋จ๊ณ๋ณ ํด๊ฒฐ โ 4. ์ฌ๋ฐ ๋ฐฉ์ง