Buttervolume
BTRFS Volume plugin for Docker
Install / Use
/learn @ccomb/ButtervolumeREADME
.. image:: https://travis-ci.org/ccomb/buttervolume.svg?branch=master :target: https://travis-ci.org/ccomb/buttervolume :alt: Travis state
BTRFS Volume plugin for Docker
What will Buttervolume allow you to do?
- Quickly recover recent data after an exploit or failure of your web sites or applications
- Quickly rollback your data to a previous version after a failed upgrade
- Implement automatic upgrade of your applications without fear
- Keep an history of your data
- Make many backups without consuming more disk space than needed
- Build a resilient hosting cluster with data replication
- Quickly move your applications between nodes
- Create preconfigured or templated applications to deploy in seconds
What can Buttervolume do?
- Snapshot your Docker volumes
- Restore a snapshot to its original volume or under a new volume
- List and remove existing snapshots of your volumes
- Clone your Docker volumes
- Replicate or Sync your volumes to another host
- Run periodic snapshots, sync or replication of your volumes
- Remove your old snapshots periodically
- Pause or resume the periodic jobs, either individually or globally
How does it work?
Buttervolume is a Docker Volume Plugin that stores each Docker volume as a BTRFS subvolume.
.. contents::
Introduction
BTRFS <https://btrfs.wiki.kernel.org/>_ is a next-generation copy-on-write
filesystem with subvolume and snapshot support. A BTRFS subvolume <https://btrfs.wiki.kernel.org/index.php/SysadminGuide#Subvolumes>_ can be
seen as an independant file namespace that can live in a directory and can be
mounted as a filesystem and snapshotted individually.
On the other hand, Docker volumes <https://docs.docker.com/storage/volumes/>_ are commonly used
to store persistent data of stateful containers, such as a MySQL/PostgreSQL
database or an upload directory of a CMS. By default, Docker volumes are just
local directories in the host filesystem. A number of Volume plugins <https://docs.docker.com/engine/extend/legacy_plugins/#/volume-plugins>_
already exist for various storage backends, including distributed filesystems,
but small clusters often can't afford to deploy a distributed filesystem.
We believe BTRFS subvolumes are a powerful and lightweight storage solution for Docker volumes, allowing fast and easy replication (and backup) across several nodes of a small cluster.
Prerequisites
Make sure the directory /var/lib/buttervolume/ is living in a BTRFS
filesystem. It can be a BTRFS mountpoint or a BTRFS subvolume or both.
Initial Setup
Use the buttervolume init command to easily set up the BTRFS environment::
# Default setup - checks /var/lib/buttervolume is on BTRFS and creates required directories
sudo buttervolume init
# Custom BTRFS path - uses existing BTRFS filesystem at specified path
sudo buttervolume init --path /custom/btrfs/path
# Image file - creates a new BTRFS image file
sudo buttervolume init --file /var/lib/docker/btrfs.img --size 20G
The init command must be run as root and automatically creates the required directory structure (config, ssh, volumes, snapshots).
Manual Setup (Alternative)
If you prefer manual setup, create the directories for the config and ssh on the host::
sudo mkdir /var/lib/buttervolume
sudo mkdir /var/lib/buttervolume/config
sudo mkdir /var/lib/buttervolume/ssh
Build and run as a contributor
If you want to be a contributor, read this chapter. Otherwise jump to the next section.
You first need to create a root filesystem for the plugin, using the provided Dockerfile::
git clone https://github.com/ccomb/buttervolume
./build.sh
By default the plugin is built for the latest commit (HEAD). You can build another version by specifying it like this::
./build.sh 3.7
At this point, you can set the SSH_PORT option for the plugin by running::
docker plugin set ccomb/buttervolume SSH_PORT=1122
Note that this option is only relevant if you use the replication feature between two nodes.
Now you can enable the plugin, which should start buttervolume in the plugin container::
docker plugin enable ccomb/buttervolume:HEAD
You can check it is responding by running a buttervolume command using aliases::
export RUNCROOT=/run/docker/runtime-runc/plugins.moby/ # or /run/docker/plugins/runtime-root/plugins.moby/
alias drunc="sudo runc --root $RUNCROOT"
alias buttervolume="drunc exec -t $(drunc list|tail -n+2|awk '{print $1}') buttervolume"
buttervolume scheduled
Increase the log level by writing a /var/lib/buttervolume/config/config.ini file with::
[DEFAULT]
TIMER = 120
Then check the logs with::
sudo journalctl -f -u docker.service
You can also locally install and run the plugin in the foreground with::
uv venv
uv sync --extra dev
sudo .venv/bin/buttervolume run
Then you can use the buttervolume CLI that was installed in developer mode in the venv::
.venv/bin/buttervolume --version
Install and run as a user
If the plugin is already pushed to the image repository, you can install it with::
docker plugin install ccomb/buttervolume
Check it is running::
docker plugin ls
Find your runc root, then define useful aliases or functions.
Option 1: Using aliases (quick setup)::
export RUNCROOT=/run/docker/runtime-runc/plugins.moby/ # or /run/docker/plugins/runtime-root/plugins.moby/
alias drunc="sudo runc --root $RUNCROOT"
alias buttervolume="drunc exec -t $(drunc list|tail -n+2|awk '{print $1}') buttervolume"
Option 2: Using functions (recommended for .bash_profile)::
function drunc () {
RUNCROOT=/run/docker/runtime-runc/plugins.moby/ # or /run/docker/plugins/runtime-root/plugins.moby/
sudo runc --root $RUNCROOT $@
}
function buttervolume () {
drunc exec -t $(docker plugin ls --no-trunc | grep 'ccomb/buttervolume:latest' | awk '{print $1}') buttervolume $@
}
And try a buttervolume command::
buttervolume scheduled
Or create a volume with the driver. Note that the name of the driver is the name of the plugin::
docker volume create -d ccomb/buttervolume:latest myvolume
Upgrade
You must force disable it before reinstalling it (as explained in the docker documentation)::
docker plugin disable -f ccomb/buttervolume
docker plugin rm -f ccomb/buttervolume
docker plugin install ccomb/buttervolume
Using buttervolume CLI in a container
If you need to run the buttervolume CLI from within a Docker container, you need to ensure proper access to the Docker daemon and plugin sockets.
Method 1: Mount required directories::
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /run/docker/plugins:/run/docker/plugins \
your-container-with-buttervolume buttervolume scheduled
Method 2: Override socket path::
# If you know the exact socket path
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /run/docker/plugins:/run/docker/plugins \
-e BUTTERVOLUME_SOCKET=/run/docker/plugins/<plugin-id>/btrfs.sock \
your-container-with-buttervolume buttervolume scheduled
Creating a CLI container::
# Dockerfile
FROM python:alpine
RUN pip install buttervolume
COPY --from=docker /usr/local/bin/docker /usr/local/bin/docker
# Usage
docker build -t buttervolume-cli .
docker run --rm -it \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /run/docker/plugins:/run/docker/plugins \
buttervolume-cli buttervolume scheduled
Migrating existing Docker volumes
To migrate existing Docker volumes to buttervolume, the approach depends on whether your volumes are already on a BTRFS filesystem.
If /var/lib/docker/volumes is on the same BTRFS partition as /var/lib/buttervolume:
You can efficiently move or snapshot existing volumes::
# Stop containers using the volumes first
docker stop <container-using-volume>
# Method 1: Move the volume (fastest)
sudo mv /var/lib/docker/volumes/<volume-name>/_data /var/lib/buttervolume/volumes/<volume-name>
# Method 2: Create BTRFS snapshot (preserves original)
sudo btrfs subvolume snapshot /var/lib/docker/volumes/<volume-name>/_data /var/lib/buttervolume/volumes/<volume-name>
If /var/lib/docker/volumes is NOT on BTRFS:
You need to copy the data::
# Stop containers using the volumes first
docker stop <container-using-volume>
# Create buttervolume and copy data
docker volume create -d ccomb/buttervolume:latest <volume-name>
sudo cp -ar /var/lib/docker/volumes/<volume-name>/_data/* /var/lib/buttervolume/volumes/<volume-name>/
# Remove old volume after verifying data integrity
docker volume rm <volume-name>
Update your containers:
After migration, update your containers to use the new buttervolume driver::
# In docker-compose.yml
volumes:
my-data:
driver: ccomb/buttervolume:latest
# Or with docker run
docker run -v my-data:/data --volume-driver=ccomb/buttervolume:latest myimage
Verification:
Test that your migrated volumes work correctly before removing the originals::
# Check volume exists
docker volume ls -f driver=ccomb/buttervolume:latest
# Test with a temporary container
docker run --rm -v <volume-name>:/test --volume-driver=ccomb/buttervolume:latest alpine ls -la /test
Configure
You can configure the following variables:
* ``DRIVERNAME``: the full name of the driver (with the tag)
* ``VOLUMES_PATH``: the path where the BTRFS volumes are located
* ``SNAPSHOTS_PATH``: the path where the BTRFS snapshots are located
* ``TEST_REMOTE_PATH``: the path during
Related Skills
node-connect
347.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
prose
347.2kOpenProse VM skill pack. Activate on any `prose` command, .prose files, or OpenProse mentions; orchestrates multi-agent workflows.
frontend-design
108.0kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
347.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
