Skip to content

Commit

Permalink
Full backup
Browse files Browse the repository at this point in the history
  • Loading branch information
RyanKaleliGabriel committed Nov 23, 2024
1 parent 6e6dc07 commit c5092ab
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 28 deletions.
62 changes: 62 additions & 0 deletions backups/mysql-sample_2024-11-22T14-01-40-531Z.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
-- MySQL dump 10.13 Distrib 9.1.0, for Linux (x86_64)
--
-- Host: localhost Database: sample
-- ------------------------------------------------------
-- Server version 9.1.0

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Current Database: `sample`
--

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `sample` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;

USE `sample`;

--
-- Table structure for table `users`
--

DROP TABLE IF EXISTS `users`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `users` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`email` varchar(100) NOT NULL,
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `users`
--

LOCK TABLES `users` WRITE;
/*!40000 ALTER TABLE `users` DISABLE KEYS */;
INSERT INTO `users` VALUES (1,'John Doe','john.doe@example.com','2024-11-21 14:55:43'),(2,'Jane Smith','jane.smith@example.com','2024-11-21 14:55:43');
/*!40000 ALTER TABLE `users` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2024-11-22 14:01:40
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file removed commands/yargs.ts
Empty file.
1 change: 1 addition & 0 deletions compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ services:
- "27017:27017"
volumes:
- mongo_data:/data/lib
- ./backups:/backup
- ./db/mongo/init.js:/docker-entrypoint-initdb.d/init.js

volumes:
Expand Down
43 changes: 36 additions & 7 deletions services/mongodb/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { MongoClient } from "mongodb";
import { dbParams } from "../../models/universal";
import { program } from "commander";
import path from "path";
import { ensureBackupDirectory } from "../../utils/ensureBackupDirectory";
import { exec } from "child_process";

export const mongoDbBackup = async ({
host,
Expand All @@ -9,11 +11,38 @@ export const mongoDbBackup = async ({
password,
database,
}: dbParams) => {
const uri = `mongodb://${user}:${password}@${host}:${port}`;
const client = new MongoClient(uri);
await client.connect();
console.log("Connected to MongoDB!");
await client.close();
};
try {
const uri = `mongodb://${user}:${password}@${host}:${port}`;
const client = new MongoClient(uri);
await client.connect();
console.log("Connected to MongoDB!");
const backupDir = path.resolve("./backups");
ensureBackupDirectory(backupDir);

// Define the output path for the backup (directory where the database dump will be saved)
const outputDir = `${database}_${new Date()
.toISOString()
.replace(/[:.]/g, "-")}`;
const containerBackupDir = `/backup/${outputDir}`; // This is the directory inside the Docker container

// Create a dump command for MongoDB
// If the user is associated with a specific authentication database (e.g., admin), you must use the --authenticationDatabase flag to indicate where the user is stored.
const dumpCommand = `docker exec mongo_db sh -c "mongodump --uri=${uri} --port=${port} --username=${user} --password=${password} --authenticationDatabase=admin --db=${database} --gzip --out=${containerBackupDir}"`;
console.log(`Starting backup for mongo db: ${database}`);
await new Promise<void>((resolve, reject) => {
exec(dumpCommand, (error, stdout, stderr) => {
if (error) {
console.error("Backup failed:", stderr);
return reject(error);
}

console.log("Backup completed successfully", stdout);
return resolve();
});
});
await client.close();
} catch (error) {
console.error("Error during backup");
throw error;
}
};
52 changes: 43 additions & 9 deletions services/mysql/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { dbParams } from "../../models/universal";
import mysql from "mysql2/promise";
import { ensureBackupDirectory } from "../../utils/ensureBackupDirectory";
import path from "path";
import { exec } from "node:child_process";
// 1. Connect to the db
// 2. Export the file
// 3. Save th exported data to a file

export const mysqlBackup = async ({
host,
Expand All @@ -8,14 +14,42 @@ export const mysqlBackup = async ({
password,
database,
}: dbParams) => {
const conncetion = await mysql.createConnection({
host,
port,
user,
password,
database,
});
try {
const conncetion = await mysql.createConnection({
host,
port,
user,
password,
database,
});

console.log("Connected to MYSQL!");
await conncetion.end();
console.log("Connected to MYSQL!");
const backupDir = path.resolve("./backups");
ensureBackupDirectory(backupDir);

const outputPath = path.join(
backupDir,
`mysql-${database}_${new Date().toISOString().replace(/[:.]/g, "-")}.sql`
);

const dumpCommand = `docker exec mysql_db sh -c "mysqldump --databases ${database} --port ${port} --user ${user} --password=${password} --host ${host}" > ${outputPath}`;

console.log(`Starting backup for mysql db: ${database}`);

await new Promise<void>((resolve, reject) => {
exec(dumpCommand, (error, stdout, stderr) => {
if (error) {
console.error("Backup failed:", stderr);
return reject(error);
}

console.log("Backup completed successfully", stdout);
return resolve();
});
});
await conncetion.end();
} catch (error: any) {
console.error("Error during backup", error);
throw error;
}
};
67 changes: 55 additions & 12 deletions services/postgresql/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { dbParams } from "../../models/universal";
import { exec } from "node:child_process";
import { Client } from "pg";
import { dbParams } from "../../models/universal";
import path from "path";
import { ensureBackupDirectory } from "../../utils/ensureBackupDirectory";


// 1. Connect to the database.
// 2. Export data
// 3. Saved the exported data to a local file

export const postgresBackup = async ({
host,
Expand All @@ -8,15 +16,50 @@ export const postgresBackup = async ({
password,
database,
}: dbParams) => {
const client = new Client({
host,
port,
user,
password,
database,
});

await client.connect();
console.log(`Connected to postgreSQL!`);
await client.end();
try {
const client = new Client({
host,
port,
user,
password,
database,
});

await client.connect();
console.log(`Connected to postgreSQL!`);

const backupDir = path.resolve("./backups");
ensureBackupDirectory(backupDir);

const outputPath = path.join(
backupDir,
`postgres-${database}_${new Date().toISOString().replace(/[:.]/g, "-")}.sql`
);

// Construct the pg_dump. pg_dump is a utility for backing up a PostgreSQL database.
// -f file --file=file. Send output to the specified file.
// c custom Output a custom-format archive suitable for input into pg_restore.
// -b --large-objects --blobs (deprecated). Include large objects in the dump. ed. The -b switch is therefore only useful to add large objects to dumps where a specific schema or table has been requested.
const dumpCommand = `docker exec postgres_db sh -c "PGPASSWORD=${password} pg_dump -U ${user} -F c -b -v ${database}" > ${outputPath}`;

console.log(`Starting backup for database: ${database}`);

await new Promise<void>((resolve, reject) => {
exec(dumpCommand, (error, stdout, stderr) => {
if (error) {
console.error("Backup failed:", stderr);
return reject(error);
}
console.log("Backup completed successfully:", stdout);
resolve();
});
});

console.log(`Backup saved at: ${outputPath}`);
await client.end();
return outputPath;
} catch (error: any) {
console.error("Error during backup:", error);
throw error;
}
};
8 changes: 8 additions & 0 deletions utils/ensureBackupDirectory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import fs from "fs";

export const ensureBackupDirectory = (dir: string) => {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
console.log(`Backup directory created: ${dir}`);
}
};

0 comments on commit c5092ab

Please sign in to comment.