diff --git a/docs/how-tos/backup.md b/docs/how-tos/backup.md index 2cea167..3c9da7a 100644 --- a/docs/how-tos/backup.md +++ b/docs/how-tos/backup.md @@ -38,6 +38,8 @@ services: - DB_NAME=database - DB_USERNAME=username - DB_PASSWORD=password + # You can also use JDBC format + #- DB_URL=jdbc:postgresql://postgres:5432/database?user=user&password=password # pg-bkup container must be connected to the same network with your database networks: - web @@ -67,7 +69,7 @@ services: # for a list of available releases. image: jkaninda/pg-bkup container_name: pg-bkup - command: backup -d database --cron-expression "0 1 * * *" + command: backup -d database --cron-expression @midnight volumes: - ./backup:/backup environment: @@ -76,7 +78,9 @@ services: - DB_NAME=database - DB_USERNAME=username - DB_PASSWORD=password - - BACKUP_CRON_EXPRESSION=0 1 * * * + - BACKUP_CRON_EXPRESSION=@midnight + # You can also use JDBC format + #- DB_URL=jdbc:postgresql://postgres:5432/database?user=user&password=password #Delete old backup created more than specified days ago #- BACKUP_RETENTION_DAYS=7 # pg-bkup container must be connected to the same network with your database diff --git a/docs/how-tos/migrate.md b/docs/how-tos/migrate.md index 336839b..6d05857 100644 --- a/docs/how-tos/migrate.md +++ b/docs/how-tos/migrate.md @@ -38,12 +38,16 @@ services: - DB_NAME=database - DB_USERNAME=username - DB_PASSWORD=password + # You can also use JDBC format + #- DB_URL=jdbc:postgresql://postgres:5432/database?user=username&password=password ## Target database - TARGET_DB_HOST=target-postgres - TARGET_DB_PORT=5432 - TARGET_DB_NAME=dbname - TARGET_DB_USERNAME=username - TARGET_DB_PASSWORD=password + # You can also use JDBC format + #- TARGET_DB_URL=jdbc:postgresql://target-postgres:5432/dbname?user=username&password=password # mysql-bkup container must be connected to the same network with your database networks: - web diff --git a/docs/reference/index.md b/docs/reference/index.md index 1f99bb5..95e1336 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -32,43 +32,48 @@ Backup, restore and migrate targets, schedule and retention are configured using ## Environment variables -| Name | Requirement | Description | -|------------------------|---------------------------------------------------------------|-----------------------------------------------------------------| -| DB_PORT | Optional, default 5432 | Database port number | -| DB_HOST | Required | Database host | -| DB_NAME | Optional if it was provided from the -d flag | Database name | -| DB_USERNAME | Required | Database user name | -| DB_PASSWORD | Required | Database password | -| AWS_ACCESS_KEY | Optional, required for S3 storage | AWS S3 Access Key | -| AWS_SECRET_KEY | Optional, required for S3 storage | AWS S3 Secret Key | -| AWS_BUCKET_NAME | Optional, required for S3 storage | AWS S3 Bucket Name | -| AWS_BUCKET_NAME | Optional, required for S3 storage | AWS S3 Bucket Name | -| AWS_REGION | Optional, required for S3 storage | AWS Region | -| AWS_DISABLE_SSL | Optional, required for S3 storage | Disable SSL | -| AWS_FORCE_PATH_STYLE | Optional, required for S3 storage | Force path style | -| FILE_NAME | Optional if it was provided from the --file flag | Database file to restore (extensions: .sql, .sql.gz) | -| GPG_PASSPHRASE | Optional, required to encrypt and restore backup | GPG passphrase | -| GPG_PUBLIC_KEY | Optional, required to encrypt backup | GPG public key, used to encrypt backup (/config/public_key.asc) | -| BACKUP_CRON_EXPRESSION | Optional if it was provided from the `--cron-expression` flag | Backup cron expression for docker in scheduled mode | -| BACKUP_RETENTION_DAYS | Optional | Delete old backup created more than specified days ago | -| SSH_HOST | Optional, required for SSH storage | ssh remote hostname or ip | -| SSH_USER | Optional, required for SSH storage | ssh remote user | -| SSH_PASSWORD | Optional, required for SSH storage | ssh remote user's password | -| SSH_IDENTIFY_FILE | Optional, required for SSH storage | ssh remote user's private key | -| SSH_PORT | Optional, required for SSH storage | ssh remote server port | -| REMOTE_PATH | Optional, required for SSH or FTP storage | remote path (/home/toto/backup) | -| FTP_HOST | Optional, required for FTP storage | FTP host name | -| FTP_PORT | Optional, required for FTP storage | FTP server port number | -| FTP_USER | Optional, required for FTP storage | FTP user | -| FTP_PASSWORD | Optional, required for FTP storage | FTP user password | -| TARGET_DB_HOST | Optional, required for database migration | Target database host | -| TARGET_DB_PORT | Optional, required for database migration | Target database port | -| TARGET_DB_NAME | Optional, required for database migration | Target database name | -| TARGET_DB_USERNAME | Optional, required for database migration | Target database username | -| TARGET_DB_PASSWORD | Optional, required for database migration | Target database password | -| TG_TOKEN | Optional, required for Telegram notification | Telegram token (`BOT-ID:BOT-TOKEN`) | -| TG_CHAT_ID | Optional, required for Telegram notification | Telegram Chat ID | -| TZ | Optional | Time Zone | +| Name | Requirement | Description | +|------------------------------|---------------------------------------------------------------|-----------------------------------------------------------------| +| DB_PORT | Optional, default 5432 | Database port number | +| DB_HOST | Required | Database host | +| DB_NAME | Optional if it was provided from the -d flag | Database name | +| DB_USERNAME | Required | Database user name | +| DB_PASSWORD | Required | Database password | +| DB_URL | Optional | Database URL in JDBC URI format | +| AWS_ACCESS_KEY | Optional, required for S3 storage | AWS S3 Access Key | +| AWS_SECRET_KEY | Optional, required for S3 storage | AWS S3 Secret Key | +| AWS_BUCKET_NAME | Optional, required for S3 storage | AWS S3 Bucket Name | +| AWS_BUCKET_NAME | Optional, required for S3 storage | AWS S3 Bucket Name | +| AWS_REGION | Optional, required for S3 storage | AWS Region | +| AWS_DISABLE_SSL | Optional, required for S3 storage | Disable SSL | +| AWS_FORCE_PATH_STYLE | Optional, required for S3 storage | Force path style | +| FILE_NAME | Optional if it was provided from the --file flag | Database file to restore (extensions: .sql, .sql.gz) | +| GPG_PASSPHRASE | Optional, required to encrypt and restore backup | GPG passphrase | +| GPG_PUBLIC_KEY | Optional, required to encrypt backup | GPG public key, used to encrypt backup (/config/public_key.asc) | +| BACKUP_CRON_EXPRESSION | Optional if it was provided from the `--cron-expression` flag | Backup cron expression for docker in scheduled mode | +| BACKUP_RETENTION_DAYS | Optional | Delete old backup created more than specified days ago | +| SSH_HOST | Optional, required for SSH storage | ssh remote hostname or ip | +| SSH_USER | Optional, required for SSH storage | ssh remote user | +| SSH_PASSWORD | Optional, required for SSH storage | ssh remote user's password | +| SSH_IDENTIFY_FILE | Optional, required for SSH storage | ssh remote user's private key | +| SSH_PORT | Optional, required for SSH storage | ssh remote server port | +| REMOTE_PATH | Optional, required for SSH or FTP storage | remote path (/home/toto/backup) | +| FTP_HOST | Optional, required for FTP storage | FTP host name | +| FTP_PORT | Optional, required for FTP storage | FTP server port number | +| FTP_USER | Optional, required for FTP storage | FTP user | +| FTP_PASSWORD | Optional, required for FTP storage | FTP user password | +| TARGET_DB_HOST | Optional, required for database migration | Target database host | +| TARGET_DB_PORT | Optional, required for database migration | Target database port | +| TARGET_DB_NAME | Optional, required for database migration | Target database name | +| TARGET_DB_USERNAME | Optional, required for database migration | Target database username | +| TARGET_DB_URL | Optional | Database URL in JDBC URI format | +| TARGET_DB_PASSWORD | Optional, required for database migration | Target database password | +| TG_TOKEN | Optional, required for Telegram notification | Telegram token (`BOT-ID:BOT-TOKEN`) | +| TG_CHAT_ID | Optional, required for Telegram notification | Telegram Chat ID | +| TZ | Optional | Time Zone | +| AZURE_STORAGE_CONTAINER_NAME | Optional, required for Azure Blob Storage storage | Azure storage container name | +| AZURE_STORAGE_ACCOUNT_NAME | Optional, required for Azure Blob Storage storage | Azure storage account name | +| AZURE_STORAGE_ACCOUNT_KEY | Optional, required for Azure Blob Storage storage | Azure storage account key | --- ## Run in Scheduled mode diff --git a/pkg/config.go b/pkg/config.go index ba63be4..31fb1ee 100644 --- a/pkg/config.go +++ b/pkg/config.go @@ -109,6 +109,14 @@ type AWSConfig struct { } func initDbConfig(cmd *cobra.Command) *dbConfig { + jdbcUri := os.Getenv("DB_URL") + if len(jdbcUri) != 0 { + config, err := convertJDBCToDbConfig(jdbcUri) + if err != nil { + utils.Fatal("Error: %v", err.Error()) + } + return config + } // Set env utils.GetEnv(cmd, "dbname", "DB_NAME") dConf := dbConfig{} @@ -293,6 +301,20 @@ func initRestoreConfig(cmd *cobra.Command) *RestoreConfig { return &rConfig } func initTargetDbConfig() *targetDbConfig { + jdbcUri := os.Getenv("TARGET_DB_URL") + if len(jdbcUri) != 0 { + config, err := convertJDBCToDbConfig(jdbcUri) + if err != nil { + utils.Fatal("Error: %v", err.Error()) + } + return &targetDbConfig{ + targetDbHost: config.dbHost, + targetDbPort: config.dbPort, + targetDbName: config.dbName, + targetDbPassword: config.dbPassword, + targetDbUserName: config.dbUserName, + } + } tdbConfig := targetDbConfig{} tdbConfig.targetDbHost = os.Getenv("TARGET_DB_HOST") tdbConfig.targetDbPort = utils.EnvWithDefault("TARGET_DB_PORT", "5432") diff --git a/pkg/helper.go b/pkg/helper.go index 0a8c4e2..d18ca8e 100644 --- a/pkg/helper.go +++ b/pkg/helper.go @@ -29,6 +29,7 @@ import ( "fmt" "github.com/jkaninda/pg-bkup/utils" "gopkg.in/yaml.v3" + "net/url" "os" "os/exec" "path/filepath" @@ -196,3 +197,34 @@ func RemoveLastExtension(filename string) string { } return filename } +func convertJDBCToDbConfig(jdbcURI string) (*dbConfig, error) { + // Remove the "jdbc:" prefix + jdbcURI = strings.TrimPrefix(jdbcURI, "jdbc:") + // Parse the URI + u, err := url.Parse(jdbcURI) + if err != nil { + return &dbConfig{}, fmt.Errorf("failed to parse JDBC URI: %v", err) + } + // Extract components + host := u.Hostname() + port := u.Port() + if port == "" { + port = "5432" // Default PostgreSQL port + } + database := strings.TrimPrefix(u.Path, "/") + params, _ := url.ParseQuery(u.RawQuery) + username := params.Get("user") + password := params.Get("password") + // Validate essential fields + if host == "" || database == "" || username == "" { + return &dbConfig{}, fmt.Errorf("incomplete JDBC URI: missing host, database, or username") + } + + return &dbConfig{ + dbHost: host, + dbPort: port, + dbName: database, + dbUserName: username, + dbPassword: password, + }, nil +}