skip to content

Garage (S3)

Table of Contents

FreeBSD (via Linux Docker)

sudo pkg install -y podman-suite
sudo zfs create -o mountpoint=/var/db/containers zroot/containers
sudo sysctl net.pf.filter_local=1 # makes pf process packets that originate _and_ stay on the local machine
sudo pfilctl link -o pf:default-out inet-local # links pf's outbound ruleset to hook for packets generated by the local host, so pf actually processes host-originated packets — not just forwarded ones
printf 'sysctl net.pf.filter_local=1\npfilctl link -o pf:default-out inet-local\n' | sudo tee -a /etc/rc.local # to preserve that
sudo sysrc linux_enable=YES
sudo service linux enable && sudo service linux start
# Podman & Linux setup
# sudo sysrc podman_enable=YES # optional, depends on the setup
sudo tee -a /etc/fstab << 'EOF'
fdesc /dev/fd fdescfs rw 0 0
EOF
sudo mount -a
mount | grep fdescfs | wc -l
# ZFS for Garage
sudo zfs set quota=10T reservation=5T tank/s3-garage # set limits as required
sudo zfs create tank/s3-garage
sudo zfs create tank/s3-garage/meta
sudo zfs create tank/s3-garage/data
sudo zfs set compression=lz4 tank/s3-garage/data
sudo zfs set compression=lz4 tank/s3-garage/meta
sudo zfs set atime=off tank/s3-garage/data
# Garage setup now
sudo tee /tank/s3-garage/garage.toml << 'EOF'
metadata_dir = "/tank/garage/meta"
data_dir = "/tank/garage/data"
db_engine = "sqlite"
metadata_auto_snapshot_interval = "6h"
replication_factor = 1 # replicate across nodes
compression=lz4
rpc_bind_addr = "127.0.0.1:3901"
rpc_public_addr = "127.0.0.1:3901"
rpc_secret = "<generated-rpc-secret>" # openssl rand -hex 32
[s3_api]
s3_region = "garage"
api_bind_addr = "127.0.0.1:3900"
root_domain = ".s3.garage"
EOF
sudo tee /tank/s3-garage/docker-compose.yml << 'EOF'
services:
s3-garage:
image: dxflrs/garage:v2.2.0
container_name: s3-garage
restart: unless-stopped
volumes:
- ./garage.toml:/tank/s3-garage/garage.toml
- /tank/garage/meta:/var/lib/garage/meta
- /tank/garage/data:/var/lib/garage/data
expose:
- "3900" # S3 API
- "3901" # Admin API
- "3903" # Metrics/Admin HTTP
ports:
- "127.0.0.1:3900:3900"
EOF

To start it:

cd /tank/s3-garage && sudo podman compose up -d

reverse proxy (haproxy)

==> follow the instructions inside FreeBSD bare metal

Linux

Ref

# Linux
alias garage="docker exec -ti s3-garage /garage"
# or
# FreeBSD
alias garage="sudo podman exec -ti s3-garage /garage"
garage status
garage layout assign -z dc1 -c 10T 679316a0bafde61b # 10Tb on node_id from the status
garage layout show # that gives the version to apply for the next command
garage layout apply --version 1
garage status # shall demonstrate zone, capacity, etc
garage bucket list
garage bucket create app-uploads
garage bucket info app-uploads
garage key create app-uploads-key
garage key list
garage key info app-uploads-key
garage bucket allow --read --write --owner app-uploads --key app-uploads-key
garage bucket info app-uploads

here is the rclone’s config file (key & access keys are not encrypted):

[s3_storage]
type = s3
provider = Other
access_key_id = ...
secret_access_key = ...
endpoint = https://s3.example.com/
region = garage
acl = private
bucket_acl = private

Create new user

user="app-user"
bucket="app-backups"
garage key create "${user}-key"
garage bucket allow --read --write --owner "$bucket" --key "${user}-key"
garage bucket info "$bucket"

Create new bucket

bucket="app-uploads"
garage bucket create "$bucket"