Self-hosted service
Clivern/Walrus avatar
Clivern/Walrus

Walrus splits backup into a tower you log into and an agent that runs on the host

🔥 Fast, Secure and Reliable System Backup, Set up in Minutes.

546 stars25 forksGoMIT

At a glance

What is it?
Walrus is a Go backup service that pushes dumps of SQLite, MySQL, PostgreSQL, Redis, etcd or whole directories into S3-compatible storage, and its architecture is a central tower plus a per-host agent. It suits an operator who wants a dashboard and scheduled backups with restore in reach, and it asks you to run etcd, a systemd service and a static API key.
Who is it for?
Walrus is a reasonable fit for an operator who wants backups of several databases and directories pushed to S3, DigitalOcean Spaces or MinIO with a dashboard to see them, because the tower and agent split keeps the credentials and the scheduling in one place while the agent runs where the data lives. It is a poor fit for a single laptop or a one-off job, because the setup asks for etcd, a systemd unit and a matched API key on both sides.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two binaries: the tower holds the schedule, the agent holds the data

Walrus is not a single process that runs next to your database. It ships as two commands with separate configuration files and separate systemd services. The tower is the control plane: it runs an HTTP API, serves a dashboard on its own port, and owns the backup settings for everything it manages. The agent is the data plane: it runs on the host where the databases and directories live, reports back to the tower, and performs the work. The agent config points at the tower with a URL, an `apiKey` and an `encryptionKey` that the comments say must match the ones in the tower config file, and it also carries a `pingInterval` used for the time between agent ping checks, defaulting to 60 seconds. The tower config in turn carries an API key and an encryption key of its own, along with the database, metrics and logging settings. This split is the whole deployment model, and it is what lets one dashboard show backups for a dozen hosts without any host being directly reachable from the tower.

The tower config is a YAML file of environment variable defaults

Every setting in the tower configuration is written as a shell-style default with an environment variable override, which makes the same file work in a container and on a developer laptop. The relevant block looks like this:

yaml
    # API Configs
    api:
        key: ${WALRUS_API_KEY:-6c68b836-6f8e-465e-b59f-89c1db53afca}
        encryptionKey: ${WALRUS_ENCRYPTION_KEY:-B?E(H+Mb}

Those two defaults are shipped in the file, and the documentation asks you to update the `apiKey` and the `encryptionKey` to different random values before running anything. The port, the URL, the TLS status and the PEM and key paths are all configured the same way, with the TLS block defaulting to off and pointing at `cert/server.pem` and `cert/server.key` when it is turned on. The rest of the file covers the async workers, where a queue buffer of 5000 and four concurrent workers are the defaults, the Prometheus metrics endpoint, which defaults to the `/metrics` route, and the log settings, where the level defaults to info, the output to stdout and the format to json. The agent config uses the identical pattern with a different default port, 8001, and a different URL.

etcd is the application database, and it is not optional

The tower keeps its state in etcd, and the database block in the config makes that explicit with a driver field that defaults to etcd, a database name or prefix of `walrus`, an optional username and password, and a list of endpoints pointing at `http://127.0.0.1:2379` with a 30 second timeout. The deployment instructions say to install an etcd cluster or a single node and refer you to the etcd docs or to the bin directory inside the repository. That is a real operational cost, and it is worth being clear about it: Walrus is not a single binary that you drop next to your application and forget. It wants a key-value store, and the Go module pulls in the etcd v3 client explicitly. The upside is that etcd is a component most infrastructure teams already run, that the state is small, and that the client library handles failover across the configured endpoints. The downside is a three-part system, tower, agent and etcd, where each part is a thing that can be down at three in the morning.

The agent needs a matching key pair and a ping interval to stay registered

The agent's job is to reach the tower and be reachable in return. Its config block points at the tower URL with a default of `http://127.0.0.1:8000` and supplies the two shared secrets, with the source comments repeating that the `apiKey` and the `encryptionKey` must match the tower config file. That is the one piece of configuration most likely to break a first install, because a mismatch produces an agent that never appears in the dashboard and gives the operator nothing to work with. The `pingInterval` defaults to 60 seconds and is described as the time interval between agent ping checks, which is how the tower knows an agent is alive. The backup settings block on the agent is where the temporary directory is configured, defaulting to `/tmp`, and that is where dumps are staged before they are pushed. The agent also has the same TLS, worker and logging blocks as the tower, so an operator can turn on TLS for the agent-to-tower link in the same way as for the public API.

Installation is a curl into the GitHub releases and a systemd unit

The deployment path is short enough to follow without surprises. The documentation points at the latest release binary and suggests making it executable from everywhere. The download is scripted:

bash
$ export WALRUS_LATEST_VERSION=$(curl --silent "https://api.github.com/repos/Clivern/Walrus/releases/latest" | jq '.tag_name' | sed -E 's/.*"([^"]+)".*/\1/' | tr -d v)

That resolves the newest tag through the GitHub API and strips the leading v. The archive is then fetched and unpacked:

bash
$ curl -sL https://github.com/Clivern/Walrus/releases/download/v{$WALRUS_LATEST_VERSION}/walrus_{$WALRUS_LATEST_VERSION}_Linux_x86_64.tar.gz | tar xz

After that, the two services are started with the config file each one needs:

bash
walrus tower -c /path/to/tower.config.yml
bash
walrus agent -c /path/to/agent.config.yml

The documentation then tells you to open the tower dashboard at `http://127.0.0.1:8000` and start the setup from there. The command names match the cobra command tree in the Go module, and the config path is given with `-c`. Note the naming quirk: the repository is `Clivern/Walrus` on GitHub while the Go module is `github.com/clivern/walrus` in lowercase, and the download URL in the instructions uses the capitalised form.

The container image pins an older version than the release page

There is a Dockerfile at the root and it is worth reading before you build it. The base is `golang:1.21.3-alpine`, and the image then downloads a prebuilt release tarball instead of compiling from source and deletes the curl package it used. The version it downloads is a build argument:

dockerfile
ARG WALRUS_VERSION=1.2.4

That default is two patch releases behind the current tag, so an image built without overriding the argument ships an older Walrus than the release page advertises. The image creates `/app/configs`, `/app/var/logs` and `/app/var/storage`, declares `/app/configs` and `/app/var` as volumes, and exposes port 8000, which is the tower's port. The default command starts the tower with the distributed config:

dockerfile
CMD ["./walrus", "tower", "-c", "/app/configs/config.dist.yml"]

Shipping `config.dist.yml` as the live configuration is worth noticing, because that is the file containing the placeholder API key and encryption key the documentation tells you to replace. An operator who runs the image without mounting a modified config over `/app/configs` is running with the published defaults.

The Makefile enforces a licence header and a formatted tree

The project's own quality gates are visible in the Makefile, and two of them are unusual. The `check_license` target walks every Go file outside vendor, takes the first three lines, and fails unless they match a pattern for Copyright or generated code, which means a missing licence header is a build failure rather than a review comment. The `style` target runs gofmt in diff mode over the same file set and fails with a message telling you to use your current Go version for formatting. The test targets come in three forms: `test_short` runs the packages with the short flag, `test` runs them with the unit tag and coverage enabled, and `integration` is documented as requiring etcd, which is consistent with etcd being the tower's database. There is also an `install_revive` target that installs the revive linter at its latest version. The Go module pins a recent set of dependencies, including the AWS SDK, gin for the HTTP layer, cobra and viper for the command line and configuration, logrus for logging, the Prometheus client, the etcd v3 client, and crypto.

What Walrus does not tell you, and what a plain cron job already does

The honest limitations are in what the documentation leaves out. There is no restore procedure here. The described flow ends at the dashboard, with the tower scheduling backups and the agent pushing them, and nothing in the visible documentation explains how a dump gets turned back into a working database, what a restore does to a live schema, or how integrity is verified on the way out. For a backup product, that is the gap that matters, and it is worth asking the maintainers before trusting a schedule. The other gap is the alternative. A plain cron job that runs mysqldump or pg_dump into an S3 bucket with a lifecycle rule does the same job with no tower, no agent, no etcd, no dashboard and no encryption key to rotate. The difference in approach is that Walrus centralises: one place to see every host's backup state, one place to change the schedule, and a consistent encryption key across destinations. The cost is a three-process system and a shared secret to manage. For a single host with a single database, the cron job is the smaller and more verifiable answer. Walrus earns its complexity when the number of hosts and destinations makes a central view worth having.

Editorial conclusion

Walrus is a reasonable fit for an operator who wants backups of several databases and directories pushed to S3, DigitalOcean Spaces or MinIO with a dashboard to see them, because the tower and agent split keeps the credentials and the scheduling in one place while the agent runs where the data lives. It is a poor fit for a single laptop or a one-off job, because the setup asks for etcd, a systemd unit and a matched API key on both sides. It is also a poor fit if you need to know the restore procedure works before you need it, since the documentation here covers deployment and the dashboard but says nothing about the restore path. Before deploying, read the tower config for the `encryptionKey` and `apiKey` defaults and change them, as the documentation instructs, and note that the last push to the repository was on 2026-10-22 while the most recent tagged release is v1.2.6 from 2024-01-31, so the binary you get from the release page and the code on the main branch are not the same thing.

Frequently asked questions

What is the difference between the Walrus tower and the Walrus agent?

The tower is the control plane: it runs the HTTP API, serves the dashboard, owns the schedule and the encryption key, and keeps its state in etcd. The agent runs on each host where the data lives, performs the backup work, pings the tower on the configured interval, and shares the tower's API key and encryption key.

How do I install Walrus?

Download the latest release binary from the GitHub releases page, install etcd as a cluster or single node, create tower.config.yml and agent.config.yml from config.dist.yml, and run the two services with walrus tower -c and walrus agent -c. The dashboard is then reachable at http://127.0.0.1:8000.

Which storage backends does Walrus support?

The documentation states that it supports AWS S3, DigitalOcean Spaces and any S3-compatible object storage service, with topics in the repository also referring to MinIO. The Go module depends on the AWS SDK for the object storage calls.

Does the Walrus container image run the current release?

Not by default. The Dockerfile sets ARG WALRUS_VERSION=1.2.4 and downloads that specific release tarball, so an image built without overriding the argument runs an older version than the latest tag. It also copies config.dist.yml into the image and uses it as the default tower configuration.

Official sources

  1. Clivern/Walrus on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/clivern-walrus.svg)](https://hysenlabs.com/projects/clivern-walrus)

Was this useful?