mirror of
https://github.com/offen/docker-volume-backup.git
synced 2025-12-06 17:38:01 +01:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94a1edc4ad | ||
|
|
a654097e59 | ||
|
|
1b1fc4856c | ||
|
|
e81c34b8fc | ||
|
|
9c23767fce |
28
README.md
28
README.md
@@ -207,9 +207,9 @@ You can populate below template according to your requirements and use it as you
|
|||||||
# AWS_ENDPOINT_PROTO="https"
|
# AWS_ENDPOINT_PROTO="https"
|
||||||
|
|
||||||
# Setting this variable to `true` will disable verification of
|
# Setting this variable to `true` will disable verification of
|
||||||
# SSL certificates. You shouldn't use this unless you use self-signed
|
# SSL certificates for AWS_ENDPOINT. You shouldn't use this unless you use
|
||||||
# certificates for your remote storage backend. This can only be used
|
# self-signed certificates for your remote storage backend. This can only be
|
||||||
# when AWS_ENDPOINT_PROTO is set to `https`.
|
# used when AWS_ENDPOINT_PROTO is set to `https`.
|
||||||
|
|
||||||
# AWS_ENDPOINT_INSECURE="true"
|
# AWS_ENDPOINT_INSECURE="true"
|
||||||
|
|
||||||
@@ -232,6 +232,12 @@ You can populate below template according to your requirements and use it as you
|
|||||||
|
|
||||||
# WEBDAV_PASSWORD="password"
|
# WEBDAV_PASSWORD="password"
|
||||||
|
|
||||||
|
# Setting this variable to `true` will disable verification of
|
||||||
|
# SSL certificates for WEBDAV_URL. You shouldn't use this unless you use
|
||||||
|
# self-signed certificates for your remote storage backend.
|
||||||
|
|
||||||
|
# WEBDAV_URL_INSECURE="true"
|
||||||
|
|
||||||
# In addition to storing backups remotely, you can also keep local copies.
|
# In addition to storing backups remotely, you can also keep local copies.
|
||||||
# Pass a container-local path to store your backups if needed. You also need to
|
# Pass a container-local path to store your backups if needed. You also need to
|
||||||
# mount a local folder or Docker volume into that location (`/archive`
|
# mount a local folder or Docker volume into that location (`/archive`
|
||||||
@@ -747,7 +753,7 @@ services:
|
|||||||
backup:
|
backup:
|
||||||
image: offen/docker-volume-backup:v2
|
image: offen/docker-volume-backup:v2
|
||||||
environment:
|
environment:
|
||||||
AWS_BUCKET_NAME: backup-bucket
|
AWS_S3_BUCKET_NAME: backup-bucket
|
||||||
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
||||||
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
||||||
volumes:
|
volumes:
|
||||||
@@ -769,7 +775,7 @@ services:
|
|||||||
image: offen/docker-volume-backup:v2
|
image: offen/docker-volume-backup:v2
|
||||||
environment:
|
environment:
|
||||||
AWS_ENDPOINT: s3.filebase.com
|
AWS_ENDPOINT: s3.filebase.com
|
||||||
AWS_BUCKET_NAME: filebase-bucket
|
AWS_S3_BUCKET_NAME: filebase-bucket
|
||||||
AWS_ACCESS_KEY_ID: FILEBASE-ACCESS-KEY
|
AWS_ACCESS_KEY_ID: FILEBASE-ACCESS-KEY
|
||||||
AWS_SECRET_ACCESS_KEY: FILEBASE-SECRET-KEY
|
AWS_SECRET_ACCESS_KEY: FILEBASE-SECRET-KEY
|
||||||
volumes:
|
volumes:
|
||||||
@@ -791,7 +797,7 @@ services:
|
|||||||
image: offen/docker-volume-backup:v2
|
image: offen/docker-volume-backup:v2
|
||||||
environment:
|
environment:
|
||||||
AWS_ENDPOINT: minio.example.com
|
AWS_ENDPOINT: minio.example.com
|
||||||
AWS_BUCKET_NAME: backup-bucket
|
AWS_S3_BUCKET_NAME: backup-bucket
|
||||||
AWS_ACCESS_KEY_ID: MINIOACCESSKEY
|
AWS_ACCESS_KEY_ID: MINIOACCESSKEY
|
||||||
AWS_SECRET_ACCESS_KEY: MINIOSECRETKEY
|
AWS_SECRET_ACCESS_KEY: MINIOSECRETKEY
|
||||||
volumes:
|
volumes:
|
||||||
@@ -855,7 +861,7 @@ services:
|
|||||||
backup:
|
backup:
|
||||||
image: offen/docker-volume-backup:v2
|
image: offen/docker-volume-backup:v2
|
||||||
environment:
|
environment:
|
||||||
AWS_BUCKET_NAME: backup-bucket
|
AWS_S3_BUCKET_NAME: backup-bucket
|
||||||
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
||||||
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
||||||
volumes:
|
volumes:
|
||||||
@@ -879,7 +885,7 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
# take a backup on every hour
|
# take a backup on every hour
|
||||||
BACKUP_CRON_EXPRESSION: "0 * * * *"
|
BACKUP_CRON_EXPRESSION: "0 * * * *"
|
||||||
AWS_BUCKET_NAME: backup-bucket
|
AWS_S3_BUCKET_NAME: backup-bucket
|
||||||
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
||||||
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
||||||
volumes:
|
volumes:
|
||||||
@@ -900,7 +906,7 @@ services:
|
|||||||
backup:
|
backup:
|
||||||
image: offen/docker-volume-backup:v2
|
image: offen/docker-volume-backup:v2
|
||||||
environment:
|
environment:
|
||||||
AWS_BUCKET_NAME: backup-bucket
|
AWS_S3_BUCKET_NAME: backup-bucket
|
||||||
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
||||||
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
||||||
BACKUP_FILENAME: backup-%Y-%m-%dT%H-%M-%S.tar.gz
|
BACKUP_FILENAME: backup-%Y-%m-%dT%H-%M-%S.tar.gz
|
||||||
@@ -924,7 +930,7 @@ services:
|
|||||||
backup:
|
backup:
|
||||||
image: offen/docker-volume-backup:v2
|
image: offen/docker-volume-backup:v2
|
||||||
environment:
|
environment:
|
||||||
AWS_BUCKET_NAME: backup-bucket
|
AWS_S3_BUCKET_NAME: backup-bucket
|
||||||
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
||||||
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
||||||
GPG_PASSPHRASE: somesecretstring
|
GPG_PASSPHRASE: somesecretstring
|
||||||
@@ -973,7 +979,7 @@ services:
|
|||||||
image: offen/docker-volume-backup:v2
|
image: offen/docker-volume-backup:v2
|
||||||
environment: &backup_environment
|
environment: &backup_environment
|
||||||
BACKUP_CRON_EXPRESSION: "0 2 * * *"
|
BACKUP_CRON_EXPRESSION: "0 2 * * *"
|
||||||
AWS_BUCKET_NAME: backup-bucket
|
AWS_S3_BUCKET_NAME: backup-bucket
|
||||||
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
|
||||||
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
|
||||||
# Label the container using the `data_1` volume as `docker-volume-backup.stop-during-backup=service1`
|
# Label the container using the `data_1` volume as `docker-volume-backup.stop-during-backup=service1`
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ type Config struct {
|
|||||||
EmailSMTPUsername string `envconfig:"EMAIL_SMTP_USERNAME"`
|
EmailSMTPUsername string `envconfig:"EMAIL_SMTP_USERNAME"`
|
||||||
EmailSMTPPassword string `envconfig:"EMAIL_SMTP_PASSWORD"`
|
EmailSMTPPassword string `envconfig:"EMAIL_SMTP_PASSWORD"`
|
||||||
WebdavUrl string `split_words:"true"`
|
WebdavUrl string `split_words:"true"`
|
||||||
|
WebdavUrlInsecure bool `split_words:"true"`
|
||||||
WebdavPath string `split_words:"true" default:"/"`
|
WebdavPath string `split_words:"true" default:"/"`
|
||||||
WebdavUsername string `split_words:"true"`
|
WebdavUsername string `split_words:"true"`
|
||||||
WebdavPassword string `split_words:"true"`
|
WebdavPassword string `split_words:"true"`
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -146,6 +147,15 @@ func newScript() (*script, error) {
|
|||||||
} else {
|
} else {
|
||||||
webdavClient := gowebdav.NewClient(s.c.WebdavUrl, s.c.WebdavUsername, s.c.WebdavPassword)
|
webdavClient := gowebdav.NewClient(s.c.WebdavUrl, s.c.WebdavUsername, s.c.WebdavPassword)
|
||||||
s.webdavClient = webdavClient
|
s.webdavClient = webdavClient
|
||||||
|
if s.c.WebdavUrlInsecure {
|
||||||
|
defaultTransport, ok := http.DefaultTransport.(*http.Transport)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("newScript: unexpected error when asserting type for http.DefaultTransport")
|
||||||
|
}
|
||||||
|
webdavTransport := defaultTransport.Clone()
|
||||||
|
webdavTransport.TLSClientConfig.InsecureSkipVerify = s.c.WebdavUrlInsecure
|
||||||
|
s.webdavClient.SetTransport(webdavTransport)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,7 +546,8 @@ func (s *script) pruneBackups() error {
|
|||||||
if s.minioClient != nil {
|
if s.minioClient != nil {
|
||||||
candidates := s.minioClient.ListObjects(context.Background(), s.c.AwsS3BucketName, minio.ListObjectsOptions{
|
candidates := s.minioClient.ListObjects(context.Background(), s.c.AwsS3BucketName, minio.ListObjectsOptions{
|
||||||
WithMetadata: true,
|
WithMetadata: true,
|
||||||
Prefix: s.c.BackupPruningPrefix,
|
Prefix: filepath.Join(s.c.AwsS3Path, s.c.BackupPruningPrefix),
|
||||||
|
Recursive: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
var matches []minio.ObjectInfo
|
var matches []minio.ObjectInfo
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -12,7 +12,7 @@ require (
|
|||||||
github.com/minio/minio-go/v7 v7.0.16
|
github.com/minio/minio-go/v7 v7.0.16
|
||||||
github.com/otiai10/copy v1.7.0
|
github.com/otiai10/copy v1.7.0
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f
|
github.com/studio-b12/gowebdav v0.0.0-20220128162035-c7b1ff8a5e62
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
|
||||||
)
|
)
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -660,6 +660,8 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd
|
|||||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f h1:L2NE7BXnSlSLoNYZ0lCwZDjdnYjCNYC71k9ClZUTFTs=
|
github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f h1:L2NE7BXnSlSLoNYZ0lCwZDjdnYjCNYC71k9ClZUTFTs=
|
||||||
github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
|
github.com/studio-b12/gowebdav v0.0.0-20211109083228-3f8721cd4b6f/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
|
||||||
|
github.com/studio-b12/gowebdav v0.0.0-20220128162035-c7b1ff8a5e62 h1:b2nJXyPCa9HY7giGM+kYcnQ71m14JnGdQabMPmyt++8=
|
||||||
|
github.com/studio-b12/gowebdav v0.0.0-20220128162035-c7b1ff8a5e62/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
|
||||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ services:
|
|||||||
BACKUP_PRUNING_PREFIX: test
|
BACKUP_PRUNING_PREFIX: test
|
||||||
GPG_PASSPHRASE: 1234secret
|
GPG_PASSPHRASE: 1234secret
|
||||||
WEBDAV_URL: http://webdav/
|
WEBDAV_URL: http://webdav/
|
||||||
|
WEBDAV_URL_INSECURE: 'true'
|
||||||
WEBDAV_PATH: /my/new/path/
|
WEBDAV_PATH: /my/new/path/
|
||||||
WEBDAV_USERNAME: test
|
WEBDAV_USERNAME: test
|
||||||
WEBDAV_PASSWORD: test
|
WEBDAV_PASSWORD: test
|
||||||
|
|||||||
Reference in New Issue
Block a user