W dzisiejszym świecie programowania, gdzie dane są nieocenionym zasobem, automatyzacja backupów staje się podstawą niezawodnych aplikacji. Node.js, dzięki swojej asynchronicznej naturze i bogatemu ekosystemowi bibliotek npm, idealnie nadaje się do tworzenia skryptów backupowych, które mogą zapisywać pliki na FTP lub w chmurze jak Google Cloud Storage (alternatywa dla Google Drive do automatyzacji). W tym przewodniku krok po kroku zbudujesz kompletny system – od konfiguracji po automatyzację z użyciem crona.
Artykuł jest podzielony na następujące sekcje:
- wprowadzenie do backupów,
- konfiguracja Node.js,
- integracja z ftp,
- integracja z google cloud storage,
- tworzenie skryptu głównego,
- obsługa błędów i logowanie,
- testowanie i automatyzacja,
- najlepsze praktyki i bezpieczeństwo.
Dlaczego automatyzować backupy w Node.js?
Backupy to cykliczne kopie danych, które chronią przed utratą informacji spowodowaną awariami, atakami czy błędami ludzkimi. Node.js wyróżnia się tu asynchronicznością i prostotą – jeden skrypt może kompresować pliki, wysłać je na zdalny serwer i uruchamiać się automatycznie.
Zadanie crona to zestaw instrukcji definiujących gdzie (ścieżka), jak (akcja) i kiedy (harmonogram) wykonać backup, np. codziennie o 1:00.
Dla początkujących: Node.js nie wymaga kompilacji – instalujesz pakiety za pomocą npm install, piszesz kod w pliku .js i uruchamiasz node nazwa-pliku.js.
Przygotowanie środowiska Node.js
Zainstaluj Node.js z oficjalnej strony (wersja LTS, np. 20.x), a następnie utwórz nowy projekt i zainicjuj go komendami:
mkdir backup-automation
cd backup-automation
npm init -y
Zainstaluj kluczowe pakiety:
node-cron– do automatyzacji zadań w aplikacji (na serwerach i tak skorzystamy z systemowego crona);basic-ftp– klient FTP/FTPS do wysyłania plików;@google-cloud/storage– integracja z Google Cloud Storage (prostsze od Google Drive w kontekście automatyzacji);archiverorazfs-extra– kompresja do ZIP i wygodna obsługa plików/katalogów;mysqldump– opcjonalnie do eksportu bazy MySQL;dotenv– wczytywanie zmiennych środowiskowych z pliku.env.
Komenda instalacji:
npm install node-cron basic-ftp @google-cloud/storage archiver fs-extra mysqldump dotenv
Automatyzacja backupów przez FTP
FTP (File Transfer Protocol) to prosty protokół do przesyłania plików na zdalne serwery. W praktyce używaj FTPS (secure: true) wszędzie tam, gdzie to możliwe.
Krok 1 – podstawowy skrypt FTP
Utwórz plik backup-ftp.js z funkcją tworzącą archiwum i wysyłającą je na serwer:
const fs = require('fs-extra');
const archiver = require('archiver');
const FTPClient = require('basic-ftp');
async function createAndUploadBackup(sourceDir, ftpConfig, remoteDir = '/backups') {
const backupFilename = `backup-${new Date().toISOString().replace(/[:.]/g, '-')}.zip`;
const localPath = backupFilename;
// Tworzenie archiwum ZIP
await new Promise((resolve, reject) => {
const output = fs.createWriteStream(localPath);
const archive = archiver('zip', { zlib: { level: 9 } });
output.on('close', resolve);
archive.on('warning', (err) => {
if (err.code === 'ENOENT') {
console.warn('Ostrzeżenie archiver:', err.message);
} else {
reject(err);
}
});
archive.on('error', reject);
archive.pipe(output);
archive.directory(sourceDir, false);
archive.finalize();
});
// Wysyłka na FTP/FTPS
const client = new FTPClient.Client();
try {
await client.access({
host: ftpConfig.host,
user: ftpConfig.user,
password: ftpConfig.password,
secure: ftpConfig.secure ?? true
});
await client.ensureDir(remoteDir);
await client.uploadFrom(localPath, `${remoteDir}/${backupFilename}`);
console.log(`Wysłano: ${backupFilename}`);
} finally {
client.close();
await fs.remove(localPath); // Porządki lokalne
}
return backupFilename;
}
module.exports = createAndUploadBackup;
Wyjaśnienie dla początkujących – funkcja kompresuje katalog sourceDir do ZIP, łączy się z FTP/FTPS, tworzy katalog docelowy (jeśli nie istnieje), przesyła plik i usuwa kopię lokalną po zakończeniu.
Krok 2 – bezpieczeństwo FTP
Przechowuj dane logowania w pliku .env i nie commituj go do repozytorium:
FTP_HOST=ftp.example.com
FTP_USER=user
FTP_PASS=pass
FTP_SECURE=true
FTP_REMOTE_DIR=/backups
SOURCE_DIR=./data
Wczytaj zmienne środowiskowe na początku aplikacji:
require('dotenv').config();
Backupy do chmury (Google Cloud Storage)
Google Drive jest intuicyjne, ale w automatyzacji prostszy i szybszy jest Google Cloud Storage (GCS) – konfigurujesz konto serwisowe i używasz klucza JSON bez interakcji użytkownika.
Krok 1 – konfiguracja Google Cloud
Wykonaj następujące kroki konfiguracyjne:
- Utwórz projekt w Google Cloud (console.cloud.google.com).
- Włącz Storage API w projekcie.
- Utwórz konto serwisowe z rolą Storage Object Creator lub wyższą (zgodnie z potrzebami).
- Pobierz klucz JSON (np.
gcs.json) i zapisz w katalogu projektu. - Utwórz bucket, np.
backup-bucket-2026.
Krok 2 – skrypt GCS
Utwórz plik backup-gcs.js do backupu bazy MySQL i wysyłki do GCS:
const { Storage } = require('@google-cloud/storage');
const mysqldump = require('mysqldump');
const fs = require('fs-extra');
const path = require('path');
async function createDBBackupAndUploadGCS({ projectId, keyFilename, bucketName, connection }) {
const dumpFileName = `${new Date().toISOString().slice(0,10)}.dump.sql`;
try {
// Backup bazy MySQL do pliku
await mysqldump({ connection, dumpToFile: dumpFileName });
// Upload do GCS
const storage = new Storage({ projectId, keyFilename });
const bucket = storage.bucket(bucketName);
await bucket.upload(dumpFileName, {
gzip: true,
metadata: { cacheControl: 'private, max-age=0' }
});
console.log(`Backup wgrany do GCS: gs://${bucketName}/${dumpFileName}`);
} finally {
// Usuń lokalny plik dump po udanym/późniejszym procesie
if (await fs.pathExists(dumpFileName)) {
await fs.remove(dumpFileName);
}
}
}
module.exports = createDBBackupAndUploadGCS;
Wskazówka – dla plików i katalogów (zamiast bazy) użyj archiver, jak w przykładzie z FTP, a następnie wyślij powstały ZIP do GCS metodą bucket.upload.
Główny skrypt backupowy z wyborem metody
Utwórz plik index.js, który zbiera konfigurację z .env i uruchamia właściwą metodę:
require('dotenv').config();
const createBackupFTP = require('./backup-ftp');
const createBackupGCS = require('./backup-gcs');
async function main() {
const method = process.argv[2] || 'ftp';
try {
if (method === 'ftp') {
const sourceDir = process.env.SOURCE_DIR || './data';
const ftpConfig = {
host: process.env.FTP_HOST,
user: process.env.FTP_USER,
password: process.env.FTP_PASS,
secure: process.env.FTP_SECURE === 'true'
};
const remoteDir = process.env.FTP_REMOTE_DIR || '/backups';
await createBackupFTP(sourceDir, ftpConfig, remoteDir);
} else if (method === 'gcs') {
await createBackupGCS({
projectId: process.env.GCP_PROJECT_ID || 'backup-project',
keyFilename: process.env.GCP_KEY_FILE || './gcs.json',
bucketName: process.env.GCS_BUCKET || 'backup-bucket-2026',
connection: {
host: process.env.DB_HOST || 'localhost',
user: process.env.DB_USER || 'root',
password: process.env.DB_PASS || '',
database: process.env.DB_NAME || 'moja_baza'
}
});
} else {
console.error('Nieznana metoda. Użyj: ftp lub gcs');
process.exit(1);
}
} catch (err) {
console.error('Błąd zadania backupu:', err);
process.exit(1);
}
}
main();
Obsługa błędów i logowanie
Zainstaluj logger i dodaj go do projektu:
npm install winston
Przykładowa konfiguracja winston z plikiem logów i znacznikami czasu:
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.json()
),
transports: [
new winston.transports.Console(),
new winston.transports.File({ filename: 'backup.log' })
]
});
// Przykład użycia:
logger.info('Backup zakończony pomyślnie', { method: 'ftp' });
logger.error('Błąd backupu', { error: new Error('Timeout') });
Obsługuj przypadki brzegowe: brak połączenia z internetem, pełne dyski, zbyt niskie uprawnienia, przekroczone limity API (np. rozmiar pliku), brak miejsca w bucketach lub na FTP.
Testowanie skryptu
Przetestuj działanie krok po kroku:
- Uruchom ręcznie:
node index.js ftplubnode index.js gcs. - Sprawdź, czy pliki pojawiły się na FTP lub w GCS (bucket).
- Symuluj błędy: rozłącz internet, zmień błędnie hasło, zasymuluj pełny dysk.
Automatyzacja z cronem
Cron w Linux/macOS pozwala harmonogramować zadania. Edytuj konfigurację poleceniem crontab -e, a następnie dodaj wpis:
0 1 * * * /usr/bin/node /ścieżka/do/index.js gcs >> /var/log/backup.log 2>&1
Format crona – minuta, godzina, dzień miesiąca, miesiąc, dzień tygodnia. Przykład powyżej uruchamia backup codziennie o 1:00.
Dla Windows skorzystaj z Harmonogramu zadań, np. poleceniem:
schtasks /Create /SC DAILY /TN "DB-GCS-Backup" /TR "node C:\ścieżka\do\index.js gcs" /ST 01:00
Najlepsze praktyki i bezpieczeństwo
Poniżej znajdziesz zestaw rekomendacji, które zwiększają niezawodność i bezpieczeństwo procesu backupu:
- rotacja backupów – automatycznie usuwaj stare pliki (np. przechowuj 7–14 dni);
- szyfrowanie – przed wysyłką zaszyfruj archiwum (np. AES za pomocą
crypto); - środowiska – testuj rozwiązanie na dev/stage, a produkcję uruchamiaj z tajnymi kluczami (secrets);
- monitoring – integruj alerty błędów ze Slack/Email i monitoruj czas trwania zadań;
- skalowalność – dla dużych danych stosuj dzielenie na części lub tryb resumable upload w GCS;
- bezpieczeństwo kluczy – nie commituj kluczy (
.gitignore), używaj zmiennych środowiskowych i minimalnych ról IAM.
Krótko porównanie metod, które pomoże wybrać właściwą ścieżkę:
| Metoda | Zalety | Wady | Koszt |
|---|---|---|---|
| FTP | proste wdrożenie, szerokie wsparcie u dostawców hostingu | domyślnie brak szyfrowania (chyba że FTPS), niższa wydajność | niski |
| GCS | szybkie, skalowalne, łatwe klucze serwisowe | wymaga konta Google i konfiguracji projektu | ok. 0,02 USD/GB/miesiąc |






