feat: add backup compression
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
49510a6179
commit
5acf40d86e
|
@ -1,4 +1,5 @@
|
||||||
.idea/
|
.idea/
|
||||||
docker-db-backup
|
docker-db-backup
|
||||||
*.sql
|
*.sql
|
||||||
|
*.gz
|
||||||
./backups
|
./backups
|
||||||
|
|
|
@ -78,6 +78,10 @@ Default: `12`
|
||||||
If provided, the tool will do an empty GET request to this URL to indicate it successfully completed the backup job.
|
If provided, the tool will do an empty GET request to this URL to indicate it successfully completed the backup job.
|
||||||
You can use this with other tools to monitor if backups are completed as they should.
|
You can use this with other tools to monitor if backups are completed as they should.
|
||||||
|
|
||||||
|
### `BACKUP_COMPRESS`
|
||||||
|
|
||||||
|
If set provided and set to `true`, all backups will be compressed using gzip.
|
||||||
|
|
||||||
## Building from source
|
## Building from source
|
||||||
|
|
||||||
This project uses go modules, so you'll need at least go 1.11 to compile it.
|
This project uses go modules, so you'll need at least go 1.11 to compile it.
|
||||||
|
|
|
@ -18,6 +18,7 @@ type conf struct {
|
||||||
Schedule string
|
Schedule string
|
||||||
MaxBackups int
|
MaxBackups int
|
||||||
CompletionWebhookURL string
|
CompletionWebhookURL string
|
||||||
|
CompressBackups bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -30,6 +31,7 @@ const (
|
||||||
envSchedule = `BACKUP_SCHEDULE`
|
envSchedule = `BACKUP_SCHEDULE`
|
||||||
envMax = `BACKUP_MAX`
|
envMax = `BACKUP_MAX`
|
||||||
envCompletionWebhookURL = `BACKUP_COMPLETION_WEBHOOK_URL`
|
envCompletionWebhookURL = `BACKUP_COMPLETION_WEBHOOK_URL`
|
||||||
|
envCompressBackups = `BACKUP_COMPRESS`
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -66,6 +68,11 @@ func init() {
|
||||||
if has {
|
if has {
|
||||||
config.CompletionWebhookURL = webhookURL
|
config.CompletionWebhookURL = webhookURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compress, has := os.LookupEnv(envCompressBackups)
|
||||||
|
if has {
|
||||||
|
config.CompressBackups = compress == "1" || compress == "true"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateFullBackupPath() {
|
func updateFullBackupPath() {
|
||||||
|
|
|
@ -63,5 +63,5 @@ func (m *MysqlDumper) Dump(c *client.Client) error {
|
||||||
|
|
||||||
args := m.buildDumpArgs()
|
args := m.buildDumpArgs()
|
||||||
|
|
||||||
return runAndSaveCommandInContainer(getDumpFilename(m.Container.Name), c, m.Container, "mysqldump", args...)
|
return runAndSaveCommandInContainer(c, m.Container, "mysqldump", args...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,5 +26,5 @@ func (d *PostgresDumper) Dump(c *client.Client) error {
|
||||||
user = u
|
user = u
|
||||||
}
|
}
|
||||||
|
|
||||||
return runAndSaveCommandInContainer(getDumpFilename(d.Container.Name), c, d.Container, "pg_dumpall", "-U", user)
|
return runAndSaveCommandInContainer(c, d.Container, "pg_dumpall", "-U", user)
|
||||||
}
|
}
|
||||||
|
|
22
go.mod
22
go.mod
|
@ -1,15 +1,31 @@
|
||||||
module kolaente.dev/konrad/docker-db-backup
|
module kolaente.dev/konrad/docker-db-backup
|
||||||
|
|
||||||
go 1.16
|
go 1.21
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/containerd/containerd v1.5.5 // indirect
|
|
||||||
github.com/docker/docker v20.10.8+incompatible
|
github.com/docker/docker v20.10.8+incompatible
|
||||||
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/Microsoft/go-winio v0.4.17 // indirect
|
||||||
|
github.com/containerd/containerd v1.5.5 // indirect
|
||||||
|
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||||
github.com/docker/go-connections v0.4.0 // indirect
|
github.com/docker/go-connections v0.4.0 // indirect
|
||||||
|
github.com/docker/go-units v0.4.0 // indirect
|
||||||
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
|
github.com/golang/protobuf v1.5.0 // indirect
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
|
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||||
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
|
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect
|
||||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||||
|
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // indirect
|
||||||
google.golang.org/grpc v1.40.0 // indirect
|
google.golang.org/grpc v1.40.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.26.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
25
save.go
25
save.go
|
@ -1,6 +1,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"compress/gzip"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -10,16 +11,21 @@ import (
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runAndSaveCommandInContainer(filename string, c *client.Client, container *types.ContainerJSON, command string, args ...string) error {
|
func runAndSaveCommandInContainer(c *client.Client, container *types.ContainerJSON, command string, args ...string) error {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
config := types.ExecConfig{
|
filename := getDumpFilename(container.Name)
|
||||||
|
if config.CompressBackups {
|
||||||
|
filename += ".gz"
|
||||||
|
}
|
||||||
|
|
||||||
|
containerConfig := types.ExecConfig{
|
||||||
AttachStderr: true,
|
AttachStderr: true,
|
||||||
AttachStdout: true,
|
AttachStdout: true,
|
||||||
Cmd: append([]string{command}, args...),
|
Cmd: append([]string{command}, args...),
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := c.ContainerExecCreate(ctx, container.ID, config)
|
r, err := c.ContainerExecCreate(ctx, container.ID, containerConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -36,7 +42,18 @@ func runAndSaveCommandInContainer(filename string, c *client.Client, container *
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
_, err = io.Copy(f, resp.Reader)
|
var target io.Writer = f
|
||||||
|
|
||||||
|
if config.CompressBackups {
|
||||||
|
gw, err := gzip.NewWriterLevel(f, gzip.BestCompression)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer gw.Close()
|
||||||
|
target = gw
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(target, resp.Reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue