Genesis
This commit is contained in:
23
.env.example
Normal file
23
.env.example
Normal file
@@ -0,0 +1,23 @@
|
||||
# AWS S3 Configuration
|
||||
AWS_ACCESS_KEY_ID=your_access_key_id
|
||||
AWS_SECRET_ACCESS_KEY=your_secret_access_key
|
||||
AWS_REGION=your_region
|
||||
S3_BUCKET_NAME=your_bucket_name
|
||||
|
||||
# MSSQL Configuration
|
||||
MSSQL_SERVER=your_server_address
|
||||
MSSQL_PORT=1433
|
||||
MSSQL_USER=your_username
|
||||
MSSQL_PASSWORD=your_password
|
||||
MSSQL_DATABASE=eazybusiness
|
||||
|
||||
# Backup File Path
|
||||
BACKUP_FILE_PATH=F:\\ez.bak
|
||||
|
||||
# SMB Configuration for downloading backup file
|
||||
SMB_ADDRESS=//server/share
|
||||
SMB_USERNAME=your_username
|
||||
SMB_PASSWORD=your_password
|
||||
SMB_DOMAIN=your_domain
|
||||
SMB_DOWNLOAD_FILE=ez.bak
|
||||
SMB_LOCAL_DOWNLOAD_FILE=ez.bak
|
||||
53
.gitignore
vendored
Normal file
53
.gitignore
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
# Environment variables
|
||||
.env
|
||||
|
||||
# Dependencies
|
||||
node_modules/
|
||||
|
||||
# Backup files
|
||||
*.bak
|
||||
downloads/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Build files
|
||||
dist
|
||||
out
|
||||
build
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
79
README.md
Normal file
79
README.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Database Backup Service
|
||||
|
||||
A Node.js application that continuously runs and creates backups of an MSSQL database, then uploads them to Amazon S3.
|
||||
|
||||
## Features
|
||||
|
||||
- Automatically backs up MSSQL database using T-SQL backup commands
|
||||
- Uploads backup files to Amazon S3
|
||||
- Runs continuously with scheduled backups
|
||||
- Configurable backup interval
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js (v14 or higher recommended)
|
||||
- Access to an MSSQL database server
|
||||
- AWS S3 bucket and credentials
|
||||
|
||||
## Setup
|
||||
|
||||
1. Clone this repository
|
||||
2. Install dependencies:
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
3. Configure environment variables:
|
||||
Copy the `.env.example` file to `.env` and fill in your credentials:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Then edit the `.env` file with your actual credentials:
|
||||
- AWS_ACCESS_KEY_ID: Your AWS access key ID
|
||||
- AWS_SECRET_ACCESS_KEY: Your AWS secret access key
|
||||
- AWS_REGION: Your AWS region (e.g., us-east-1)
|
||||
- S3_BUCKET_NAME: Your S3 bucket name
|
||||
- MSSQL_SERVER: Your MSSQL server address
|
||||
- MSSQL_PORT: Your MSSQL server port (default: 1433)
|
||||
- MSSQL_USER: Your MSSQL username
|
||||
- MSSQL_PASSWORD: Your MSSQL password
|
||||
- MSSQL_DATABASE: Your database name (default: eazybusiness)
|
||||
- BACKUP_FILE_PATH: Path where backup file is created on MSSQL server (default: F:\ez.bak)
|
||||
- SMB_ADDRESS: Your SMB share address (e.g., //server/share)
|
||||
- SMB_USERNAME: Your SMB username
|
||||
- SMB_PASSWORD: Your SMB password
|
||||
- SMB_DOMAIN: Your SMB domain (optional)
|
||||
- SMB_LOCAL_DOWNLOAD_PATH: Local path to download backup files (default: ./downloads)
|
||||
|
||||
## Running the Application
|
||||
|
||||
Start the backup service:
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
For development with auto-restart:
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
1. The application connects to your MSSQL database using the provided credentials
|
||||
2. It executes a T-SQL backup command to create a backup file on the MSSQL server
|
||||
3. The backup file is downloaded from the SMB share to a local directory
|
||||
4. The local backup file is then uploaded to your specified S3 bucket
|
||||
5. This process repeats every 24 hours (configurable in the code)
|
||||
|
||||
## Configuration
|
||||
|
||||
The backup interval can be adjusted in `index.js` by modifying the `setInterval` parameter:
|
||||
```javascript
|
||||
// Currently set to 24 hours (86400000 milliseconds)
|
||||
setInterval(runBackupProcess, 86400000);
|
||||
```
|
||||
|
||||
## File Path Note
|
||||
|
||||
The backup file is created on the MSSQL server at the path specified by BACKUP_FILE_PATH environment variable (default: F:\ez.bak). Make sure this path is accessible on your MSSQL server and has appropriate permissions.
|
||||
22
gruvbox-terminal-theme.json
Normal file
22
gruvbox-terminal-theme.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"terminal.background": "#282828",
|
||||
"terminal.foreground": "#ebdbb2",
|
||||
"terminal.ansiBlack": "#282828",
|
||||
"terminal.ansiRed": "#cc241d",
|
||||
"terminal.ansiGreen": "#98971a",
|
||||
"terminal.ansiYellow": "#d79921",
|
||||
"terminal.ansiBlue": "#458588",
|
||||
"terminal.ansiMagenta": "#b16286",
|
||||
"terminal.ansiCyan": "#689d6a",
|
||||
"terminal.ansiWhite": "#a89984",
|
||||
"terminal.ansiBrightBlack": "#928374",
|
||||
"terminal.ansiBrightRed": "#fb4934",
|
||||
"terminal.ansiBrightGreen": "#b8bb26",
|
||||
"terminal.ansiBrightYellow": "#fabd2f",
|
||||
"terminal.ansiBrightBlue": "#83a598",
|
||||
"terminal.ansiBrightMagenta": "#d3869b",
|
||||
"terminal.ansiBrightCyan": "#8ec07c",
|
||||
"terminal.ansiBrightWhite": "#ebdbb2",
|
||||
"terminalCursor.foreground": "#ebdbb2",
|
||||
"terminal.selectionBackground": "#3c3836"
|
||||
}
|
||||
147
index.js
Normal file
147
index.js
Normal file
@@ -0,0 +1,147 @@
|
||||
require('dotenv').config();
|
||||
const sql = require('mssql');
|
||||
const AWS = require('aws-sdk');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const SambaClient = require('samba-client');
|
||||
|
||||
// AWS S3 Configuration
|
||||
const s3 = new AWS.S3({
|
||||
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
||||
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
|
||||
region: process.env.AWS_REGION
|
||||
});
|
||||
|
||||
// MSSQL Configuration
|
||||
const config = {
|
||||
user: process.env.MSSQL_USER,
|
||||
password: process.env.MSSQL_PASSWORD,
|
||||
server: process.env.MSSQL_SERVER,
|
||||
port: parseInt(process.env.MSSQL_PORT) || 1433,
|
||||
database: process.env.MSSQL_DATABASE,
|
||||
options: {
|
||||
encrypt: true, // Use this if you're on Windows Azure
|
||||
trustServerCertificate: true // Change to true for local dev / self-signed certs
|
||||
}
|
||||
};
|
||||
|
||||
// Backup file path
|
||||
const backupFilePath = process.env.BACKUP_FILE_PATH;
|
||||
|
||||
// SMB Configuration
|
||||
const smbConfig = {
|
||||
address: process.env.SMB_ADDRESS,
|
||||
username: process.env.SMB_USERNAME,
|
||||
password: process.env.SMB_PASSWORD,
|
||||
domain: process.env.SMB_DOMAIN || '', // optional
|
||||
};
|
||||
|
||||
// Ensure download directory exists
|
||||
const downloadFile = process.env.SMB_DOWNLOAD_FILE;
|
||||
const localDownloadFile = process.env.SMB_LOCAL_DOWNLOAD_FILE;
|
||||
|
||||
|
||||
// Function to create database backup
|
||||
async function createDatabaseBackup() {
|
||||
try {
|
||||
console.log('Connecting to database...');
|
||||
await sql.connect(config);
|
||||
|
||||
console.log('Creating database backup...');
|
||||
const backupQuery = `
|
||||
BACKUP DATABASE [${process.env.MSSQL_DATABASE}]
|
||||
TO DISK = N'${backupFilePath}'
|
||||
WITH NOFORMAT, NOINIT, NAME = N'${process.env.MSSQL_DATABASE}-Vollständig Datenbank Sichern',
|
||||
SKIP, NOREWIND, NOUNLOAD, STATS = 10
|
||||
`;
|
||||
|
||||
const result = await sql.query(backupQuery);
|
||||
console.log('Database backup created successfully');
|
||||
return backupFilePath;
|
||||
} catch (err) {
|
||||
console.error('Error creating database backup:', err);
|
||||
throw err;
|
||||
} finally {
|
||||
await sql.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Function to download backup file from SMB share
|
||||
async function downloadBackupFile() {
|
||||
try {
|
||||
console.log('Downloading backup file from SMB share...');
|
||||
|
||||
// Create SMB client
|
||||
const client = new SambaClient(smbConfig);
|
||||
|
||||
// Download file from SMB share
|
||||
await client.getFile(downloadFile, localDownloadFile);
|
||||
|
||||
console.log('Backup file downloaded successfully to:', localDownloadFile);
|
||||
return localDownloadFile;
|
||||
} catch (err) {
|
||||
console.error('Error downloading backup file from SMB share:', err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to upload backup to S3
|
||||
async function uploadBackupToS3(filePath) {
|
||||
try {
|
||||
console.log('Uploading backup to S3...');
|
||||
|
||||
// Create a read stream for the file
|
||||
const fileStream = fs.createReadStream(filePath);
|
||||
|
||||
// Handle stream errors
|
||||
fileStream.on('error', (err) => {
|
||||
console.error('File stream error:', err);
|
||||
throw err;
|
||||
});
|
||||
|
||||
// Create S3 upload parameters using stream
|
||||
const params = {
|
||||
Bucket: process.env.S3_BUCKET_NAME,
|
||||
Key: `backups/${process.env.MSSQL_DATABASE}_${new Date().toISOString().replace(/[:.]/g, '-')}.bak`,
|
||||
Body: fileStream
|
||||
};
|
||||
|
||||
// Upload file to S3 using stream
|
||||
const data = await s3.upload(params).promise();
|
||||
console.log('Backup uploaded successfully to S3:', data.Location);
|
||||
return data.Location;
|
||||
} catch (err) {
|
||||
console.error('Error uploading backup to S3:', err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
// Function to run backup process
|
||||
async function runBackupProcess() {
|
||||
try {
|
||||
console.log('Starting backup process at', new Date().toISOString());
|
||||
|
||||
// Create database backup
|
||||
await createDatabaseBackup();
|
||||
|
||||
// Download backup file from SMB share
|
||||
const localBackupFile = await downloadBackupFile();
|
||||
|
||||
// Upload backup to S3
|
||||
const s3Url = await uploadBackupToS3(localBackupFile);
|
||||
|
||||
console.log('Backup process completed successfully at', new Date().toISOString());
|
||||
console.log('Backup available at:', s3Url);
|
||||
} catch (err) {
|
||||
console.error('Backup process failed:', err);
|
||||
}
|
||||
}
|
||||
|
||||
// Run backup immediately when starting
|
||||
runBackupProcess();
|
||||
|
||||
// Schedule backup to run every 24 hours (86400000 milliseconds)
|
||||
// You can adjust this interval as needed
|
||||
setInterval(runBackupProcess, 86400000);
|
||||
|
||||
console.log('Database backup service started. Running backups every 24 hours.');
|
||||
3129
package-lock.json
generated
Normal file
3129
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
27
package.json
Normal file
27
package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "db-backup-service",
|
||||
"version": "1.0.0",
|
||||
"description": "A service to backup MSSQL database and upload to AWS S3",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"dev": "nodemon index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"aws-sdk": "^2.1490.0",
|
||||
"dotenv": "^16.0.3",
|
||||
"mssql": "^9.1.1",
|
||||
"samba-client": "^7.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"nodemon": "^3.0.1"
|
||||
},
|
||||
"keywords": [
|
||||
"mssql",
|
||||
"backup",
|
||||
"aws",
|
||||
"s3"
|
||||
],
|
||||
"author": "Cline",
|
||||
"license": "MIT"
|
||||
}
|
||||
Reference in New Issue
Block a user