atoll-storage. This page covers what the self-hosted install adds for that and how to turn it off.
What gets installed
The stores themselves (named
st-<id>, labelled atoll.app/store and atoll.app/org) are created by atoll-server.
Secrets
create-secrets.sh runs create-storage-secrets.sh, which can also be run alone on an existing install. It keeps
Secrets that already exist.
Postgres backups go to bucket
atoll-store-backups on the Files SeaweedFS (ATOLL_DATASTORE_BACKUP_*), so they
live in the same cluster as the stores. Copy that bucket off-site like the platform’s own (see
backups.md), or point features.datastore.backups at an external S3 bucket and put
its keys in the atoll-store-backups Secret.
Public Files endpoint
Files stores are reachable from outside athttps://s3.<apps domain> (ATOLL_DATASTORE_FILES_PUBLIC_ENDPOINT):
signed requests and presigned URLs work, and buckets with public read answer anonymous reads.
- DNS: nothing to add, the wildcard record
*.<apps domain>already coverss3. - TLS: the wildcard certificate, served as Traefik’s default certificate like app hosts. With ingress-nginx
set it as
--default-ssl-certificate. s3can’t clash with a project: project names are at least three characters long.
features.datastore.files.publicEndpoint and files.ingress.enabled: false to publish it elsewhere.
Network
- App pods may connect to
atoll-storageon 5432, 6379 and 8333 (atoll-appspolicy). Postgres and Redis pods only let in the app pods of projects connected to them, through a policy per store that atoll-server keeps. - Files S3 (8333) accepts every app pod and the ingress controller: requests are signed per bucket, as on the public host.
- Everything else in
atoll-storageaccepts only its own namespace (replicas, backups to the Files S3), atoll-server (5432, 6379, 8333: usage probes, buckets, backup sizes; the stores’ own policies admit it fromATOLL_DATASTORE_SERVER_NAMESPACE, the release namespace), the CloudNativePG operator (5432, 8000) andnetworkPolicy.storage.monitoringNamespaceson the metrics ports (9187, 9121, 9327). The chart restricts no egress there: Postgres pods archive WAL to the Files S3 and talk to the Kubernetes API; Redis pods get a deny-all egress policy from their engine.
Disks and resizing
Stores get PersistentVolumeClaims offeatures.datastore.storageClass (ATOLL_DATASTORE_STORAGE_CLASS; per kind
ATOLL_DATASTORE_REDIS_STORAGE_CLASS through features.datastore.config), or the cluster default. Growing a store
resizes its claims, which needs a StorageClass with allowVolumeExpansion: true and a driver that can expand
volumes (Longhorn, a cloud CSI driver, OpenEBS LVM…). k3s’ local-path (also used by
deploy/selfhost/local/k3d.sh) can’t: it ignores sizes and has no resizer, so resizes are refused with a clear
message (the server reads the StorageClass, rbac.storageClasses).
Images default to the engines’ own; ATOLL_DATASTORE_POSTGRES_IMAGE and ATOLL_DATASTORE_REDIS_IMAGE (in
features.datastore.config) pin others.
Regions
Every region that should run stores needs the same pieces in its cluster: CloudNativePG with the Barman Cloud plugin, theatoll-storage namespace with the Files SeaweedFS, the Secrets atoll-store-backups (Postgres backups
fail without it) and atoll-files-s3-config, and the Role above (plus the StorageClass ClusterRole) bound to the
region’s service account. Test connection on the region (Admin, Regions) checks the namespace, the rights and the
operators. A region without them still runs apps; the test then says why storage is off there.
Turning it off
features.datastore.enabled: false. The server then answers that storage is turned off
(ATOLL_DATASTORE_ENABLED=false), and the chart creates no storage namespace, Role or policies. Existing stores and
the namespace are kept (the namespace has helm.sh/resource-policy: keep); delete them by hand once they are empty.