Table of Contents
seaweed-up ships a cluster plan command that turns a host inventory into the cluster.yaml that cluster deploy consumes. Instead of hand-writing the topology and chasing per-host disk paths and ports, you list hosts and the roles each one runs; plan SSHes to each box, discovers its hardware, and synthesizes a reviewable spec.
This page walks through the workflow end to end. For the inventory schema in detail see Cluster Plan Inventory Reference; for ongoing operations see Cluster Plan Day 2 Operations.
Contents
- Mental model
- 1. Write inventory.yaml
- 2. Probe (optional, dry information-gathering)
- 3. Synthesize cluster.yaml
- 4. Preview before applying changes
- 5. Deploy
- 6. Day-2: grow the cluster
- 7. Day-2: a host's hardware changed
- Escape hatches
Mental model
| Phase | Verb | Mutates? | Use when |
|---|---|---|---|
| 1 | plan --json |
nothing | sanity-checking SSH/probe |
| 2 | plan -o cluster.yaml (greenfield) |
creates files | first time |
| 3 | plan -o cluster.yaml (re-run) |
append-merge | adding hosts |
| 4 | plan --dry-run |
nothing | preview any of the above |
| 4 | plan --refresh-host=<ip> |
swaps one entry | drift remediation |
| — | deploy -f cluster.yaml |
the cluster | apply the spec |
The pattern: inventory is your source of truth; cluster.yaml is a reviewable intermediate; deploy only acts on cluster.yaml.
1. Write inventory.yaml
The inventory is the only file you author by hand. It lists hosts, the roles each one runs, and SSH connection details. Everything else (disk layout, ports, max counts) is discovered or defaulted.
defaults:
ssh:
user: root
port: 22
identity: ~/.ssh/id_rsa
hosts:
- ip: 10.0.0.11
roles: [master]
- ip: 10.0.0.12
roles: [master]
- ip: 10.0.0.13
roles: [master, filer]
- ip: 10.0.0.21
roles: [volume]
labels: {zone: us-east-1a, rack: r1}
- ip: 10.0.0.22
roles: [volume]
Recognized roles: master, volume, filer, s3, sftp, admin, worker, envoy, external. A host can carry multiple roles; plan emits one entry per role into the corresponding *_servers section. Per-host ssh: and labels: override the inventory defaults. See Cluster Plan Inventory Reference for every field.
2. Probe (optional, dry information-gathering)
seaweed-up cluster plan -i inventory.yaml --json > facts.json
Read-only on every target. Useful for sanity-checking that SSH works and seeing what disks the planner sees on each host before you let it write anything.
3. Synthesize cluster.yaml
seaweed-up cluster plan -i inventory.yaml -o cluster.yaml \
--filer-backend-file /etc/seaweed-up/filer.dsn
plan SSHes to each host, generates a cluster.yaml (the file cluster deploy consumes), and writes two sidecars next to it:
cluster.facts.json— the raw probe output (audit + drift baseline for the next run)cluster.deploy-disks.json— the per-host allowlist of disksdeployis permitted to mkfs+mount
The generated cluster.yaml carries a header comment marking it plan-generated and is safe to hand-edit. You'll want to review it before the first deploy.
Filer backend
If your filer needs an external metadata store (Postgres, MySQL, Redis…), pass the DSN with one of:
# 1. file (recommended: avoids leaking the password via `ps`)
seaweed-up cluster plan -i inventory.yaml -o cluster.yaml \
--filer-backend-file /etc/seaweed-up/filer.dsn
# 2. direct CLI flag
seaweed-up cluster plan -i inventory.yaml -o cluster.yaml \
--filer-backend 'postgres://seaweed:CHANGE_ME@10.0.0.41:5432/seaweedfs?sslmode=disable'
# 3. environment variable (good for CI)
SEAWEEDUP_FILER_BACKEND='postgres://seaweed:s3cret@10.0.0.41/seaweedfs' \
seaweed-up cluster plan -i inventory.yaml -o cluster.yaml
Precedence is file > flag > env. You can also reference a tagged inventory host symbolically — see Cluster Plan Inventory Reference's tag section.
4. Preview before applying changes
seaweed-up cluster plan -i inventory.yaml -o cluster.yaml --dry-run
Prints a unified diff of what the next plan run would write, without touching anything on disk. This is the safe review step before any rewrite. Sidecars are summarized but not written.
5. Deploy
seaweed-up cluster deploy -f cluster.yaml
Reads cluster.yaml plus the deploy-disks.json sidecar (fail-closed: if the sidecar is missing on a plan-generated spec, deploy refuses rather than scanning every disk). Brings up systemd units, mounts disks, configures filer/admin/etc.
6. Day-2: grow the cluster
Add a host to inventory.yaml:
- ip: 10.0.0.23
roles: [volume]
Re-run plan:
seaweed-up cluster plan -i inventory.yaml -o cluster.yaml
The default behavior when -o already exists is append-merge — every existing entry stays byte-identical (your hand edits, your inline comments, your key ordering survive), and the new 10.0.0.23 row gets appended to volume_servers. Then cluster deploy -f cluster.yaml again.
7. Day-2: a host's hardware changed
You added a disk to 10.0.0.21. Run plan and you'll see:
WARN: drift on 10.0.0.21:22 (since previous facts.json): added /dev/sdc
plan compared the new probe against the previous run's facts.json and noticed the disk count moved. The YAML wasn't touched — drift is informational. To actually update that one host's entry without disturbing the rest of the file:
seaweed-up cluster plan -i inventory.yaml -o cluster.yaml --refresh-host 10.0.0.21
That host's master_servers / filer_servers / volume_servers rows get re-emitted from fresh facts; every other entry stays byte-identical. Then deploy.
See Cluster Plan Day 2 Operations for the full drift / refresh / dry-run workflow.
What plan does NOT generate
cluster plan brings up the infrastructure; a few things it deliberately leaves for the operator:
-
Buckets: none auto-created. SeaweedFS doesn't pre-create any S3 bucket; the S3 gateway exposes the filer's
/buckets/directory as the bucket namespace, but it starts empty. After deploy, create buckets via the S3 API (aws --endpoint http://<s3-host>:8333 s3 mb s3://photos) orweed shell(bucket.create -name photos). -
Filer metadata-store credentials: the
filer_servers[].config:block is empty unless you pass--filer-backend/--filer-backend-file/$SEAWEEDUP_FILER_BACKEND. With no backend, the filer falls back to embedded LevelDB at<dataDir>/<instance>/filerldb2(no credentials needed; not horizontally scalable). See Cluster Plan Inventory Reference for thetag:-substitution form. -
S3 IAM identities: plan emits empty
s3_servers[]entries; access keys / secret keys / per-user permissions are operator-authored. Hand-edit thes3_servers[].s3_config.identitiesblock (see examples/typical.yaml) before deploy or your S3 gateway runs anonymous-only. -
Admin UI password: plan stamps
admin_user: admin/admin_password: CHANGE_MEso the deployed UI isn't silently unauthenticated. The header comment in the generatedcluster.yamlcalls this out — edit it to a real secret before deploy or your admin UI accepts a known-bad password.
Escape hatches
--overwrite— regeneratecluster.yamlfrom scratch, discarding all hand edits. Use when you've drifted too far to merge cleanly.- Hand-written
cluster.yamlfiles are still fully supported — see Deployment with seaweed-up for the no-inventory workflow.
Introduction
- Quick Start with weed mini
- Simplest S3 Bucket and User Setup
- Components
- Getting Started
- Production Setup
- A typical step‐by‐step example
- Benchmarks
- FAQ
- Applications
API
Configuration
- Replication
- Store file with a Time To Live
- Failover Master Server
- Erasure coding for warm storage
- EC Bitrot Detection
- Server Startup via Systemd
- Environment Variables
Filer
- Filer Setup
- Directories and Files
- File Operations Quick Reference
- Data Structure for Large Files
- Filer Data Encryption
- Filer Commands and Operations
- Filer JWT Use
- TUS Resumable Uploads
Filer Stores
- Filer Cassandra Setup
- Filer Redis Setup
- Super Large Directories
- Path-Specific Filer Store
- Choosing a Filer Store
- Customize Filer Store
Management
Advanced Filer Configurations
- Migrate to Filer Store
- Add New Filer Store
- Filer Store Replication
- Filer Active Active cross cluster continuous synchronization
- Filer as a Key-Large-Value Store
- Path Specific Configuration
- Filer Change Data Capture
- Filer Operation Serialization
FUSE Mount
- FIO benchmark
- fstab and systemd mount
- POSIX Compliance
- Distributed POSIX Locks
- P2P reading in weed mount
WebDAV
SFTP Server
Cloud Drive
- Cloud Drive Benefits
- Cloud Drive Architecture
- Configure Remote Storage
- Mount Remote Storage
- Cache Remote Storage
- Cloud Drive Quick Setup
- Gateway to Remote Object Storage
AWS S3 API
- Amazon S3 API
- Supported APIs vs Minio
- S3 Lifecycle
- S3 Lifecycle vs Volume TTL
- S3 Conditional Operations
- S3 CORS
- S3 Object Lock and Retention
- S3 Object Versioning
- S3 API Benchmark
- S3 API FAQ
- S3 Bucket Quota
- S3 Rate Limiting
- S3 API Audit log
- S3 Nginx Proxy
- Docker Compose for S3
S3 Table Bucket
- S3 Table Bucket
- S3 Table Bucket Commands
- S3 Tables Security
- SeaweedFS Iceberg Catalog
- Iceberg Table Maintenance
Iceberg Integrations
- Spark Iceberg Integration
- Trino Iceberg Integration
- Dremio Iceberg Integration
- DuckDB Iceberg Integration
- Doris Iceberg Integration
- RisingWave Iceberg Integration
- Lakekeeper Iceberg Integration
S3 Authentication & IAM
- S3 Configuration - Start Here
- S3 Credentials (
-s3.config) - OIDC Integration (
-s3.iam.config) - Kubernetes ServiceAccount Authentication (IRSA-style)
- S3 Policy Variables
- S3 Policy Conditions
- S3 Bucket Policies
- Amazon IAM API
- AWS IAM CLI
- weed shell - Shell IAM Commands
Server-Side Encryption
S3 Client Tools
- AWS CLI with SeaweedFS
- s3cmd with SeaweedFS
- rclone with SeaweedFS
- restic with SeaweedFS
- nodejs with Seaweed S3
Machine Learning
HDFS
- Hadoop Compatible File System
- run Spark on SeaweedFS
- run HBase on SeaweedFS
- run Presto on SeaweedFS
- Hadoop Benchmark
- HDFS via S3 connector
Replication and Backup
- Async Replication to another Filer [Deprecated]
- Async Backup
- Async Filer Metadata Backup
- Async Replication to Cloud [Deprecated]
- Kubernetes Backups and Recovery with K8up
Metadata Change Events
Messaging
- Structured Data Lake with SMQ and SQL
- Seaweed Message Queue
- SQL Queries on Message Queue
- SQL Quick Reference
- PostgreSQL-compatible Server weed db
- Pub-Sub to SMQ to SQL
- Kafka to Kafka Gateway to SMQ to SQL
Use Cases
Operations
- System Metrics
- weed shell
- Data Backup
- Deployment to Kubernetes and Minikube
- Deployment with seaweed-up
Rust Volume Server
Advanced
- Large File Handling
- Optimization
- Optimization for Many Small Buckets
- Volume Management
- Tiered Storage
- Cloud Tier
- Cloud Monitoring
- Load Command Line Options from a file
- SRV Service Discovery
- Volume Files Structure
Security
- Security Overview
- Security Configuration
- Cryptography and FIPS Compliance
- Run Blob Storage on Public Internet