Restore Coolify storage safely after an incident.
Preview the change first. Apply it only with explicit confirmation.
coolrestore restores gzip-compressed tar archives created from Coolify storage and stored in S3-compatible storage such as RustFS. It supports local archive files and S3 objects, merge restores, replace restores, isolated staging, and atomic replace rollback.
The archive is validated and staged before anything is written to the target. By default, coolrestore only produces a plan.
Download the release binary for the target server:
coolrestore-linux-amd64
coolrestore-linux-arm64
Install it as coolrestore somewhere on the server's PATH:
install -m 0755 coolrestore-linux-amd64 /usr/local/bin/coolrestoreVerify the binary:
file /usr/local/bin/coolrestoreRelease binaries are statically built for Linux amd64 and arm64.
For development or local builds:
go install github.com/replworks/coolrestore/cmd/coolrestore@latestS3-compatible access uses the AWS SDK environment variables:
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=...
export AWS_ENDPOINT_URL=https://rustfs.example.com
export AWS_S3_FORCE_PATH_STYLE=trueIf these variables are not set, the AWS SDK default credential chain is used. Credentials are never accepted as command-line flags.
coolrestore does not create or require a persistent configuration file.
For repeated restores, use the wrapper examples in examples/ with a protected environment file instead of manually exporting credentials for each command:
install -m 600 examples/coolrestore.env.example /etc/coolrestore/env
export COOLRESTORE_ENV_FILE=/etc/coolrestore/envReplace the placeholder values before use. The release also includes the examples as coolrestore-examples.tar.gz for operators who only download the binary. For a user-specific setup, use ~/.config/coolrestore/env instead.
Preview a local archive. Preview is the default and does not modify the target directory:
coolrestore \
--source /backups/coolify-storage.tar.gz \
--target /var/lib/coolify/storageUse an S3-compatible object as the source:
coolrestore \
--source s3://coolify-backups/storage/2026-09-26.tar.gz \
--target /var/lib/coolify/storageApply a merge restore explicitly:
coolrestore \
--source s3://coolify-backups/storage/2026-09-26.tar.gz \
--target /var/lib/coolify/storage \
--mode merge \
--confirmReplace the target with the archive contents:
coolrestore \
--source s3://coolify-backups/storage/2026-09-26.tar.gz \
--target /var/lib/coolify/storage \
--mode replace \
--confirmUse a specific staging base when required:
coolrestore \
--source /backups/coolify-storage.tar.gz \
--target /var/lib/coolify/storage \
--staging /var/lib/coolify/restore-stagingOptional integrity override:
coolrestore \
--source /backups/coolify-storage.tar.gz \
--target /var/lib/coolify/storage \
--skip-checksum--mode replace requires --confirm. The target must be an absolute path and must not be a protected system directory or a final symbolic link.
Merge mode adds files that are missing from the target and overwrites files with the same path. Files that exist only in the target are preserved.
Replace mode makes the target contain exactly the archive's staged contents. The target and staging location must be on the same filesystem so the change can use atomic directory renames and rollback.
source: s3://coolify-backups/storage/2026-09-26.tar.gz
target: /var/lib/coolify/storage
mode: merge
outcome: planned
regular_files: 2
added:
uploads/avatar.png
overwritten:
config/app.php
source: s3://coolify-backups/storage/2026-09-26.tar.gz
target: /var/lib/coolify/storage
mode: merge
outcome: restored
regular_files: 2
source: s3://coolify-backups/storage/2026-09-26.tar.gz
target: /var/lib/coolify/storage
mode: merge
outcome: failed
step: change application
target_state: may contain partial changes
The process exits with 0 for a successful preview or restore and a non-zero status for failures.
coolrestore is designed for infrastructure recovery, not application-level validation.
- Archive paths are checked for traversal and absolute paths.
- Symlinks, hard links, and unsupported archive entry types are rejected.
- Archive contents are extracted into an isolated staging directory first.
- Staging and target paths may not overlap.
- A target lock prevents concurrent restores against the same directory.
- Merge failures clean temporary artifacts but may retain changes already applied.
- Replace failures restore the previous target directory through atomic rename rollback.
The backup archive produced by Coolify is treated as an input object. This tool does not create or require a SHA256 manifest for that archive. SHA256 files attached to GitHub Releases, when present, verify the downloaded coolrestore binary itself.
Verify:
AWS_ACCESS_KEY_IDandAWS_SECRET_ACCESS_KEYAWS_REGIONAWS_ENDPOINT_URLfor RustFS or another S3-compatible serviceAWS_S3_FORCE_PATH_STYLE=truewhen required by the endpoint- bucket and object-key permissions
If credentials cannot be loaded, coolrestore prints a short wrapper hint. It never prints credential values. The default system-wide environment file is /etc/coolrestore/env; COOLRESTORE_ENV_FILE can point to another protected file.
Replace mode requires explicit authorization:
--mode replace --confirmIt also requires staging and target to be on the same filesystem.
This is expected. Omit --confirm to inspect a plan without changing the target. A missing target directory is not created during preview.
Check the failure report for the archive entry and reason. Unsafe archives are rejected before any content is applied to the target.
Run tests:
go test ./...Run static checks:
go vet ./...
git diff --checkBuild the local binary:
go build ./cmd/coolrestoreBuild release targets:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o coolrestore-linux-amd64 ./cmd/coolrestore
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o coolrestore-linux-arm64 ./cmd/coolrestoreSee the repository license before distributing the tool.
Built for safe Coolify storage recovery after an incident.