@@ -67,7 +67,7 @@ These services are fully managed by Zerops and offered in highly available and s
### Storages
-Fully managed S3 compatible storage running on a separate infrastructure and persistent disk volumes that can be mounted to multiple services. Runtime containers are replaced on every deploy, so persistent data belongs in one of these — see [Storage on Zerops](/storage/overview).
+Fully managed S3 compatible storage running on a separate infrastructure, persistent disk volumes that can be mounted to multiple services, and a managed SeaweedFS distributed filesystem. Runtime containers are replaced on every deploy, so persistent data belongs in one of these — see [Storage on Zerops](/storage/overview).
## Quicklinks
@@ -3533,12 +3533,6 @@ Have you built something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Ubuntu > How To > Shared Storage
-
-
-
----------------------------------------
# Ubuntu > How To > Scaling
@@ -3620,7 +3614,7 @@ Zerops caches custom runtime images to optimize deployment times. Learn about [c
For information about managing builds and deployments, see [managing builds and deployments](/features/pipeline#manage-builds-and-deployments).
:::warning
-Shared storage mounts and Local Storage volumes are not available during the runtime prepare phase.
+Local Storage volumes are not available during the runtime prepare phase, and start commands (such as a SeaweedFS mount) do not run there.
:::
## Troubleshooting
@@ -3771,7 +3765,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -5152,8 +5146,8 @@ Zerops offers three storage services. The first word of each name tells you the
Not yet |
- | [Shared Storage](/shared-storage/overview) (deprecated) |
- Network filesystem |
+ [SeaweedFS](/seaweedfs/overview) |
+ Network filesystem, mounted or accessed over HTTP by your services |
POSIX-like with network filesystem caveats (per-mount locks, write amplification) |
Yes |
@@ -5164,13 +5158,14 @@ Zerops offers three storage services. The first word of each name tells you the
- **Uploads, media, backups, logs, exports** — [Object Storage](/object-storage/overview). Highly available, cheapest per GB, and independent of any runtime service; the default for most application data.
- **Anything that needs a real filesystem** — [Local Storage](/local-storage/overview). SQLite and other embedded databases, single-node stateful apps such as Prometheus or Gitea, and filesystem state shared between services (certificates, caches). It is the only storage type where lock-dependent workloads are safe; see its [trade-offs](/local-storage/overview#key-trade-offs).
-- **Existing `mount:`-based setups** — [Shared Storage](/shared-storage/overview) keeps working but is deprecated. Move to Local Storage with the [migration guide](/local-storage/how-to/migrate-from-shared-storage), or to Object Storage if the data fits the S3 model.
+- **Files shared between containers over the network, with high availability** — [SeaweedFS](/seaweedfs/overview). Zerops runs the managed cluster, your services mount it with `weed mount` from their start commands or talk to its filer HTTP API. Not for databases, see its [storage engine behavior](/seaweedfs/overview#storage-engine-behavior).
+- **Existing Shared Storage setups** — the service is already a SeaweedFS service. Take over the mount with the [SeaweedFS migration guide](/seaweedfs/how-to/migrate-from-shared-storage), or move the data to Local Storage with [its guide](/local-storage/how-to/migrate-from-shared-storage).
For structured data, use a [managed database](/postgresql/overview) rather than files on any storage.
- [Object Storage](/object-storage/overview) — S3 compatible storage for uploads, media, and backups.
- [Local Storage](/local-storage/overview) — Persistent local disk volume with full POSIX semantics.
-- [Shared Storage](/shared-storage/overview) — Deprecated network filesystem. See the migration guide.
+- [SeaweedFS](/seaweedfs/overview) — Managed distributed filesystem you mount from your services.
## Need help?
@@ -5628,445 +5623,356 @@ run:
----------------------------------------
-# Shared Storage > Tech Details
+# Shared Storage > Overview
-:::warning Deprecated
-Shared Storage is [deprecated](/shared-storage/overview). For new projects, use [Local Storage](/local-storage/overview) or [Object Storage](/object-storage/overview) instead. To move an existing service, follow the [migration guide](/local-storage/how-to/migrate-from-shared-storage).
+:::warning Shared Storage is deprecated
+Shared Storage, the SeaweedFS cluster that Zerops mounted into your runtime containers through the **Shared storage connections** page and the `mount:` import field, is no longer offered. The service type has been retired, the `mount:` field is rejected on import, and the connections page is gone from the GUI.
:::
-Zerops Shared Storage is built on [SeaweedFS ↗](https://github.com/seaweedfs/seaweedfs), a distributed filesystem optimized for high-volume storage with efficient retrieval.
-
-## Architecture
-
-Shared Storage consists of three main components:
-
-- **Master Server**: manages metadata and coordinates volume servers
-- **Volume Servers**: store the actual file data
-- **Filer**: provides a POSIX-compatible interface for file operations
+**Every existing Shared Storage service has been converted in place into a [SeaweedFS](/seaweedfs/overview) service.** Same containers, same data, same hostname, no action was needed on your side. The mounts your runtime services had keep working for now through the `zeropsSharedStorageMounts` environment variable, on a best-effort basis and with a deprecation warning in the runtime log. Take over the mount in your own `zerops.yaml` with the [migration guide](/seaweedfs/how-to/migrate-from-shared-storage) before the managed mounts are removed.
-### Storage Engine Behavior
+For new projects, pick by workload:
-SeaweedFS stores file data in append-only volumes. Files are split into chunks, and when a file is modified, new chunks are written while the old ones remain on disk until they are reclaimed. Frequent small modifications of existing files therefore cause significant write amplification, which is one of the reasons Shared Storage is [not suitable for databases](/shared-storage/overview#use-cases).
+- **Files shared between containers and services** over the network - [SeaweedFS](/seaweedfs/overview). The same managed cluster as before, you mount it or use its filer API yourself.
+- **A real filesystem** with correct locking, for SQLite and other filesystem-based databases or single-node stateful apps - [Local Storage](/local-storage/overview).
+- **Uploads, media, backups** - [Object Storage](/object-storage/overview).
-An **automatic vacuum process** reclaims the space occupied by deleted and superseded chunks. This process is triggered when the size of deleted content exceeds 15% (reduced from the SeaweedFS default of 30%).
+See [Storage on Zerops](/storage/overview) for the full comparison.
-## Deployment Modes
+- [Migrate to SeaweedFS](/seaweedfs/how-to/migrate-from-shared-storage) — Take over the mount in your zerops.yaml, no data moves.
+- [Migrate to Local Storage](/local-storage/how-to/migrate-from-shared-storage) — Copy the data to a Local Storage volume.
+- [Storage on Zerops](/storage/overview) — Compare the storage services and pick the right one.
-Zerops provides Shared Storage in two deployment modes:
-### Highly Available
+----------------------------------------
-Recommended for production environments where data reliability is critical.
+# Seaweedfs > Overview
-- **Architecture**: Two containers, each running its own filer and volume server; the master server runs on the first container
-- **Data Durability**: Data and filer metadata are replicated 1:1 across both containers
-- **Fault Tolerance**:
- - If a node fails, an automatic repair process begins
- - A new container replaces the failed one
- - Data is automatically replicated to the new container (duration depends on data size)
- - During master node failure, mounted directories become temporarily unavailable until the new master initializes (~30s)
-### Single Container
+[SeaweedFS ↗](https://github.com/seaweedfs/seaweedfs) is a distributed filesystem built for high volumes of files. Zerops runs the SeaweedFS cluster for you - master, volume servers and filer, in a single container or in a replicated highly available pair, with monitoring, autoscaling and backups.
-Suitable for development environments or non-critical data storage.
+What Zerops does **not** do is decide how your application talks to it. The service exposes the SeaweedFS **filer** on the project network, and you pick the client: a FUSE mount started from your `zerops.yaml`, the filer HTTP API, or any other SeaweedFS client. This replaces the deprecated [Shared Storage](/shared-storage/overview), which mounted the same cluster into your containers with one fixed set of mount options. If you have a Shared Storage service, see the [migration guide](/seaweedfs/how-to/migrate-from-shared-storage).
-- **Architecture**: Master, volume, and filer server all located on a single container
-- **Data Durability**: All data is lost if the container fails
-
-:::warning
-The deployment mode is fixed after the service is created and cannot be changed later.
+:::tip Is SeaweedFS the right storage?
+SeaweedFS is a network filesystem: files are visible from every container that mounts it, but locks are enforced per mount and the store is append-only. That makes it a good fit for **files shared between containers and services** and a bad fit for databases. For a real POSIX filesystem with correct locking use [Local Storage](/local-storage/overview), for uploads, media and backups use [Object Storage](/object-storage/overview). See [Storage on Zerops](/storage/overview) for the comparison.
:::
-## Filesystem Capabilities
-
-Shared Storage supports standard POSIX filesystem operations:
-
-- Create, read, update, and delete files and directories
-- Set permissions (with some limitations)
-- File locking (per mount only, see the warning below)
-- Hard and symbolic links
-- Directory listing and traversal
+## Supported Versions
-For a complete list of supported features, see the [SeaweedFS FUSE documentation ↗](https://github.com/seaweedfs/seaweedfs/wiki/FUSE-Mount#supported-features).
+Currently supported SeaweedFS versions:
-:::caution File locks are per-mount only
-File locks (`flock`, POSIX locks) are enforced only within a single container's mount. A process in another container can freely write to a file you hold locked. Do not rely on file locking for coordination between containers, and do not run [lock-dependent workloads such as databases](/shared-storage/overview#use-cases) on Shared Storage.
-:::
+Import configuration version:
-## Storage Capacity
+- `seaweedfs:single@3.85`, `seaweedfs:ha@3.85`
-:::caution The 60GB data limit is independent of disk scaling
-A Shared Storage service holds at most **60GB of data**, no matter how much disk the service scales to. The disk resource (up to 250GB) provides headroom for the vacuum process and filesystem metadata; raising the disk limits in autoscaling does **not** increase the amount of data you can store.
+The legacy `shared-storage:ha` and `shared-storage:single` type names are accepted as aliases and create a SeaweedFS service.
-If you need more than 60GB, contact support.
-:::
+## Service Configuration
-- Maximum storage space: 60GB (can be increased via support request)
-- Maximum file size: no fixed limit through the mount (files are stored in chunks), up to the available storage space
-- Maximum upload size via Filer UI: 64MB per file
+Zerops offers SeaweedFS in two deployment modes. The mode is part of the service type and is fixed for the life of the service.
-## Performance Considerations
+### Single Setup
-- **Latency**: higher latency compared to local storage due to the network-based distributed architecture
-- **Write performance**: for write-heavy workloads, batch operations where possible
-- **Small files**: minimize operations with many small files for better performance
-- **Mount process memory**: the mount process runs inside each connected runtime container and consumes its memory, roughly 60MB when idle and around 150MB under higher filesystem loads; it is optimized for low RAM usage, which may trade off some performance
+- One container running master, volume server and filer
+- No redundancy, all data is lost if the container fails
+- Suitable for development or non-critical data
-## Auto Scaling Configuration
+### HA (High Availability) Setup
-Zerops scales Shared Storage services automatically by raising or lowering the hardware resources of each container.
+- Two containers, each running its own volume server and filer, the master runs on the first one
+- File data and filer metadata are replicated 1:1 across both containers (SeaweedFS replication `001`)
+- When a container fails, a new one replaces it and the data is replicated onto it automatically. While the master container is being replaced, the cluster is unavailable for roughly 30 seconds until the new master starts
+- Recommended for production
-Vertical auto scaling has the following default configuration:
+### Creating the service
-:::note
-Disk size only gives the storage engine working space; the usable data capacity stays capped at 60GB. See [Storage Capacity](#storage-capacity).
-:::
+Add the service in the Zerops GUI (**Add new service** → **SeaweedFS**), or import it:
-For most cases, the default parameters will work without issues. If you need to limit the cost of the Shared Storage service, lower the maximal resources. Zerops will never scale above the selected maximums.
+```yaml title="zerops-import.yaml"
+services:
+ - hostname: storage
+ type: seaweedfs:ha@3.85
+```
-When you are experiencing problems with insufficient Shared Storage performance, increase the minimal resources. Zerops will never scale below the selected minimums.
+Use `seaweedfs:single@3.85` for the single container mode. Import the file with the [zCLI](/references/cli):
-You can change the auto scaling parameters at any time.
+```sh
+zcli project service-import zerops-import.yaml
+```
+## Connecting
-----------------------------------------
+The service exposes only the filer, the component every client talks to. Master and volume servers are internal to the cluster and clients reach them through the filer on their own.
-# Shared Storage > Overview
+| Endpoint | Address | Notes |
+|---|---|---|
+| Filer HTTP API | `http://
.zerops:8888` | File upload, download and listing over HTTP, and the Filer UI |
+| Filer gRPC | `.zerops:18888` | Used by `weed mount` and other native SeaweedFS clients (always HTTP port + 10000) |
+| Filer of one container | `node-stable-.db..zerops:8888` | Pin a client to a specific container, `n` is `1` or `2` |
+| Filer of one container | `node-stable-.db..zerops:8888` | Pin a client to a specific container, `n` is `1` or `2` |
+The generated environment variables are `hostname` and `port` (`8888`). Reference them from another service in the same project as `${storage_hostname}` and `${storage_port}` for a service named `storage`.
-:::warning Shared Storage is deprecated
-Shared Storage in its current form — a managed SeaweedFS cluster connected through the import-level `mount:` field — is deprecated. It will be replaced by a standalone SeaweedFS managed service that runtime services mount themselves with [`zsc shared-storage mount`](/references/zsc#shared-storage) in their `initCommands`. Existing Shared Storage services keep working for now, but don't build new projects on it — and move existing ones with the [migration guide](/local-storage/how-to/migrate-from-shared-storage).
+The filer is not authenticated. It is reachable only inside the project's private network and over the [Zerops VPN](/references/networking/vpn), and it cannot be exposed through public HTTP routing or subdomain access.
-For new projects, choose by workload:
+### Mounting from a runtime service
-- A **persistent filesystem shared between services** — use [Local Storage](/local-storage/overview). It is a real local filesystem with correct locking, so it also covers the workloads Shared Storage was never safe for (SQLite and other filesystem-based databases).
-- **Large or highly available data** — use [Object Storage](/object-storage/overview).
-:::
+The SeaweedFS binary that ships in every Zerops runtime container (`/opt/zerops/bin/weed-3-85`) contains `weed mount`, a FUSE client that presents the filer as a directory. Run it as one of your [`startCommands`](/zerops-yaml/specification#startcommands-), next to your application:
-Zerops **Shared Storage** is a managed disk volume that mounts as a POSIX-compatible filesystem into your runtime services. Files written by one container are immediately visible to every other container that mounts the same storage, whether they belong to the same service or to different services in the project.
+```yaml title="zerops.yaml"
+zerops:
+ - setup: app
+ run:
+ base: nodejs@22
+ startCommands:
+ - name: app
+ command: npm start
+ - name: storage
+ initCommands:
+ - sudo mkdir -p /mnt/storage
+ - sudo chown zerops:zerops /mnt/storage
+ command: sudo /opt/zerops/bin/weed-3-85 mount -filer=node-stable-1.db.storage.zerops:8888 -dir=/mnt/storage -cacheCapacityMB=0 -concurrentWriters=1 -chunkSizeLimitMB=1
+```
-Under the hood it runs [SeaweedFS ↗](https://github.com/seaweedfs/seaweedfs), a distributed filesystem optimized for high-volume storage. See [Technical details](/shared-storage/tech-details) for the architecture.
+- `weed mount` runs in the foreground and keeps the directory mounted for the lifetime of the container. Zerops restarts it like any other start command if it exits.
+- `-filer` points at the filer of one container. In HA mode both containers run a filer with the same metadata, so a second service can mount `node-stable-2` to spread the load.
+- The mount needs `sudo`, both Ubuntu and Alpine runtime images allow it without a password.
+- Every container of the service gets its own mount, and every mount sees the same files.
+- The three trailing flags keep the memory footprint of the mount process around 100-150 MB by disabling the local cache and limiting write buffers. Without them the process can grow well beyond the container's RAM. Tune or drop them if you have the memory to spare and want more throughput, see the [`weed mount` options ↗](https://github.com/seaweedfs/seaweedfs/wiki/FUSE-Mount).
+- The mount is only available while the container runs, not during the build or the [runtime prepare](/features/pipeline#runtime-prepare-phase-optional) phase.
-## Quick start
+:::note Shortcut: `zsc shared-storage mount`
+`zsc shared-storage mount ` does the same thing with the flags above baked in: it creates `/mnt/`, gives it to the `zerops` user and mounts the filer of the first container (`node-stable-1.db..zerops:8888`) there. It exists for backwards compatibility with the deprecated Shared Storage and stays available, see the [zsc reference](/references/zsc#shared-storage).
+:::
-Add a shared storage to your project and mount it into a runtime service with a `zerops-import.yaml`:
+### Mounting in init commands
-```yaml title="zerops-import.yaml"
-services:
- - hostname: teststorage
- # type is shared-storage:{mode}
- type: shared-storage:ha
+A start command only runs after the [`initCommands`](/zerops-yaml/specification#initcommands-), so if an init command needs the storage (a certificate that lives there, a config it has to write, a migration over shared files), mount it there instead, in the background:
- - hostname: app
- type: nodejs@22
- buildFromGit: https://github.com/myorg/myapp
- # mount the storage into /mnt/teststorage
- mount:
- - teststorage
+```yaml title="zerops.yaml"
+zerops:
+ - setup: app
+ run:
+ base: nodejs@22
+ initCommands:
+ - sudo zsc shared-storage mount storage --background
+ - cp /mnt/storage/certs/app.pem /var/www/app.pem
+ start: npm start
```
-The storage appears in the runtime containers at `/mnt/teststorage`. See [Create shared storage](/shared-storage/how-to/create) for the GUI flow and configuration details, and [Connect & mount](/shared-storage/how-to/connect) for how the mount behaves.
-
-## Use cases
-
-Shared Storage is a good fit for:
-
-- **Configuration sharing**: deploy configuration once and share it across services (e.g. Apache Airflow configuration and DAG files shared with all worker nodes)
-- **Application data**: user uploads, images, documents, and other assets shared between containers (avoid huge trees of tiny files, see [performance considerations](/shared-storage/tech-details#performance-considerations))
-- **Fallback to object storage**: applications that strictly require filesystem semantics and cannot work with [object storage](/object-storage/overview)
+`--background` mounts `/mnt/` the same way as the foreground form (same filer, same memory flags), leaves a detached `weed mount` process behind and returns once the mount is ready. Init commands run on every container start, and the command cleans up a stale mount before mounting, so a restart mounts again.
-:::caution Not suitable for databases
-Do **not** run databases on Shared Storage. This includes SQLite, Prometheus TSDB, and other filesystem-based databases.
+The raw equivalent, for a custom path or options, is `weed fuse`: it takes every `weed mount` flag as an `-o` option and detaches the same way:
-- File locks are enforced **per mount only**: a lock held in one container does not prevent another container from writing to the same file, which leads to data corruption.
-- The underlying storage engine is an append-only chunk store: every modification writes new chunks, so the frequent small writes typical for databases cause heavy write amplification.
+```yaml
+ initCommands:
+ - sudo mkdir -p /mnt/certs && sudo chown zerops:zerops /mnt/certs
+ - sudo /opt/zerops/bin/weed-3-85 fuse /mnt/certs -o "filer=node-stable-1.db.storage.zerops:8888,filer.path=/certs,readOnly=true,cacheCapacityMB=0,concurrentWriters=1,chunkSizeLimitMB=1"
+```
-Use [managed databases](/postgresql/overview) instead. For SQLite and other filesystem-based databases, use [Local Storage](/local-storage/overview) — a local filesystem with correct locking where these workloads are safe. For storing database *backups*, prefer [object storage](/object-storage/overview): it is cheaper and better suited for write-once files.
+:::caution Nothing supervises a background mount
+A mount started from an init command is not restarted if its process dies, unlike a start command. Zerops replaces a container whose health check fails, but a lost mount alone does not fail the health check. If the storage is part of what your application serves, prefer the start command form, or add a [health check](/zerops-yaml/specification#healthcheck-) that touches a file on the mount.
:::
-## Deployment modes
+### Useful mount options
-Choose the reliability model when you create the service. It is set through the service `type` and is **fixed for the life of the service**.
+These apply to `weed mount` as flags (`-filer.path=/certs`) and to `weed fuse` as `-o` options (`filer.path=/certs`):
-
-
-
- | Mode |
- type |
- What it is |
-
-
-
-
- | Highly Available |
- shared-storage:ha |
- Two containers with data and metadata replicated 1:1 across both, with automatic repair when a node fails. Recommended for production. |
-
-
- | Single container |
- shared-storage:single |
- One container, so lower cost but no redundancy. All data is lost if the container fails. Good for development and non-critical data. |
-
-
-
-
-## Key limits
-
-- The storage holds at most **60GB of data**, regardless of the disk resource in autoscaling. See [storage capacity](/shared-storage/tech-details#storage-capacity).
-- File locks work **only within a single container's mount**, not across containers. See [filesystem capabilities](/shared-storage/tech-details#filesystem-capabilities).
-- The mount is available only in runtime containers, not during build and prepare phases.
+| Option | What it does |
+|---|---|
+| `filer=:8888,:8888` | Comma-separated list of filers. In HA mode you can list both containers (`node-stable-1.db..zerops:8888,node-stable-2.db..zerops:8888`) instead of pinning the mount to one of them. |
+| `filer.path=/some/dir` | Mounts only that directory of the storage, so different services can get different subtrees of one storage. The directory is created if missing. |
+| `readOnly=true` | Read-only mount, writes fail with `Read-only file system`. |
+| `cacheCapacityMB`, `concurrentWriters`, `chunkSizeLimitMB` | Memory trade-offs described above. |
+| `allowOthers=false` | Restricts the mount to the user that mounted it (root when started with `sudo`), the default `true` lets the `zerops` user in. |
+| `allowOthers=false` | Restricts the mount to the user that mounted it (root when started with `sudo`), the default `true` lets the `zerops` user in. |
-## Next steps
+See the [FUSE mount documentation ↗](https://github.com/seaweedfs/seaweedfs/wiki/FUSE-Mount) for the full list.
-- [Create shared storage](/shared-storage/how-to/create) — Create a service in the GUI or with zerops-import.yaml.
-- [Connect & mount](/shared-storage/how-to/connect) — Connect runtime services and understand how the mount behaves.
-- [Manage & backups](/shared-storage/how-to/manage) — Web interfaces, monitoring, backups, and restore.
-- [Technical details](/shared-storage/tech-details) — Architecture, storage engine behavior, limits, and autoscaling.
+### Filer HTTP API
-## Need help?
+Any HTTP client can read and write files without a mount, which suits build steps, one-off jobs and languages with an HTTP client but no FUSE:
-Stuck, or want to share what you built? Our core team and community are on Discord.
-
-- [Discord](https://discord.com/invite/WDvCZ54) — Join the Zerops community on Discord. Ask questions and share your tips.
-- [zCLI](/references/cli) — Get more out of Zerops with the command-line tool.
-
-
-----------------------------------------
+```sh
+# upload (creates the directories on the way)
+curl -F "file=@report.pdf" http://storage.zerops:8888/reports/2026/
-# Shared Storage > How To > Manage
+# download
+curl -o report.pdf http://storage.zerops:8888/reports/2026/report.pdf
+# list a directory as JSON
+curl -H "Accept: application/json" http://storage.zerops:8888/reports/2026/
-:::warning Deprecated
-Shared Storage is [deprecated](/shared-storage/overview). For new projects, use [Local Storage](/local-storage/overview) or [Object Storage](/object-storage/overview) instead. To move an existing service, follow the [migration guide](/local-storage/how-to/migrate-from-shared-storage).
-:::
+# delete
+curl -X DELETE http://storage.zerops:8888/reports/2026/report.pdf
+```
-Zerops Shared Storage provides several web interfaces to manage, monitor, and troubleshoot your storage, and automated encrypted backups of your data.
+Uploads through the HTTP API are limited to **64 MB per file**. Files written through a mount are chunked and have no such limit. See the [filer server API ↗](https://github.com/seaweedfs/seaweedfs/wiki/Filer-Server-API) for the full interface.
-## Web interfaces
+### Web interfaces
-The web interfaces are accessible through the [Zerops VPN](/references/networking/vpn).
+Over the [Zerops VPN](/references/networking/vpn) you can open the SeaweedFS UIs in a browser:
-### Filer UI
+- **Filer UI** - `http://.zerops:8888` - browse, upload and download files
+- **Master UI** - `http://node-stable-1.db..zerops:9333` - cluster topology, volume servers, health
+- **Volume UI** - `http://node-stable-.db..zerops:8080/ui/index.html` - volume status and disk usage of one container
-* `http://.zerops:8888`
+## Storage engine behavior
-A web-based interface for managing files and directories:
-- Browse the directory structure and create new directories
-- Upload new files (up to 64MB per file) and download existing files
-- Rename and delete files and directories
+SeaweedFS stores file data in append-only volumes. Files are split into chunks, and when a file is modified new chunks are written while the old ones stay on disk until a vacuum reclaims them. Zerops triggers the automatic vacuum when deleted content exceeds 15% of a volume (the SeaweedFS default is 30%).
-### Master UI
+The consequences for your workload:
-* `http://node-stable-1.db..zerops:9333`
+- **Frequent small modifications of existing files** cause heavy write amplification. Batch writes where possible and avoid huge trees of tiny files.
+- **File locks are per mount.** `flock` and POSIX locks are enforced only inside the container that holds the mount, a process in another container can write to the locked file freely.
+- **Latency is higher** than on a local disk, every operation crosses the network.
-System status and monitoring information:
-- View cluster topology
-- Monitor volume servers
-- Check system status and health
-- View statistics and metrics
+:::caution Not suitable for databases
+Do not run SQLite, Prometheus TSDB or any other filesystem-based database on SeaweedFS. Per-mount locks lead to corruption as soon as two containers touch the database, and the append-only store amplifies every small write. Use a [managed database](/postgresql/overview), or [Local Storage](/local-storage/overview) for embedded databases.
+:::
-### Volume UI
+## Capacity
-* `http://node-stable-.db..zerops:8080/ui/index.html`
+A SeaweedFS service holds at most **60 GB of data** regardless of the disk resource in autoscaling. The disk gives the storage engine working space for the vacuum process and metadata, raising it in autoscaling does not raise the data capacity. If you need more, contact support.
-Monitoring of individual storage volumes:
-- View volume status
-- Check disk usage
-- Monitor I/O operations
-- View volume statistics
+- Maximum file size: no fixed limit through a mount, up to the available capacity
+- Maximum upload size through the filer HTTP API and UI: 64 MB per file
+- `df` inside a mount reports the filer's view and can be misleading, use the service detail page in the GUI for accurate usage
-## Monitoring
+## Auto Scaling Configuration
-Several options are available to help you monitor your Shared Storage:
+Zerops scales the containers vertically. The default configuration is:
-- **Runtime service logs**: navigate to your runtime service detail page, open the **Runtime Logs** section, and filter using the tag `zerops-mount-` (standard output and error of the mount process)
-- **Shared Storage logs**: access from the Shared Storage service detail page, **Runtime Logs** tab
-- **System and volume status**: monitor replication status, disk usage, and performance metrics through the Master UI and Volume UI
+The number of containers is fixed by the deployment mode. If you need to limit the cost of the service, lower the maximum resources, Zerops never scales above them. If the storage feels slow, raise the minimum resources, Zerops never scales below them. The parameters can be changed at any time.
-## Backups
+## Health Monitoring
-Zerops provides automated data backup for Shared Storage services with full encryption.
+Zerops checks the master (`/cluster/healthz`), the volume server (`/status`) and the filer of every container and shows the result on the service detail page. The SeaweedFS logs of every component are in the service's **Runtime Logs**, the logs of a mount process are in the runtime logs of the service that runs it, under the name of the start command.
-For general backup information including configuration, scheduling, retention, tagging, quotas, and CLI tools, see the [Zerops Backups](/features/backup) documentation.
-
-### Backup format
+## Backup and Recovery
-Shared Storage backups are created using tar archival:
+Zerops takes automated encrypted backups of the whole filesystem. For configuration, scheduling, retention, tagging, quotas and CLI tools see [Zerops Backups](/features/backup).
-- **Format**: `.tar.gz` (archive of the directory contents)
-- **Content**: the entire shared volume (`/mnt/`)
-- **Storage**: encrypted and stored in isolated object storage
+- **Format**: `.tar.gz` archive of the filesystem contents
+- **Storage**: encrypted, in isolated object storage
### Restoring backups
-To restore a Shared Storage backup:
-
-1. Download the backup file (`.tar.gz`) from the Zerops UI.
-2. Transfer the archive into a runtime service that has the shared storage [connected](/shared-storage/how-to/connect), for example over the [Zerops VPN](/references/networking/vpn).
-3. Extract the archive into the mount directory from within the runtime container:
+1. Download the backup archive from the Zerops GUI.
+2. Transfer it into a runtime service that has the storage [mounted](#mounting-from-a-runtime-service), for example over the [Zerops VPN](/references/networking/vpn).
+3. Extract it into the mount directory:
```sh
-tar -xzf backup.tar.gz -C /mnt/
+tar -xzf backup.tar.gz -C /mnt/storage
```
-:::note
-Do not restore by uploading files through the Filer UI. Uploads there are limited to 64MB per file, so extracting the archive directly into the mounted directory is the reliable path.
-:::
+Extract through a mount rather than uploading through the Filer UI, whose 64 MB per-file limit would reject larger files.
-### Best practices
+## Support
-- Regularly clean up unnecessary files from your Shared Storage to reduce backup size
-- Create manual backups with protected tags before major file operations or migrations
-- Test your restore process periodically to ensure data integrity
+- Ask in the Zerops [Discord](https://discord.com/invite/WDvCZ54)
+- SeaweedFS [wiki ↗](https://github.com/seaweedfs/seaweedfs/wiki) for client options and the filer API
----------------------------------------
-# Shared Storage > How To > Create
+# Seaweedfs > How To > Migrate From Shared Storage
-:::warning Deprecated
-Shared Storage is [deprecated](/shared-storage/overview). For new projects, use [Local Storage](/local-storage/overview) or [Object Storage](/object-storage/overview) instead. To move an existing service, follow the [migration guide](/local-storage/how-to/migrate-from-shared-storage).
-:::
+[Shared Storage](/shared-storage/overview) is deprecated. Every existing Shared Storage service has already been converted in place into a [SeaweedFS](/seaweedfs/overview) service: same containers, same data, same hostname. What changes is who mounts it. Zerops used to mount the storage into your runtime containers through the **Shared storage connections** page and the `mount:` import field. Now your service mounts it itself, from its `zerops.yaml`.
-## Create Using Zerops GUI
-
-Go to your project dashboard and choose **Add new service** in the left menu in the **Services** block. Then add a new Shared Storage service:
+Until you do that, the old mounts keep working: the connection lives on as the `zeropsSharedStorageMounts` environment variable of the runtime service, Zerops still mounts every hostname listed in it at `/mnt/` on container start, and logs a deprecation warning into the runtime log each time. The managed mount is best-effort from now on and will be removed in a later release, so plan the switch.
-[Video: /vids/services/shared-storage.webm](/vids/services/shared-storage.webm)
-
-### Set a Hostname
-
-Enter a unique service identifier like "storage", "files" etc.
-
-- Maximum 25 characters
-- Must contain only lowercase ASCII letters (a-z) or numbers (0-9)
-- Must be unique within the project
-
-:::note
-The hostname is fixed after the service is created. It can't be changed later.
-:::
-
-### Connect to Services
-
-Select one or more of the project's runtime services in the **Share with Services** block:
-
-Runtime services can be [connected and disconnected](/shared-storage/how-to/connect) at any time, even after the shared storage is created.
-
-### Choose Deployment Mode
+The migration in short:
-Choose between **Highly Available** (recommended for production) and **Single Container** (suitable for development). See the [mode comparison](/shared-storage/overview#deployment-modes) and [technical details](/shared-storage/tech-details#deployment-modes).
+1. Add a `weed mount` start command to the `zerops.yaml` of every service that uses the storage.
+2. Delete the `zeropsSharedStorageMounts` variable of that service.
+3. Deploy.
+4. Update your import files.
-:::warning
-The deployment mode is fixed after the service is created. It can't be changed later.
-:::
+Throughout the guide, `storage` is the hostname of the storage service and `app` the runtime service that mounts it. Replace them with your own.
-### Set Auto Scaling Configuration
+## Before you start
-Configure vertical auto scaling parameters to control resource allocation and costs:
+- The storage service now shows up as **SeaweedFS** in the GUI and has a `port` variable (`8888`, the filer). Nothing on it needs changing, and there is no **Shared storage connections** page anymore.
+- Take a fresh [backup](/seaweedfs/overview#backup-and-recovery) of the storage before you touch the mounts.
+- If you would rather move the data off SeaweedFS altogether, the [Local Storage migration guide](/local-storage/how-to/migrate-from-shared-storage) covers copying it to a Local Storage volume.
-:::note
-Raising the disk limits does not raise the usable data capacity, which is capped at 60GB. See [Storage Capacity](/shared-storage/tech-details#storage-capacity) and [Auto Scaling Configuration](/shared-storage/tech-details#auto-scaling-configuration).
-:::
-
-## Create Using Import YAML
+## 1. Mount the storage from zerops.yaml
-The deployment mode is part of the service type:
+Add a second entry to [`startCommands`](/zerops-yaml/specification#startcommands-) that runs `weed mount`. Keep the mount path the storage was at, `/mnt/`, so the application does not change. If your `zerops.yaml` uses a single `start` command, convert it into the first `startCommands` entry:
-```yaml title="zerops-import.yaml"
-services:
- - # Shared storage service in highly available mode
- hostname: teststorage
- type: shared-storage:ha
+```yaml title="zerops.yaml"
+zerops:
+ - setup: app
+ run:
+ base: nodejs@22
+ # start: npm start
+ startCommands:
+ - name: app
+ command: npm start
+ - name: storage
+ initCommands:
+ - sudo mkdir -p /mnt/storage
+ - sudo chown zerops:zerops /mnt/storage
+ command: sudo /opt/zerops/bin/weed-3-85 mount -filer=node-stable-1.db.storage.zerops:8888 -dir=/mnt/storage
```
-Use `shared-storage:single` for the single container mode.
+The `-filer` address is `node-stable-1.db..zerops:8888`, where `storage` is the **hostname of your SeaweedFS service** (the former Shared Storage service, its hostname did not change) and `8888` is the filer port. `node-stable-1.db..zerops` is the fixed name of the service's first container, which is where the managed mount always connected. In HA mode the second container is `node-stable-2.db..zerops`, and `.zerops:8888` alone resolves to the filer HTTP API too. A service that mounted several storages gets one such entry per storage.
-:::note
-You can also pin the underlying engine version directly with `seaweedfs:ha@3` or `seaweedfs:single@3`.
+:::note Memory-saving flags of the managed mount
+The managed mount ran `weed mount` with `-volumeServerAccess=direct -cacheCapacityMB=0 -concurrentWriters=1 -chunkSizeLimitMB=1`, which disables the local read cache and shrinks the write buffers so the mount process stays around 100-150 MB of RAM. Without them the process can grow well beyond that under load. Append them to the command above if the container's RAM is tight, see [Mounting from a runtime service](/seaweedfs/overview#mounting-from-a-runtime-service) for what they do.
:::
-Import the file with the [zCLI](/references/cli):
+The equivalent one-liner is `zsc shared-storage mount storage`, which stays available as a [shortcut](/references/zsc#shared-storage). It runs exactly what the managed mount ran: the filer address above, the mount at `/mnt/` owned by the `zerops` user, and the memory-saving flags:
-```sh
-zcli project service-import zerops-import.yaml
+```yaml
+ - name: storage
+ command: sudo zsc shared-storage mount storage
```
-To mount the storage into a runtime service in the same import, add the `mount:` parameter to the runtime service. See the [import reference](/references/import#service-mount-shared-storage) for details and requirements.
-
-### Runtime-Specific Guides
+### Alternative: mount in init commands
-export const languages = [
- { name: "Node.js", link: "/nodejs/how-to/shared-storage#create-nodejs-service-with-a-shared-storage-using-zcli" },
- { name: "PHP", link: "/php/how-to/shared-storage#create-php-service-with-a-shared-storage-using-zcli" },
- { name: "Python", link: "/python/how-to/shared-storage#create-python-service-with-a-shared-storage-using-zcli" },
- { name: "Go", link: "/go/how-to/shared-storage#create-go-service-with-a-shared-storage-using-zcli" },
- { name: ".NET", link: "/dotnet/how-to/shared-storage#create-dotnet-service-with-a-shared-storage-using-zcli" },
- { name: "Rust", link: "/rust/how-to/shared-storage#create-rust-service-with-a-shared-storage-using-zcli" }
-]
-
-
-----------------------------------------
-
-# Shared Storage > How To > Connect
-
-
-:::warning Deprecated
-Shared Storage is [deprecated](/shared-storage/overview). For new projects, use [Local Storage](/local-storage/overview) or [Object Storage](/object-storage/overview) instead. To move an existing service, follow the [migration guide](/local-storage/how-to/migrate-from-shared-storage).
-:::
+If your `initCommands` already use the storage (they read a certificate from it, write a config into it, run a migration over shared files), a start command comes too late, it only runs after the init commands. Mount in the background from the init commands instead:
-This page covers how to connect an existing shared storage to runtime services, how to disconnect it, and how the mount behaves inside your containers.
-
-## How the mount behaves
-
-Once a shared storage is connected to a runtime service, Zerops mounts it at `/mnt/` in the runtime containers. For example, `/mnt/teststorage` for a `teststorage` shared storage:
-
-- The content is shared among **all containers** of the connected runtime service; if you connect multiple runtime services, they all see the same content
-- Multiple storages can be mounted to a single service (e.g. `/mnt/files1`, `/mnt/files2`)
-- The mount point is owned by the `zerops` user and group (no sudo required)
-- Mounting removes any existing content of the mount directory
-- The mount is only available in runtime containers, not during build and prepare runtime phases
-- The mount process logs its standard output and error to the runtime service logs (tagged `zerops-mount-`); individual file operations are not logged
-
-:::note
-The `df` command may show incorrect or misleading information for shared storage mounts. Refer to the Zerops GUI for accurate storage metrics.
-:::
+```yaml title="zerops.yaml"
+zerops:
+ - setup: app
+ run:
+ base: nodejs@22
+ initCommands:
+ - sudo zsc shared-storage mount storage --background
+ - cp /mnt/storage/certs/app.pem /var/www/app.pem
+ start: npm start
+```
-## Connect in Zerops GUI
+The mount lands at the same `/mnt/storage`, with the same filer and memory flags, and stays mounted after the init commands finish. Init commands run on every container start, so restarts mount again. The difference to the start command form: nothing restarts the mount process if it dies. See [Mounting in init commands](/seaweedfs/overview#mounting-in-init-commands) for the raw `weed fuse` equivalent and the options it accepts (sub-path, read-only, both HA filers).
-When creating a new shared storage service, you can directly select which runtime services it should be connected to. See [Create shared storage](/shared-storage/how-to/create) for the creation process.
+## 2. Delete the `zeropsSharedStorageMounts` variable
-For existing storage, go to the shared storage service detail page and select **Shared storage connections**. Toggle ON any runtime services you wish to connect to this storage.
+Open the runtime service's **Environment variables** page and delete `zeropsSharedStorageMounts`. If the service mounts several storages and you are switching them one at a time, edit the variable and remove only the hostname you have taken over (the value is a `|`-separated list of hostnames).
-To disconnect storage, toggle OFF the desired runtime service in the same place.
+The change is applied live: the managed mount of that storage is unmounted from the running containers right away, and it is not recreated on the next container start. Your application loses the storage until step 3 completes, so do steps 2 and 3 back to back, or during a maintenance window.
-:::note
-Connecting and disconnecting a shared storage is applied live; the runtime containers are not restarted.
+:::caution Do it before the deploy, not after
+The managed mount and your `weed mount` target the same directory. Deploying first would start your mount on top of the managed one in the new containers, delete the variable first so only your mount runs.
:::
-## Mount and unmount using zsc
+## 3. Deploy
-You can also mount and unmount a shared storage from within a runtime container using the `zsc` command:
-
-```sh
-# Mount a shared storage
-zsc shared-storage mount
+Deploy the service with the changed `zerops.yaml` (`zcli push`, or trigger your pipeline). The new containers mount the storage from the start command, at the same path as before.
-# Unmount a shared storage
-zsc shared-storage unmount
+Check the runtime log: the `storage` start command logs the mount, and the deprecation warning that used to appear on container start is gone.
-# Wait until the storage mount is ready
-zsc shared-storage wait
-```
+## 4. Update your import files
-Run these commands from your runtime container via web terminal or SSH, or as part of your `zerops.yaml` commands. For more details, see the [zsc reference](/references/zsc#shared-storage).
+- Replace the `mount:` field of runtime services in `zerops-import.yaml` files and templates by the `startCommands` entry above, `mount:` is rejected by the import now (`yamlMountDeprecated`).
+- The `shared-storage:ha` and `shared-storage:single` type names still work and create a SeaweedFS service, but prefer `seaweedfs:ha@3.85` and `seaweedfs:single@3.85`.
-:::caution
-The shared storage must be mounted (through the GUI connection toggle or via `zsc shared-storage mount`) before your application can access the `/mnt/` directory.
+## Rollback
-Before stopping or deleting a shared storage service, you must first disconnect (unmount) it from all runtime services.
-:::
+Put the hostname back into `zeropsSharedStorageMounts` (or recreate the variable with the hostname as its value), remove the `weed mount` start command and deploy. Zerops mounts the storage on the next container start as before.
----------------------------------------
@@ -6159,12 +6065,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Rust > How To > Shared Storage
-
-
-
----------------------------------------
# Rust > How To > Scaling
@@ -6345,7 +6245,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -7644,12 +7544,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Ruby > How To > Shared Storage
-
-
-
----------------------------------------
# Ruby > How To > Scaling
@@ -7831,7 +7725,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -9683,12 +9577,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Python > How To > Shared Storage
-
-
-
----------------------------------------
# Python > How To > Scaling
@@ -9869,7 +9757,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -12067,12 +11955,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Php > How To > Shared Storage
-
-
-
----------------------------------------
# Php > How To > Scaling
@@ -12537,7 +12419,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -14557,12 +14439,6 @@ If your build process seems to be hanging or timing out, check your logs for int
-----------------------------------------
-
-# Nodejs > How To > Shared Storage
-
-
-
----------------------------------------
# Nodejs > How To > Scaling
@@ -14742,7 +14618,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -16000,12 +15876,6 @@ Zerops provides built-in prerender.io support. Simply set the `PRERENDER_TOKEN`
-----------------------------------------
-
-# Nginx > How To > Shared Storage
-
-
-
----------------------------------------
# Nginx > How To > Scaling
@@ -16227,7 +16097,7 @@ Zerops caches custom runtime images to optimize deployment times. Learn about [c
For information about managing builds and deployments, see [managing builds and deployments](/features/pipeline#manage-builds-and-deployments).
:::warning
-Shared storage mounts and Local Storage volumes are not available during the runtime prepare phase.
+Local Storage volumes are not available during the runtime prepare phase, and start commands (such as a SeaweedFS mount) do not run there.
:::
## Troubleshooting
@@ -18707,7 +18577,7 @@ All connected containers run on the same physical machine and share one kernel,
- **Atomic rename and `O_APPEND`** behave exactly as on a local disk
- **inotify propagates across containers**: file watchers in one container see events triggered from another
-This is why filesystem-based databases (SQLite, Prometheus TSDB) are safe on Local Storage while they are explicitly unsafe on [Shared Storage](/shared-storage/overview#use-cases) or any other network filesystem.
+This is why filesystem-based databases (SQLite, Prometheus TSDB) are safe on Local Storage while they are explicitly unsafe on [SeaweedFS](/seaweedfs/overview#storage-engine-behavior) or any other network filesystem.
:::note Single-writer restrictions still apply
Correct locking makes concurrent access *safe*, not concurrent writes *possible*. SQLite still allows only one writer at a time — additional writers block or fail with `SQLITE_BUSY`, exactly as they would for two processes on one machine. A single-writer setup therefore remains the most robust pattern for SQLite and similar embedded databases: keep writes in one service (and ideally one container), and mount the volume with the [`readOnly` option](/local-storage/how-to/connect#the-volume-field) everywhere else to enforce it.
@@ -18783,9 +18653,9 @@ Automated [backups](/local-storage/how-to/manage#backups) are enabled by default
## Choosing a storage type
-Local Storage trades high availability for correctness and speed: it is the only storage type where lock-dependent workloads like databases are safe. An HA mode may be added in the future. See [Storage on Zerops](/storage/overview) for a comparison with Object Storage and Shared Storage and guidance on which one to use.
+Local Storage trades high availability for correctness and speed: it is the only storage type where lock-dependent workloads like databases are safe. An HA mode may be added in the future. See [Storage on Zerops](/storage/overview) for a comparison with Object Storage and SeaweedFS and guidance on which one to use.
-Already on Shared Storage? Follow the [migration guide](/local-storage/how-to/migrate-from-shared-storage) to move your data to a Local Storage volume without changing your application.
+Already on the deprecated Shared Storage? Follow the [migration guide](/local-storage/how-to/migrate-from-shared-storage) to move your data to a Local Storage volume without changing your application, or keep the data where it is and [mount it as SeaweedFS](/seaweedfs/how-to/migrate-from-shared-storage).
## Key trade-offs
@@ -18816,24 +18686,24 @@ Stuck, or want to share what you built? Our core team and community are on Disco
# Local Storage > How To > Migrate From Shared Storage
-[Shared Storage](/shared-storage/overview) is deprecated. This guide moves the data of an existing Shared Storage service to a new Local Storage volume and switches your runtime services over to it. The new volume is mounted at the **same path** the shared storage used (`/mnt/`), so your application code and configuration stay untouched.
+[Shared Storage](/shared-storage/overview) is deprecated, and existing Shared Storage services have been converted into [SeaweedFS](/seaweedfs/overview) services. If you only want to keep using them, follow the [SeaweedFS migration guide](/seaweedfs/how-to/migrate-from-shared-storage) instead. This guide moves the data off the network filesystem to a new Local Storage volume and switches your runtime services over to it. The new volume is mounted at the **same path** the shared storage used (`/mnt/`), so your application code and configuration stay untouched.
The migration in short:
1. Stop everything that writes to the shared storage.
2. Create the Local Storage service and a temporary migrator service that mounts both storages.
3. Copy the data from the old mount to the new one.
-4. Disconnect the shared storage from all services and stop it.
+4. Remove the shared storage mounts from all services and stop it.
5. Mount the new volume in your runtime services at the old path and deploy.
6. Verify, then delete the migrator and the shared storage.
-Throughout the guide, `volume` is the hostname of the **old Shared Storage** service and `volume2` the hostname of the **new Local Storage** service. Replace them with your own.
+Throughout the guide, `volume` is the hostname of the **old Shared Storage** service (now a SeaweedFS service) and `volume2` the hostname of the **new Local Storage** service. Replace them with your own.
## Before you start
Local Storage is a different kind of storage than the network filesystem it replaces — read its [key trade-offs](/local-storage/overview#key-trade-offs) before you migrate. One consequence for the migration: a runtime service mounts at most one Local Storage volume, so if a service mounts several shared storages, copy them into subdirectories of a single volume and point your application at the new paths.
-Take a fresh [backup](/shared-storage/how-to/manage#backups) of the shared storage before you begin.
+Take a fresh [backup](/seaweedfs/overview#backup-and-recovery) of the shared storage before you begin.
## 1. Stop all writers
@@ -18845,7 +18715,7 @@ Files that change while they are being copied end up inconsistent on the new vol
## 2. Create the Local Storage and a migrator service
-Import the new Local Storage service together with a temporary `fsmigrator` service that has **both** storages mounted: the old shared storage through the import-level `mount` field, and the new volume through the `volume` field in its inline `zeropsYaml`.
+Import the new Local Storage service together with a temporary `fsmigrator` service that has **both** storages mounted: the new volume through the `volume` field in its inline `zeropsYaml`, and the old shared storage through a [`weed mount` start command](/seaweedfs/overview#mounting-from-a-runtime-service).
```yaml title="zerops-import.yaml"
services:
@@ -18865,9 +18735,10 @@ services:
volume:
# Hostname of the new Local Storage service.
hostname: volume2
- mount:
- # Hostname of the old Shared Storage service.
- - volume
+ startCommands:
+ # Mount the old Shared Storage service (hostname volume) at /mnt/volume.
+ - name: volume
+ command: sudo zsc shared-storage mount volume
# Start the container without deploying any code.
startWithoutCode: true
```
@@ -18908,11 +18779,11 @@ find /mnt/volume -type f | wc -l; find /mnt/volume2 -type f | wc -l
`du` and `df` can report misleading numbers for the shared storage mount. If the totals differ, compare file counts or run `diff -r /mnt/volume /mnt/volume2` before you worry about it.
:::
-## 4. Disconnect and stop the shared storage
+## 4. Remove the shared storage mounts and stop it
-On the shared storage service detail page, open **Shared storage connections** and toggle **off** every connected runtime service, including `fsmigrator`. Then stop the shared storage service.
+On every runtime service that still has the old managed mount, open **Environment variables** and delete the `zeropsSharedStorageMounts` variable (or remove `volume` from its `|`-separated list if the service mounts other storages too). This is applied live: the mount disappears from the running containers without a restart. Stop the `fsmigrator` service as well, then stop the shared storage service.
-Disconnecting is applied live and does not restart the runtime containers. Keep the service stopped rather than deleted for now — it is your rollback path until the new volume is verified.
+Keep the shared storage stopped rather than deleted for now — it is your rollback path until the new volume is verified.
## 5. Mount the new volume in your runtime services
@@ -18933,13 +18804,13 @@ zerops:
Deploy each service with the changed `zerops.yaml` (`zcli push`, or trigger your pipeline). The volume is mounted in the new containers at `/mnt/volume`, exactly where the shared storage used to be. See [Mount to a service](/local-storage/how-to/connect) for the full `volume` field reference.
-If you keep your infrastructure in a `zerops-import.yaml` or a template, update it as well: replace the `shared-storage` service with the `local-storage:single@1` service and remove the `mount` field from the runtime services.
+If you keep your infrastructure in a `zerops-import.yaml` or a template, update it as well: replace the `shared-storage` / `seaweedfs` service with the `local-storage:single@1` service and remove the `mount` field (or any `weed mount` start command) from the runtime services.
## 6. Verify
Start the runtime services you stopped in step 1 (if they did not start with the deploy) and check that the application works — read an existing file, write a new one, and confirm the results in the [Local Storage container](/local-storage/how-to/manage#access-the-volume-directly), where the volume is mounted at `/data`.
-If something is wrong, you can roll back: remove the `volume` field from `zerops.yaml`, deploy, start the shared storage service and reconnect it to the runtime services.
+If something is wrong, you can roll back: remove the `volume` field from `zerops.yaml`, deploy, start the shared storage service and put its hostname back into the `zeropsSharedStorageMounts` variable of the runtime services (or mount it with a `weed mount` start command).
## 7. Clean up
@@ -19937,12 +19808,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Java > How To > Shared Storage
-
-
-
----------------------------------------
# Java > How To > Scaling
@@ -20123,7 +19988,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -21571,54 +21436,87 @@ A change to `envSecrets` requires a **service restart** to take effect.
----------------------------------------
-# Guides > Shared Storage Integration
-
-
-**DEPRECATED**: Shared Storage is deprecated and will be replaced by a standalone SeaweedFS managed service mounted with `zsc shared-storage mount` in `initCommands`. For new projects, prefer **[Local Storage](/local-storage/overview)** (`run.volume` in zerops.yaml) for a persistent shared filesystem, or **Object Storage** for large or highly available data. Existing Shared Storage services keep working; move them with the [migration guide](/local-storage/how-to/migrate-from-shared-storage).
+# Guides > Seaweedfs Integration
-Shared storage is a managed SeaweedFS volume mounted as a POSIX filesystem at `/mnt/` into one or more runtime services — for files that must be shared *between containers/services* (shared config, plugin directories, a common working set). It is mounted via the import.yaml `mount:` field; there is **no `zerops.yaml` mount** (do not confuse it with `run.volume`, which mounts a Local Storage volume). For high-write workloads or user uploads, prefer Object Storage (S3) instead — shared storage is POSIX/NFS-style and not built for high-throughput churn.
-## Mounting — import.yaml `mount:` is the only config-file mechanism
+Managed SeaweedFS cluster (`seaweedfs:ha@3.85` / `seaweedfs:single@3.85`) exposing an unauthenticated filer at `.zerops:8888`. Zerops does not mount it into runtimes — the runtime mounts it with `weed mount` in `run.startCommands` (or uses the filer HTTP API). Replaces the deprecated [Shared Storage](/shared-storage/overview). Human-facing docs: [SeaweedFS](/seaweedfs/overview).
-Declare the storage service, then list it under the runtime's service-level `mount:`. This auto-connects the storage at provision — import alone is sufficient, no second step:
+## Service
```yaml
services:
- hostname: storage
- type: shared-storage
- - hostname: app
- type: nodejs@22
- buildFromGit: https://github.com/myorg/myapp # mount: requires buildFromGit
- mount:
- - storage # list one or more shared-storage hostnames
+ type: seaweedfs:ha@3.85 # 2 containers, replicated. seaweedfs:single@3.85 = 1 container
```
-After deploy, the runtime has `/mnt/storage` (SeaweedFS FUSE, writable). Multiple volumes can be mounted to one service (`/mnt/files1`, `/mnt/files2`, …).
+- Mode is part of the type and immutable. `shared-storage:ha` / `shared-storage:single` are accepted aliases.
+- Env vars generated on the service: `hostname` (`storage`), `port` (`8888`). Reference cross-service as `${storage_hostname}`, `${storage_port}`. No credentials — the filer is unauthenticated, reachable only on the project network and over VPN. Cannot be exposed via `enableSubdomainAccess` or public routing.
+- Endpoints: filer HTTP `http://storage.zerops:8888`, filer gRPC `storage.zerops:18888`, per-container filer `node-stable-<1|2>.db.storage.zerops:8888`. Master (`9333`) and volume (`8080`) servers are internal.
+- Vertical autoscaling only (defaults RAM 0.5 GB, disk 5 GB min); data capacity capped at **60 GB** regardless of disk. Backups: `.tar.gz` of the whole filesystem, restore by extracting through a mount.
+
+## Mounting from a runtime (zerops.yaml)
+
+Every runtime image ships `/opt/zerops/bin/weed-3-85`. Run `weed mount` as an extra `startCommands` entry; it stays in the foreground and Zerops restarts it if it exits:
-**There is NO `zerops.yaml` mount field.** A `mount:` under `run:` is silently stripped by the platform — it even passes yaml validation (validation-passing ≠ honored), but produces no mount and no connection. Mounting is import.yaml-only (or `connect-storage`, below).
+```yaml
+zerops:
+ - setup: app
+ run:
+ base: nodejs@22
+ startCommands:
+ - name: app
+ command: npm start
+ - name: storage
+ initCommands:
+ - sudo mkdir -p /mnt/storage
+ - sudo chown zerops:zerops /mnt/storage
+ command: sudo /opt/zerops/bin/weed-3-85 mount -filer=node-stable-1.db.storage.zerops:8888 -dir=/mnt/storage -cacheCapacityMB=0 -concurrentWriters=1 -chunkSizeLimitMB=1
+```
+
+- `sudo` is passwordless on Ubuntu and Alpine runtimes. The three trailing flags cap the mount process at ~100-150 MB RAM; drop them for throughput if RAM allows. `-filer` targets one container's filer; in HA mode `node-stable-2` works too (same metadata).
+- Shortcut with identical flags, mounts at `/mnt/` against `node-stable-1`: `command: sudo zsc shared-storage mount storage`.
+- The mount exists only in running containers: not during build, not during `run.prepareCommands`. There is no `run.mount` field and no import-level `mount:` (rejected with `yamlMountDeprecated`).
+- Every container of the service mounts independently; all see the same files.
-## Connecting a storage to a runtime that missed the import mount
+### Mount in initCommands (when init commands need the files)
-A runtime that was READY_TO_DEPLOY at import time (e.g. a stage service created but not yet deployed) does NOT pick up the import `mount:`. Once it's ACTIVE, connect explicitly:
+`startCommands` run after `initCommands`, so mount in the background from the init commands when they need the storage:
+```yaml
+ initCommands:
+ - sudo zsc shared-storage mount storage --background # mounts /mnt/storage, returns when ready
+ - cp /mnt/storage/certs/app.pem /var/www/app.pem
```
-zerops_manage action="connect-storage" serviceHostname="app" storageHostname="storage"
+
+Raw form with options (`weed fuse` accepts every `weed mount` flag as `-o`): `sudo /opt/zerops/bin/weed-3-85 fuse /mnt/certs -o "filer=node-stable-1.db.storage.zerops:8888,filer.path=/certs,readOnly=true,cacheCapacityMB=0,concurrentWriters=1,chunkSizeLimitMB=1"` (create + chown the dir first). Both detach a `weed mount` child; it is re-created on every container start (init commands rerun) but **not restarted if it dies** - prefer the start command form unless init commands need the mount.
+
+Useful options: `filer=a:8888,b:8888` (list both HA containers), `filer.path=/sub` (mount a subtree per service), `readOnly=true`, `allowOthers=false`.
+
+## Filer HTTP API (no mount)
+
+```sh
+curl -F "file=@report.pdf" http://storage.zerops:8888/reports/2026/ # upload, creates dirs
+curl -o report.pdf http://storage.zerops:8888/reports/2026/report.pdf # download
+curl -H "Accept: application/json" http://storage.zerops:8888/reports/2026/ # list
+curl -X DELETE http://storage.zerops:8888/reports/2026/report.pdf # delete
```
-This registers the connection, but the FUSE mount materializes **only on the next fresh deploy (new container creation)** — a plain restart does NOT bring it up. Redeploy the service after connecting.
+HTTP uploads are limited to 64 MB per file; mounted writes are chunked and unlimited within capacity.
-## Constraints & behavior
+## Constraints
-- **Mount path**: always `/mnt/`. Runtime containers only — NOT available during build or `run.prepareCommands` phases.
-- **Mounting overwrites** any existing content in the mount directory.
-- **Capacity**: max 60 GB total (raise via support request); file size is unbounded within the 60 GB. `verticalAutoscaling` floors: RAM 0.5 GB, disk 5 GB.
-- **HA**: 1:1 replication with auto-failover; during a master failover the mount is briefly unavailable (~30s).
-- **POSIX**: standard filesystem ops (with minor permission-setting limits). Filesystem operations are logged to runtime logs tagged `zerops-mount-`. `df` can report misleading numbers — use the Zerops GUI for accurate storage metrics.
-- **No env vars**: shared storage exposes no connection variables — it's a filesystem, not a networked service.
+- **Not for databases.** Locks (`flock`, POSIX) are enforced per mount only; the store is append-only (write amplification on small rewrites). SQLite, Prometheus TSDB etc. belong on [Local Storage](/local-storage/overview).
+- Higher latency than local disk; avoid huge trees of tiny files; batch writes.
+- `df` inside the mount is misleading; use the GUI for usage.
+- HA failover: master container replacement makes the cluster unavailable ~30 s.
-## Shared storage vs local storage vs object storage
+## Migrating from Shared Storage
-Use **local storage** (`run.volume`) when you need a persistent POSIX filesystem — it is a real single-node local filesystem with correct locking and mmap semantics, so it also covers SQLite and other filesystem-based databases that are unsafe on shared storage. Use **shared storage** (deprecated) only for existing setups that need the filesystem replicated across nodes. Use **object storage** (S3/MinIO) for user uploads, media, and any high-throughput or write-heavy file operations — and for anything that must survive independent of any single service. Don't reach for shared storage as a generic uploads bucket.
+Existing Shared Storage services are already SeaweedFS services (converted in place, same hostname and data). Their old runtime mounts persist as the `zeropsSharedStorageMounts` env on the runtime service (`|`-separated hostnames, mounted at `/mnt/` on container start, best-effort, with a deprecation warning in runtime logs). Migration = add the `startCommands` mount above at the same `/mnt/` path, delete the env (applied live, unmounts immediately), deploy. Delete the env **before** the deploy so the two mounts do not target the same directory. Details: [migration guide](/seaweedfs/how-to/migrate-from-shared-storage).
+
+## SeaweedFS vs Local Storage vs Object Storage
+
+See [Choosing Storage](/guides/choose-storage). Short form: Object Storage for uploads/media/backups; Local Storage for anything lock-dependent or single-node stateful; SeaweedFS for an HA network filesystem shared between services where per-mount locking is acceptable.
----------------------------------------
@@ -21626,7 +21524,7 @@ Use **local storage** (`run.volume`) when you need a persistent POSIX filesystem
# Guides > Scaling
-Zerops autoscales vertically (CPU/RAM/disk) and horizontally (container count). Runtimes support both. Managed services (DB, cache, shared-storage) support vertical only with fixed container count (the `:single` type variant = 1 node, `:ha` = 3). Object-storage and Docker have no autoscaling. Extends grammar.md section 9 with mechanics, thresholds, YAML syntax, and common mistakes.
+Zerops autoscales vertically (CPU/RAM/disk) and horizontally (container count). Runtimes support both. Managed services (DB, cache, SeaweedFS) support vertical only with fixed container count (the `:single` type variant = 1 node, `:ha` = 3, SeaweedFS `:ha` = 2). Object-storage and Docker have no autoscaling. Extends grammar.md section 9 with mechanics, thresholds, YAML syntax, and common mistakes.
## When to Scale Which Way
@@ -21646,7 +21544,7 @@ Zerops autoscales vertically (CPU/RAM/disk) and horizontally (container count).
| **Linux containers** (Alpine, Ubuntu) | Yes | Yes (1-10 containers) | Same as runtimes |
| **Managed DB** (PostgreSQL, MariaDB) | Yes | No (fixed: `:single`=1, `:ha`=3) | Variant immutable after creation |
| **Managed cache** (Valkey) | Yes | No (fixed: `:single`=1, `:ha`=3) | Variant immutable after creation |
-| **Shared storage** | Yes (cpu/ram/disk configurable) | No (fixed: `:single`=1, `:ha`=3) | Accepts verticalAutoscaling in import.yml |
+| **SeaweedFS** | Yes (cpu/ram/disk configurable) | No (fixed: `:single`=1, `:ha`=2) | Accepts verticalAutoscaling in import.yml, data capacity capped at 60 GB regardless of disk |
| **Object storage** | No | No | Fixed size at creation, no verticalAutoscaling |
| **Docker** | No (manual, triggers VM restart) | Manual only (change VM count, triggers restart) | No automatic autoscaling |
| **Docker** | No (manual, triggers VM restart) | Manual only (change VM count, triggers restart) | No automatic autoscaling |
@@ -21738,15 +21636,15 @@ Applies to **runtimes and Linux containers only**. New containers are added when
**HA requirement**: applications must be stateless and handle distributed operation (no local file sessions, no local uploads).
-### Managed Services (DB, Cache, Shared Storage)
+### Managed Services (DB, Cache, SeaweedFS)
Container count is **fixed by the deployment variant in the type** (`postgresql:single@18` / `postgresql:ha@18`), set at creation, **immutable**:
| Variant | Containers | Use case |
|---|---|---|
| `:single` | 1 | Development, non-critical |
-| `:ha` | 3 (on separate physical machines) | Production, automatic failover |
-| `:ha` | 3 (on separate physical machines) | Production, automatic failover |
+| `:ha` | 3 (on separate physical machines), 2 for SeaweedFS | Production, automatic failover |
+| `:ha` | 3 (on separate physical machines), 2 for SeaweedFS | Production, automatic failover |
**Legacy form** you may still see in older YAML: a separate `mode:` field — `mode: NON_HA` ≡ `:single`, `mode: HA` ≡ `:ha`. Still accepted (remapped to the variant) but deprecated and ignored by validation.
@@ -23079,7 +22977,7 @@ When using SSHFS (`zerops_mount`) for dev workflows, deploy replaces the contain
**Three kinds of "mount" (disambiguation):**
- `zerops_mount` -- SSHFS tool, mounts service `/var/www` locally for development. This is a dev workflow tool.
-- Shared storage mount (deprecated) -- platform feature, attaches a shared-storage volume at `/mnt/{hostname}` via the service-level `mount:` parameter in import.yml. There is no `mount` field in zerops.yml (a `run.mount` is silently ignored). These are completely unrelated features.
+- SeaweedFS mount -- `weed mount` (or `zsc shared-storage mount `) run as a `run.startCommands` entry in zerops.yml, mounts a [SeaweedFS](/seaweedfs/overview) service's filer at a directory of your choice. There is no `mount` field in zerops.yml (a `run.mount` is silently ignored) and the import-level `mount:` of the deprecated Shared Storage is rejected. These are completely unrelated features.
- Local Storage volume -- platform feature, mounts a Local Storage service's persistent volume via the `run.volume` field in zerops.yml (`volume: {hostname, mountPath, readOnly}`). The volume survives deploys: new containers get the same volume attached at the configured `mountPath`.
@@ -23228,7 +23126,7 @@ Any CI system with shell access can deploy via `zcli push`:
# Guides > Choose Storage
-**Use Object Storage** (S3) for uploads, media, and backups. **Use Local Storage** (`run.volume`) for anything that needs a real filesystem — SQLite and other embedded databases, single-node stateful apps, filesystem state shared between services. **Shared Storage is deprecated** — don't use it in new projects. Human-facing comparison: [Storage on Zerops](/storage/overview).
+**Use Object Storage** (S3) for uploads, media, and backups. **Use Local Storage** (`run.volume`) for anything that needs a real filesystem — SQLite and other embedded databases, single-node stateful apps, filesystem state shared between services. **Use SeaweedFS** when the shared filesystem must be highly available and the per-mount locking of a network filesystem is acceptable — the runtime mounts it from `run.startCommands`. **Shared Storage is deprecated** — existing services were converted to SeaweedFS. Human-facing comparison: [Storage on Zerops](/storage/overview).
## Decision Matrix
@@ -23238,9 +23136,10 @@ Any CI system with shell access can deploy via `zcli push`:
| SQLite / Prometheus / filesystem-based databases | **Local Storage** | Single-kernel POSIX: locking and mmap are correct — the only Zerops storage where these workloads are safe |
| Single-node stateful app (Gitea, etc.) | **Local Storage** | Persistent volume survives deploys and container replacement |
| Filesystem state shared between services (certs, caches) | **Local Storage** | One volume mountable by multiple runtime services, writes visible immediately |
+| HA filesystem shared between services, no lock-dependent workloads | **SeaweedFS** | Replicated managed cluster, mounted by the runtime itself via `weed mount` in `run.startCommands`, or used over the filer HTTP API |
| Temp/scratch files | Container disk | Fine as-is; lost on deploy |
-| Existing `mount:`-based setups | Shared Storage (deprecated) | Keeps working; [migrate to Local Storage](/local-storage/how-to/migrate-from-shared-storage) or Object Storage |
-| Existing `mount:`-based setups | Shared Storage (deprecated) | Keeps working; [migrate to Local Storage](/local-storage/how-to/migrate-from-shared-storage) or Object Storage |
+| Existing Shared Storage (`mount:`-based) setups | SeaweedFS (already converted) | Old mounts keep working via the `zeropsSharedStorageMounts` env; [take over the mount](/seaweedfs/how-to/migrate-from-shared-storage) or [migrate to Local Storage](/local-storage/how-to/migrate-from-shared-storage) |
+| Existing Shared Storage (`mount:`-based) setups | SeaweedFS (already converted) | Old mounts keep working via the `zeropsSharedStorageMounts` env; [take over the mount](/seaweedfs/how-to/migrate-from-shared-storage) or [migrate to Local Storage](/local-storage/how-to/migrate-from-shared-storage) |
## Local Storage
@@ -23255,9 +23154,13 @@ Any CI system with shell access can deploy via `zcli push`:
See the [object-storage integration guide](/guides/object-storage-integration): S3-compatible (MinIO), `objectStorageSize` quota, `AWS_USE_PATH_STYLE_ENDPOINT: true`, `${storage_*}` env var references. Not a filesystem — no locking, no partial writes, no mmap.
+## SeaweedFS
+
+See the [SeaweedFS integration guide](/guides/seaweedfs-integration): service type `seaweedfs:ha@3.85` / `seaweedfs:single@3.85`, exposes the filer at `.zerops:8888` (HTTP API + FUSE via `weed mount`), no credentials. Zerops runs the cluster; mounting is the runtime's job (`run.startCommands` entry running `sudo /opt/zerops/bin/weed-3-85 mount ...` or `zsc shared-storage mount `). Per-mount-only locks and an append-only store make databases unsafe on it — that workload belongs on Local Storage. Data capacity is capped at 60 GB.
+
## Shared Storage (deprecated)
-A managed SeaweedFS cluster mounted at `/mnt/` via the import-level `mount:` field. Deprecated: it will be replaced by a standalone SeaweedFS managed service mounted with `zsc shared-storage mount` in `initCommands`. Its per-mount-only locks make databases unsafe on it — that workload belongs on Local Storage. Existing services keep working.
+Retired service type. Every existing Shared Storage service was converted in place into a SeaweedFS service (same containers, data and hostname). The GUI **Shared storage connections** page and the import-level `mount:` field are gone (`mount:` now fails with `yamlMountDeprecated`); the old runtime mounts survive as the `zeropsSharedStorageMounts` env (`|`-separated hostnames, mounted at `/mnt/` on container start, best-effort, with a deprecation warning in the runtime log). Migration: add the `weed mount` start command, delete the env, deploy — see the [migration guide](/seaweedfs/how-to/migrate-from-shared-storage).
----------------------------------------
@@ -23598,7 +23501,7 @@ Any change to these zerops.yml fields invalidates **both layers**:
Zerops auto-backs up databases and storage daily (00:00-01:00 UTC) with X25519 encryption; backups are retained for 7 days minimum after service/project deletion.
## Supported Services
-MariaDB, PostgreSQL, Qdrant, Elasticsearch, NATS, Meilisearch, Local Storage, Shared Storage.
+MariaDB, PostgreSQL, Qdrant, Elasticsearch, NATS, Meilisearch, Local Storage, SeaweedFS.
**ClickHouse**: not on the standard auto-backup path — back it up with the native `BACKUP ALL ...` SQL command (super user), stored as `.tar.gz`.
@@ -23644,8 +23547,8 @@ End-to-end with X25519 per-project keys. Decrypted only on download.
| Qdrant | `.snapshot` |
| NATS | `.tar.gz` |
| Local Storage | tar → `.tar.gz` (archive of the live volume — pause database writes or use an application-level backup for guaranteed consistency) |
-| Shared Storage | tar → `.tar.gz` |
-| Shared Storage | tar → `.tar.gz` |
+| SeaweedFS | tar → `.tar.gz` (archive of the whole filesystem, restore by extracting through a mount) |
+| SeaweedFS | tar → `.tar.gz` (archive of the whole filesystem, restore by extracting through a mount) |
## Gotchas
- Valkey/KeyDB are not backed up → rely on service persistence or application-level backup.
@@ -23741,12 +23644,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Go > How To > Shared Storage
-
-
-
----------------------------------------
# Go > How To > Scaling
@@ -23927,7 +23824,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -25178,12 +25075,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Gleam > How To > Shared Storage
-
-
-
----------------------------------------
# Gleam > How To > Scaling
@@ -25363,7 +25254,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -26527,7 +26418,7 @@ Unlike traditional hosting where resources must be predicted and pre-provisioned
Zerops uses two fundamentally different approaches for optimizing infrastructure:
#### **Resource Management (Vertical Scaling)**
-- **Applies to:** Runtime services, databases, local and shared storage, and Linux containers (Alpine and Ubuntu)
+- **Applies to:** Runtime services, databases, Local Storage and SeaweedFS, and Linux containers (Alpine and Ubuntu)
- **What it does:** Adjusts CPU, RAM, and disk resources within individual containers
- **Management:** Automated by Zerops, but customizable by users
@@ -26542,7 +26433,7 @@ Docker services do not support automatic vertical scaling. Resource values can b
- Container/VM creation limits can be controlled
- Docker containers run in VMs rather than native containers
-- **For Databases & Shared Storage:** High Availability Mode (fixed container count)
+- **For Databases & SeaweedFS:** High Availability Mode (fixed container count)
- Single Container OR Multi-Container HA configuration
- Must be chosen at service creation (cannot be changed later)
- Managed by Zerops (no application changes needed)
@@ -26556,7 +26447,7 @@ Docker services do not support automatic vertical scaling. Resource values can b
Feature |
Runtime Services & Linux Containers |
Databases |
- Shared Storage |
+ SeaweedFS |
Docker |
@@ -26593,7 +26484,7 @@ You can configure scaling settings at three different stages:
- **During import** - Use YAML configuration files to define comprehensive scaling settings including `verticalAutoscaling` parameters and horizontal scaling limits. See [Import & Export YAML Configuration](/references/import) for complete syntax.
-- **After service creation** - Modify most scaling settings anytime through your service's **Automatic scaling configuration** page. Note that some parameters like deployment mode for databases and shared storage cannot be changed after creation.
+- **After service creation** - Modify most scaling settings anytime through your service's **Automatic scaling configuration** page. Note that some parameters like deployment mode for databases and SeaweedFS cannot be changed after creation.
This flexibility lets you plan scaling strategies upfront or adapt them as requirements evolve.
@@ -26601,7 +26492,7 @@ This flexibility lets you plan scaling strategies upfront or adapt them as requi
Resource management in Zerops focuses on efficiently allocating and adjusting CPU, RAM, and disk resources within individual containers based on actual usage patterns.
-These resource management capabilities apply to **runtime** services, **databases**, **shared storage**, and **Linux containers** (Alpine and Ubuntu).
+These resource management capabilities apply to **runtime** services, **databases**, **SeaweedFS**, and **Linux containers** (Alpine and Ubuntu).
:::note
Docker services do not support automatic vertical scaling. Resources for Docker services are fixed at the values set manually and do not automatically adjust based on usage.
@@ -26772,7 +26663,7 @@ Below are the parameters that control this behavior across all services that sup
Container architecture in Zerops defines how services are distributed across containers. Different service types use fundamentally different approaches:
1. **Horizontal Scaling** (Runtime Services, Linux Containers, and Docker)
-2. **Deployment Modes** (Databases and Shared Storage)
+2. **Deployment Modes** (Databases and SeaweedFS)
### Horizontal Scaling (Runtime Services, Linux Containers, and Docker)
@@ -26795,9 +26686,9 @@ To configure horizontal scaling, users need to set the minimum and maximum numbe
Setting identical minimum and maximum values creates a fixed number of containers (disables automatic horizontal scaling).
:::
-### Deployment Modes (Databases and Shared Storage)
+### Deployment Modes (Databases and SeaweedFS)
-For databases and shared storage services, Zerops offers two deployment modes focused on reliability and data integrity.
+For databases and SeaweedFS services, Zerops offers two deployment modes focused on reliability and data integrity.
:::warning
Deployment mode cannot be changed after creation.
@@ -26829,7 +26720,7 @@ Highly Available (HA) Mode creates multiple containers with built-in redundancy.
- Recommended for production use
:::important
-Database and shared storage services in HA mode have a **fixed number of containers** that cannot be increased or decreased.
+Database and SeaweedFS services in HA mode have a **fixed number of containers** that cannot be increased or decreased.
:::
**Recovery process:**
@@ -27645,7 +27536,7 @@ Learn more about building custom runtime images:
:::warning
Do not include your application code in the custom runtime image, as your built application code is deployed automatically into fresh containers.
-Shared storage mounts and Local Storage volumes are also not available during the runtime prepare phase.
+Local Storage volumes are also not available during the runtime prepare phase, and start commands (such as a SeaweedFS mount) do not run there.
:::
## Deploy phase
@@ -28828,7 +28719,7 @@ ZCP supports multiple coding agents including Claude Code (Anthropic), Codex (Op
### An ordinary Zerops project underneath
-The agent operates inside a normal Zerops project — same shape as production. Managed databases (PostgreSQL, MariaDB, ClickHouse), key-value stores (KeyDB, Valkey), search (Elasticsearch, Meilisearch, Typesense), vector store (Qdrant), message queues (NATS, Kafka), object, local and shared storage, managed Nginx — all on a private network, addressable by hostname. The same pipeline that deploys here can deploy to a separate HA production project with no `zcp` service attached. Not a sandbox the work outgrows.
+The agent operates inside a normal Zerops project — same shape as production. Managed databases (PostgreSQL, MariaDB, ClickHouse), key-value stores (KeyDB, Valkey), search (Elasticsearch, Meilisearch, Typesense), vector store (Qdrant), message queues (NATS, Kafka), object storage, Local Storage and SeaweedFS, managed Nginx — all on a private network, addressable by hostname. The same pipeline that deploys here can deploy to a separate HA production project with no `zcp` service attached. Not a sandbox the work outgrows.
### Human ↔ agent handover
@@ -29624,7 +29515,7 @@ Zerops provides an automated, secure backup system for supported services. This
## Supported Services
-Zerops provides automated backup functionality for the following services. For specific backup format details and restore instructions, visit each service's documentation: [MariaDB](/mariadb/how-to/backup), [PostgreSQL](/postgresql/how-to/manage#backups), [Qdrant](/qdrant/overview), [Elasticsearch](/elasticsearch/overview), [NATS](/nats/overview), [Meilisearch](/meilisearch/overview), [Local Storage](/local-storage/how-to/manage#backups), and [Shared Storage](/shared-storage/how-to/manage#backups).
+Zerops provides automated backup functionality for the following services. For specific backup format details and restore instructions, visit each service's documentation: [MariaDB](/mariadb/how-to/backup), [PostgreSQL](/postgresql/how-to/manage#backups), [Qdrant](/qdrant/overview), [Elasticsearch](/elasticsearch/overview), [NATS](/nats/overview), [Meilisearch](/meilisearch/overview), [Local Storage](/local-storage/how-to/manage#backups), and [SeaweedFS](/seaweedfs/overview#backup-and-recovery).
## Managing Backups in the UI
@@ -30062,12 +29953,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Elixir > How To > Shared Storage
-
-
-
----------------------------------------
# Elixir > How To > Scaling
@@ -30247,7 +30132,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -31584,12 +31469,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Dotnet > How To > Shared Storage
-
-
-
----------------------------------------
# Dotnet > How To > Scaling
@@ -31770,7 +31649,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -33342,12 +33221,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Deno > How To > Shared Storage
-
-
-
----------------------------------------
# Deno > How To > Scaling
@@ -33442,7 +33315,7 @@ Zerops caches custom runtime images to optimize deployment times. Learn about [c
For information about managing builds and deployments, see [managing builds and deployments](/features/pipeline#manage-builds-and-deployments).
:::warning
-Shared storage mounts and Local Storage volumes are not available during the runtime prepare phase.
+Local Storage volumes are not available during the runtime prepare phase, and start commands (such as a SeaweedFS mount) do not run there.
:::
## Troubleshooting
@@ -33592,7 +33465,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -35192,12 +35065,6 @@ Have you build something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Bun > How To > Shared Storage
-
-
-
----------------------------------------
# Bun > How To > Scaling
@@ -35377,7 +35244,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
@@ -36581,12 +36448,6 @@ Have you built something that others might find useful? Don't hesitate to share
-----------------------------------------
-
-# Alpine > How To > Shared Storage
-
-
-
----------------------------------------
# Alpine > How To > Scaling
@@ -36668,7 +36529,7 @@ Zerops caches custom runtime images to optimize deployment times. Learn about [c
For information about managing builds and deployments, see [managing builds and deployments](/features/pipeline#manage-builds-and-deployments).
:::warning
-Shared storage mounts and Local Storage volumes are not available during the runtime prepare phase.
+Local Storage volumes are not available during the runtime prepare phase, and start commands (such as a SeaweedFS mount) do not run there.
:::
## Troubleshooting
@@ -36819,7 +36680,7 @@ S3_ACCESS_KEY_ID="P8cX1vVVb"
S3_ACCESS_SECRET="ogFthuiLYki8XoL73opSCQ"
```
-The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode)(/features/scaling#deployment-modes-databases-and-shared-storage) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
+The hostname of the PostgreSQL service will be set to "db". The [single container](/features/scaling#single-container-mode) mode will be chosen and the default auto [scaling configuration](/postgresql/how-to/scale#configure-scaling) will be set.
#### Description of description.yaml parameters
diff --git a/apps/docs/static/llms.txt b/apps/docs/static/llms.txt
index 104c875ee..364d10655 100644
--- a/apps/docs/static/llms.txt
+++ b/apps/docs/static/llms.txt
@@ -4,7 +4,7 @@
## Docs
-- [Full Docs](https://docs.zerops.io/llms-full.txt): The complete documentation as a single file (357 pages, no images).
+- [Full Docs](https://docs.zerops.io/llms-full.txt): The complete documentation as a single file (340 pages, no images).
- [Core Docs](https://docs.zerops.io/llms-small.txt): The same, trimmed to the core platform — excludes API/CLI references, company and help pages.
Every page below is also reachable in its rendered form by dropping the `.md`
@@ -37,7 +37,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Ubuntu > Overview](https://docs.zerops.io/ubuntu/overview.md)
- [Ubuntu > How To > Upgrade](https://docs.zerops.io/ubuntu/how-to/upgrade.md)
- [Ubuntu > How To > Trigger Pipeline](https://docs.zerops.io/ubuntu/how-to/trigger-pipeline.md)
-- [Ubuntu > How To > Shared Storage](https://docs.zerops.io/ubuntu/how-to/shared-storage.md)
- [Ubuntu > How To > Scaling](https://docs.zerops.io/ubuntu/how-to/scaling.md)
- [Ubuntu > How To > Logs](https://docs.zerops.io/ubuntu/how-to/logs.md)
- [Ubuntu > How To > Filebrowser](https://docs.zerops.io/ubuntu/how-to/filebrowser.md)
@@ -51,15 +50,12 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Typesense > Overview](https://docs.zerops.io/typesense/overview.md)
- [Storage > Overview](https://docs.zerops.io/storage/overview.md)
- [Static > Overview](https://docs.zerops.io/static/overview.md)
-- [Shared Storage > Tech Details](https://docs.zerops.io/shared-storage/tech-details.md)
- [Shared Storage > Overview](https://docs.zerops.io/shared-storage/overview.md)
-- [Shared Storage > How To > Manage](https://docs.zerops.io/shared-storage/how-to/manage.md)
-- [Shared Storage > How To > Create](https://docs.zerops.io/shared-storage/how-to/create.md)
-- [Shared Storage > How To > Connect](https://docs.zerops.io/shared-storage/how-to/connect.md)
+- [Seaweedfs > Overview](https://docs.zerops.io/seaweedfs/overview.md)
+- [Seaweedfs > How To > Migrate From Shared Storage](https://docs.zerops.io/seaweedfs/how-to/migrate-from-shared-storage.md)
- [Rust > Overview](https://docs.zerops.io/rust/overview.md)
- [Rust > How To > Upgrade](https://docs.zerops.io/rust/how-to/upgrade.md)
- [Rust > How To > Trigger Pipeline](https://docs.zerops.io/rust/how-to/trigger-pipeline.md)
-- [Rust > How To > Shared Storage](https://docs.zerops.io/rust/how-to/shared-storage.md)
- [Rust > How To > Scaling](https://docs.zerops.io/rust/how-to/scaling.md)
- [Rust > How To > Logs](https://docs.zerops.io/rust/how-to/logs.md)
- [Rust > How To > Filebrowser](https://docs.zerops.io/rust/how-to/filebrowser.md)
@@ -73,7 +69,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Ruby > Overview](https://docs.zerops.io/ruby/overview.md)
- [Ruby > How To > Upgrade](https://docs.zerops.io/ruby/how-to/upgrade.md)
- [Ruby > How To > Trigger Pipeline](https://docs.zerops.io/ruby/how-to/trigger-pipeline.md)
-- [Ruby > How To > Shared Storage](https://docs.zerops.io/ruby/how-to/shared-storage.md)
- [Ruby > How To > Scaling](https://docs.zerops.io/ruby/how-to/scaling.md)
- [Ruby > How To > Logs](https://docs.zerops.io/ruby/how-to/logs.md)
- [Ruby > How To > Filebrowser](https://docs.zerops.io/ruby/how-to/filebrowser.md)
@@ -113,7 +108,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Python > Overview](https://docs.zerops.io/python/overview.md)
- [Python > How To > Upgrade](https://docs.zerops.io/python/how-to/upgrade.md)
- [Python > How To > Trigger Pipeline](https://docs.zerops.io/python/how-to/trigger-pipeline.md)
-- [Python > How To > Shared Storage](https://docs.zerops.io/python/how-to/shared-storage.md)
- [Python > How To > Scaling](https://docs.zerops.io/python/how-to/scaling.md)
- [Python > How To > Logs](https://docs.zerops.io/python/how-to/logs.md)
- [Python > How To > Filebrowser](https://docs.zerops.io/python/how-to/filebrowser.md)
@@ -133,7 +127,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Php > Overview](https://docs.zerops.io/php/overview.md)
- [Php > How To > Upgrade](https://docs.zerops.io/php/how-to/upgrade.md)
- [Php > How To > Trigger Pipeline](https://docs.zerops.io/php/how-to/trigger-pipeline.md)
-- [Php > How To > Shared Storage](https://docs.zerops.io/php/how-to/shared-storage.md)
- [Php > How To > Scaling](https://docs.zerops.io/php/how-to/scaling.md)
- [Php > How To > Logs](https://docs.zerops.io/php/how-to/logs.md)
- [Php > How To > Filebrowser](https://docs.zerops.io/php/how-to/filebrowser.md)
@@ -155,7 +148,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Nodejs > Faq](https://docs.zerops.io/nodejs/faq.md)
- [Nodejs > How To > Upgrade](https://docs.zerops.io/nodejs/how-to/upgrade.md)
- [Nodejs > How To > Trigger Pipeline](https://docs.zerops.io/nodejs/how-to/trigger-pipeline.md)
-- [Nodejs > How To > Shared Storage](https://docs.zerops.io/nodejs/how-to/shared-storage.md)
- [Nodejs > How To > Scaling](https://docs.zerops.io/nodejs/how-to/scaling.md)
- [Nodejs > How To > Logs](https://docs.zerops.io/nodejs/how-to/logs.md)
- [Nodejs > How To > Filebrowser](https://docs.zerops.io/nodejs/how-to/filebrowser.md)
@@ -170,7 +162,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Nginx > Faq](https://docs.zerops.io/nginx/faq.md)
- [Nginx > How To > Upgrade](https://docs.zerops.io/nginx/how-to/upgrade.md)
- [Nginx > How To > Trigger Pipeline](https://docs.zerops.io/nginx/how-to/trigger-pipeline.md)
-- [Nginx > How To > Shared Storage](https://docs.zerops.io/nginx/how-to/shared-storage.md)
- [Nginx > How To > Scaling](https://docs.zerops.io/nginx/how-to/scaling.md)
- [Nginx > How To > Logs](https://docs.zerops.io/nginx/how-to/logs.md)
- [Nginx > How To > Filebrowser](https://docs.zerops.io/nginx/how-to/filebrowser.md)
@@ -209,7 +200,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Java > Overview](https://docs.zerops.io/java/overview.md)
- [Java > How To > Upgrade](https://docs.zerops.io/java/how-to/upgrade.md)
- [Java > How To > Trigger Pipeline](https://docs.zerops.io/java/how-to/trigger-pipeline.md)
-- [Java > How To > Shared Storage](https://docs.zerops.io/java/how-to/shared-storage.md)
- [Java > How To > Scaling](https://docs.zerops.io/java/how-to/scaling.md)
- [Java > How To > Logs](https://docs.zerops.io/java/how-to/logs.md)
- [Java > How To > Filebrowser](https://docs.zerops.io/java/how-to/filebrowser.md)
@@ -226,7 +216,7 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Guides > Vpn](https://docs.zerops.io/guides/vpn.md)
- [Guides > Verify Web Agent Protocol](https://docs.zerops.io/guides/verify-web-agent-protocol.md)
- [Guides > Smtp](https://docs.zerops.io/guides/smtp.md)
-- [Guides > Shared Storage Integration](https://docs.zerops.io/guides/shared-storage-integration.md)
+- [Guides > Seaweedfs Integration](https://docs.zerops.io/guides/seaweedfs-integration.md)
- [Guides > Scaling](https://docs.zerops.io/guides/scaling.md)
- [Guides > Readiness Health Checks](https://docs.zerops.io/guides/readiness-health-checks.md)
- [Guides > Public Access](https://docs.zerops.io/guides/public-access.md)
@@ -254,7 +244,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Go > Overview](https://docs.zerops.io/go/overview.md)
- [Go > How To > Upgrade](https://docs.zerops.io/go/how-to/upgrade.md)
- [Go > How To > Trigger Pipeline](https://docs.zerops.io/go/how-to/trigger-pipeline.md)
-- [Go > How To > Shared Storage](https://docs.zerops.io/go/how-to/shared-storage.md)
- [Go > How To > Scaling](https://docs.zerops.io/go/how-to/scaling.md)
- [Go > How To > Logs](https://docs.zerops.io/go/how-to/logs.md)
- [Go > How To > Filebrowser](https://docs.zerops.io/go/how-to/filebrowser.md)
@@ -268,7 +257,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Gleam > Overview](https://docs.zerops.io/gleam/overview.md)
- [Gleam > How To > Upgrade](https://docs.zerops.io/gleam/how-to/upgrade.md)
- [Gleam > How To > Trigger Pipeline](https://docs.zerops.io/gleam/how-to/trigger-pipeline.md)
-- [Gleam > How To > Shared Storage](https://docs.zerops.io/gleam/how-to/shared-storage.md)
- [Gleam > How To > Scaling](https://docs.zerops.io/gleam/how-to/scaling.md)
- [Gleam > How To > Logs](https://docs.zerops.io/gleam/how-to/logs.md)
- [Gleam > How To > Filebrowser](https://docs.zerops.io/gleam/how-to/filebrowser.md)
@@ -295,7 +283,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Elixir > Overview](https://docs.zerops.io/elixir/overview.md)
- [Elixir > How To > Upgrade](https://docs.zerops.io/elixir/how-to/upgrade.md)
- [Elixir > How To > Trigger Pipeline](https://docs.zerops.io/elixir/how-to/trigger-pipeline.md)
-- [Elixir > How To > Shared Storage](https://docs.zerops.io/elixir/how-to/shared-storage.md)
- [Elixir > How To > Scaling](https://docs.zerops.io/elixir/how-to/scaling.md)
- [Elixir > How To > Logs](https://docs.zerops.io/elixir/how-to/logs.md)
- [Elixir > How To > Filebrowser](https://docs.zerops.io/elixir/how-to/filebrowser.md)
@@ -310,7 +297,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Dotnet > Overview](https://docs.zerops.io/dotnet/overview.md)
- [Dotnet > How To > Upgrade](https://docs.zerops.io/dotnet/how-to/upgrade.md)
- [Dotnet > How To > Trigger Pipeline](https://docs.zerops.io/dotnet/how-to/trigger-pipeline.md)
-- [Dotnet > How To > Shared Storage](https://docs.zerops.io/dotnet/how-to/shared-storage.md)
- [Dotnet > How To > Scaling](https://docs.zerops.io/dotnet/how-to/scaling.md)
- [Dotnet > How To > Logs](https://docs.zerops.io/dotnet/how-to/logs.md)
- [Dotnet > How To > Filebrowser](https://docs.zerops.io/dotnet/how-to/filebrowser.md)
@@ -325,7 +311,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Deno > Overview](https://docs.zerops.io/deno/overview.md)
- [Deno > How To > Upgrade](https://docs.zerops.io/deno/how-to/upgrade.md)
- [Deno > How To > Trigger Pipeline](https://docs.zerops.io/deno/how-to/trigger-pipeline.md)
-- [Deno > How To > Shared Storage](https://docs.zerops.io/deno/how-to/shared-storage.md)
- [Deno > How To > Scaling](https://docs.zerops.io/deno/how-to/scaling.md)
- [Deno > How To > Logs](https://docs.zerops.io/deno/how-to/logs.md)
- [Deno > How To > Filebrowser](https://docs.zerops.io/deno/how-to/filebrowser.md)
@@ -344,7 +329,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Bun > Overview](https://docs.zerops.io/bun/overview.md)
- [Bun > How To > Upgrade](https://docs.zerops.io/bun/how-to/upgrade.md)
- [Bun > How To > Trigger Pipeline](https://docs.zerops.io/bun/how-to/trigger-pipeline.md)
-- [Bun > How To > Shared Storage](https://docs.zerops.io/bun/how-to/shared-storage.md)
- [Bun > How To > Scaling](https://docs.zerops.io/bun/how-to/scaling.md)
- [Bun > How To > Logs](https://docs.zerops.io/bun/how-to/logs.md)
- [Bun > How To > Filebrowser](https://docs.zerops.io/bun/how-to/filebrowser.md)
@@ -358,7 +342,6 @@ suffix, and any docs.zerops.io URL can be turned into clean markdown by adding i
- [Alpine > Overview](https://docs.zerops.io/alpine/overview.md)
- [Alpine > How To > Upgrade](https://docs.zerops.io/alpine/how-to/upgrade.md)
- [Alpine > How To > Trigger Pipeline](https://docs.zerops.io/alpine/how-to/trigger-pipeline.md)
-- [Alpine > How To > Shared Storage](https://docs.zerops.io/alpine/how-to/shared-storage.md)
- [Alpine > How To > Scaling](https://docs.zerops.io/alpine/how-to/scaling.md)
- [Alpine > How To > Logs](https://docs.zerops.io/alpine/how-to/logs.md)
- [Alpine > How To > Filebrowser](https://docs.zerops.io/alpine/how-to/filebrowser.md)
diff --git a/apps/docs/static/vids/services/shared-storage.webm b/apps/docs/static/vids/services/shared-storage.webm
deleted file mode 100644
index b2fd94eb2..000000000
Binary files a/apps/docs/static/vids/services/shared-storage.webm and /dev/null differ