Logger
							parent
							
								
									7c61f09817
								
							
						
					
					
						commit
						2e90fe12a3
					
				
							
								
								
									
										25
									
								
								Taskfile.yml
								
								
								
								
							
							
						
						
									
										25
									
								
								Taskfile.yml
								
								
								
								
							|  | @ -1,9 +1,26 @@ | |||
| version: '3' | ||||
| 
 | ||||
| vars: | ||||
|   NAME: code.jhot.me/jhot/docker-s3-backup | ||||
| 
 | ||||
| tasks: | ||||
|   default: | ||||
|     vars: | ||||
|       TAG: latest | ||||
|   build: | ||||
|     cmds: | ||||
|       - docker buildx build -t {{.NAME}}:{{.TAG}} . | ||||
|     vars: | ||||
|       NAME: docker-s3-backup | ||||
|       TAG: latest | ||||
|       - docker buildx build --platform linux/amd64,linux/arm64 -t "{{.NAME}}:{{.TAG}}" . | ||||
|   push: | ||||
|     cmds: | ||||
|       - docker push "{{.NAME}}:{{.TAG}}" | ||||
|   tag: | ||||
|     prompt: This will push a git tag and docker image versioned {{.TAG}}... Do you want to continue? | ||||
|     cmds: | ||||
|       - task: build | ||||
|         vars: | ||||
|           NAME: "{{.NAME}}" | ||||
|       - task: push | ||||
|         vars: | ||||
|           NAME: "{{.NAME}}" | ||||
|       - git tag "{{.TAG}}" | ||||
|       - git push origin "{{.TAG}}" | ||||
|  |  | |||
							
								
								
									
										2
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										2
									
								
								go.mod
								
								
								
								
							|  | @ -1,6 +1,6 @@ | |||
| module code.jhot.me/jhot/docker-s3-backup | ||||
| 
 | ||||
| go 1.20 | ||||
| go 1.21 | ||||
| 
 | ||||
| require ( | ||||
| 	github.com/go-co-op/gocron v1.33.1 | ||||
|  |  | |||
|  | @ -10,29 +10,50 @@ import ( | |||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	MinioClient *minio.Client | ||||
| 	MinioClient   *minio.Client | ||||
| 	backupBuckets = []string{} | ||||
| 	backupRoot    string | ||||
| 	s3Host        string | ||||
| 	s3Secure      bool | ||||
| 	s3Region      string | ||||
| 	s3User        string | ||||
| 	s3Pass        string | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	for _, bucket := range strings.Split(GetEnvWithDefault("BUCKET_NAMES", ""), ",") { | ||||
| 		backupBuckets = append(backupBuckets, strings.TrimSpace(bucket)) | ||||
| 	} | ||||
| 	backupRoot = GetEnvWithDefault("BACKUP_ROOT", "/backup") | ||||
| 	s3Host = GetEnvWithDefault("S3_HOST", "localhost:9000") | ||||
| 	s3Secure = GetEnvWithDefault("S3_USE_SSL", "") == "true" | ||||
| 	s3Region = GetEnvWithDefault("S3_REGION", "us-east-1") | ||||
| 	s3User = GetEnvWithDefault("S3_ACCESS_KEY_ID", "") | ||||
| 	s3Pass = GetEnvWithDefault("S3_ACCESS_KEY_SECRET", "") | ||||
| } | ||||
| 
 | ||||
| func Backup(ctx context.Context) error { | ||||
| 	logger.Info("Starting backup") | ||||
| 	var err error | ||||
| 	var getErrors = []string{} | ||||
| 	bucketNames := GetEnvWithDefault("BUCKET_NAMES", "") | ||||
| 	backupRoot := GetEnvWithDefault("BACKUP_ROOT", "/backup") | ||||
| 
 | ||||
| 	MinioClient, err = minio.New(GetEnvWithDefault("S3_HOST", "localhost"), &minio.Options{ | ||||
| 		Creds:  credentials.NewStaticV4(GetEnvWithDefault("S3_ACCESS_KEY_ID", ""), GetEnvWithDefault("S3_ACCESS_KEY_SECRET", ""), ""), | ||||
| 		Secure: GetEnvWithDefault("S3_USE_SSL", "") == "true", | ||||
| 		Region: GetEnvWithDefault("S3_REGION", "us-east-1"), | ||||
| 	MinioClient, err = minio.New(s3Host, &minio.Options{ | ||||
| 		Creds:  credentials.NewStaticV4(s3User, s3Pass, ""), | ||||
| 		Secure: s3Secure, | ||||
| 		Region: s3Region, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		logger.Error("Error connecting to S3", "error", err) | ||||
| 		return err | ||||
| 	} | ||||
| 	logger.Debug("Connected to S3", "host", s3Host) | ||||
| 
 | ||||
| 	for _, bucket := range strings.Split(bucketNames, ",") { | ||||
| 		bucket = strings.TrimSpace(bucket) | ||||
| 	for _, bucket := range backupBuckets { | ||||
| 		logger.Debug("Backing up bucket", "bucket", bucket) | ||||
| 		for object := range MinioClient.ListObjects(ctx, bucket, minio.ListObjectsOptions{Recursive: true}) { | ||||
| 			getError := MinioClient.FGetObject(ctx, bucket, object.Key, fmt.Sprintf("%s/%s/%s", backupRoot, bucket, object.Key), minio.GetObjectOptions{}) | ||||
| 			if getError != nil { | ||||
| 				logger.Error("Error getting object", "bucket", bucket, "error", getError) | ||||
| 				getErrors = append(getErrors, getError.Error()) | ||||
| 			} | ||||
| 		} | ||||
|  |  | |||
|  | @ -0,0 +1,14 @@ | |||
| package internal | ||||
| 
 | ||||
| import ( | ||||
| 	"log/slog" | ||||
| 	"os" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	logger *slog.Logger | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})) | ||||
| } | ||||
|  | @ -12,12 +12,14 @@ var ( | |||
| ) | ||||
| 
 | ||||
| func StartSchedule(ctx context.Context) error { | ||||
| 	logger.Info("Starting schedule") | ||||
| 	cronExpression := GetEnvWithDefault("SCHEDULE_CRON", "0 0 * * *") | ||||
| 	scheduler = gocron.NewScheduler(time.Local) | ||||
| 	_, err := scheduler.Cron(cronExpression).Do(Backup, ctx) | ||||
| 	job, err := scheduler.Cron(cronExpression).Do(Backup, ctx) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	logger.Debug("Next scheduled backup", "time", job.NextRun()) | ||||
| 	scheduler.StartBlocking() | ||||
| 	return nil | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue