우분투 DB&Home 폴더 자동백업 프로그램
마스터욱
0
127
0
0
2025-07-29 05:47:23
/*
백업 프로그램을 만들고 싶어. 순서대로 설명해줄게.
1. 백업하고 싶은 서버는 외부에 있다. 백업 프로그램은 내 로컬컴퓨터에서 실행된다. 내 로컬컴퓨터는 윈도우11이다. nodejs 로 작성해줘.
2. 외부서버는 SSH 로 접근가능하다.
3. 외부서버는 우분투이다.
4. 백업하고 싶은 폴더는 /home 폴더와 mysql 의 모든 데이터베이스이다.(information_schema, mysql, performance_schema, sys 빼고)
5. 먼저 /home 폴더에 각각의 DB 덤프파일부터 만들고, /home 폴더를 .tar.gz 로 묵어버리는거지.
6. /home/aaa.sql, /home/bbb.sql... 이런식으로 만들어지고, /home 폴더안에서 tar cvzf 250729.tar.gz * 명령어로 전체를 타르로 묶어 버리게 하는거지.
7. 그리고 압축된 tar 파일을 내 로컬 컴퓨터로 전송하는거지.
8. 로컬 컴퓨터로 전송완료후 .sql 파일과 .tar.gz 는 삭제
9. 외부서버는 최소 1개이상이다. 즉 ssh 접속 id/password 랑 db로그인 id/password 를 배열로 구성해서 만들게 하면 될듯.
*/
const { Client } = require('ssh2');
const scp = require('scp2');
const fs = require('fs');
const path = require('path');
const today = new Date().toISOString().slice(2, 10).replace(/-/g, '');
const localBackupDir = path.join(__dirname, 'backups');
if (!fs.existsSync(localBackupDir)) fs.mkdirSync(localBackupDir);
const servers = [
{
name: '',
host: '',
port: 22,
username: '',
password: '',
dbUser: '',
dbPass: '',
},
// 더 추가 가능
];
function runSSHCommand(conn, command) {
return new Promise((resolve, reject) => {
conn.exec(command, (err, stream) => {
if (err) return reject(err);
let stdout = '';
let stderr = '';
stream
.on('close', (code, signal) => {
if (code !== 0) return reject(stderr || 'Command failed');
resolve(stdout);
})
.on('data', data => (stdout += data))
.stderr.on('data', data => (stderr += data));
});
});
}
function backupServer(server) {
return new Promise((resolve, reject) => {
const conn = new Client();
conn
.on('ready', async () => {
try {
console.log(`n???? [${server.name}] 접속 완료`);
// 1. DB 목록 조회
const showDBsCmd = `mysql -u${server.dbUser} -p${server.dbPass} -e "SHOW DATABASES;"`;
const dbListRaw = await runSSHCommand(conn, showDBsCmd);
const databases = dbListRaw
.split('n')
.slice(1)
.map(db => db.trim())
.filter(
db =>
db !== '' &&
!['information_schema', 'performance_schema', 'mysql', 'sys'].includes(db)
);
// 2. 덤프
for (const db of databases) {
console.log(`???? DB 덤프: ${db}`);
const dumpCmd = `mysqldump -u${server.dbUser} -p${server.dbPass} ${db} > /home/${db}.sql`;
await runSSHCommand(conn, dumpCmd);
}
// 3. 압축
const remoteTar = `/home/${today}.tar.gz`;
console.log(`???? 압축 중 → ${remoteTar}`);
await runSSHCommand(conn, `cd /home && tar -cvzf ${today}.tar.gz *`);
// 4. 다운로드
const localFilePath = path.join(localBackupDir, `${server.name}_${today}.tar.gz`);
console.log('⬇️ 다운로드 중...');
scp.scp(
{
host: server.host,
username: server.username,
password: server.password,
path: remoteTar,
},
localFilePath,
async err => {
if (err) return reject(err);
// 5. 원격 정리
console.log('???? 원격 파일 삭제');
await runSSHCommand(conn, `rm -f /home/*.sql /home/${today}.tar.gz`);
conn.end();
console.log(`✅ [${server.name}] 백업 완료: ${localFilePath}`);
resolve();
}
);
} catch (e) {
conn.end();
reject(e);
}
})
.connect({
host: server.host,
port: server.port,
username: server.username,
password: server.password,
});
});
}
// 순차 실행
(async () => {
for (const server of servers) {
try {
await backupServer(server);
} catch (err) {
console.error(`❌ [${server.name}] 오류 발생:`, err.message);
}
}
})();








