mod_filestore
Store uploaded media and generated previews on S3-compatible storage, FTP/FTPS, or WebDAV. Zotonic keeps a database registry of remote files and serves them through a shared local cache when they are no longer on the site's disk.
Set up remote storage
- Enable
mod_filestorefor the site. - Open System → Cloud File Store in the admin. Changing settings and starting
bulk moves require the
use mod_admin_configpermission. - Enter the base URL and credentials for your storage service using the table below.
- Select Upload new media files to the cloud file store. Decide whether to Keep local files after upload and choose the remote deletion delay.
- Save the settings. Zotonic writes, reads back, and deletes a temporary
-zotonic-filestore-test-file-beneath the base URL. Settings are saved only when this test succeeds. - Upload a test image, allow the upload queue to run, and check both the original and a resized preview. Use the bulk action to upload existing media when ready.
A successful credential test checks these operations at the configured location; check normal media delivery as well. The test needs delete permission even when remote deletion is set to Never.
Supported services and URLs
| Service | Base URL example | Credentials | service value |
|---|---|---|---|
| S3-compatible | https://mybucket.s3.amazonaws.com/mysite | Access key and secret key | s3 |
| FTP over TLS | ftps://files.example.com/mysite | Username and password | ftp |
| WebDAV over HTTPS | webdavs://files.example.com/remote.php/dav/files/alice/mysite | Username and password | webdav |
The admin derives the service from the URL scheme. http: and https: select
S3, not WebDAV. For WebDAV use webdav: or webdavs:; dav: and davs: are
aliases. Use webdavs: or davs: to protect the WebDAV credentials with HTTPS.
Both ftp: and ftps: select the FTP backend. The server must support TLS:
the client uses passive FTP with explicit TLS by default, or implicit TLS when
port 990 is specified, for example ftps://files.example.com:990/mysite.
Allow the server's passive data connections through the firewall. SFTP (SSH file
transfer) is not supported by this backend.
FTP and WebDAV create missing directories during upload. Their accounts need permission to create directories and write, read, and delete files in the chosen location. For S3, the admin can try to create a private bucket if it is missing; this requires permission to create a bucket. The checkbox is a setup action, not a saved configuration option.
S3 permissions
Use a bucket or prefix dedicated to the site. Grant bucket listing where required by the provider and grant the following object permissions beneath the base URL:
| Path | Permissions |
|---|---|
-zotonic-filestore-test-file- | s3:GetObject, s3:PutObject, s3:DeleteObject |
archive/* | s3:GetObject, s3:PutObject; s3:DeleteObject when remote deletion is enabled |
preview/* | s3:GetObject, s3:PutObject; s3:DeleteObject when remote deletion is enabled |
Other applications using the filestore may write additional paths. Give those paths the corresponding permissions. Files do not need public-read access: Zotonic retrieves them using the configured credentials.
Configuration reference
Site settings are stored under mod_filestore in m_config. The historical
s3 prefixes also apply to FTP and WebDAV.
| Key | Meaning |
|---|---|
service | Backend identifier: s3, ftp, or webdav. Set it explicitly outside the admin; an empty value falls back to s3. TLS variants are URL schemes, not backend identifiers. |
s3url | Base URL, including the bucket or directory and optional site prefix. |
s3key | S3 access key, or FTP/WebDAV username. |
s3secret | S3 secret key, or FTP/WebDAV password. |
is_upload_enabled | Allow background uploads. Set explicitly when configuring storage outside the admin. Disabling this does not disable reads, queued downloads, or remote deletion. |
is_local_keep | Keep local files after successful upload. When false, uploaded files move into the evictable cache. |
delete_interval | Extra delay before deleting files marked for remote deletion: 0 (the default, no extra delay), false (never), seconds, or a value such as 1 week, 2 days, or 3 months. |
tls_options | Erlang list of TLS options passed to the selected storage client. Not an admin form field; an empty list uses the client's defaults. |
System-wide defaults and locked settings
The same keys can be set in the zotonic_mod_filestore application environment in
the system configuration. Nonempty site settings override these defaults unless
is_config_locked is true. This lock is a system-wide option: it makes sites
use the application settings and prevents editing them through the filestore form.
For example, merge this application entry into the system's Erlang configuration list, using your own endpoint and credentials:
{zotonic_mod_filestore, [
{service, <<"webdav">>},
{s3url, <<"webdavs://files.example.com/zotonic/{{site}}">>},
{s3key, <<"storage-user">>},
{s3secret, <<"replace-with-password">>},
{is_upload_enabled, true},
{is_local_keep, true},
{delete_interval, <<"false">>},
{is_config_locked, true}
]}
In a system-configured base URL, {{site}} is replaced with the site name.
If the placeholder is absent, Zotonic appends the site name as a directory.
A base URL saved in the site's admin is used as entered, without this expansion.
Configure service alongside the URL: URL-based service detection happens when
saving the admin form, not when reading application configuration.
Uploads, local copies, and the cache
New media files and previews are queued for asynchronous upload. Queue entries become eligible after one minute. Processing runs on a minute tick, with bounded batches, database-load checks, and backoff, so completion can take longer.
With is_local_keep enabled, remote storage holds an additional copy of local
media. Otherwise, successfully uploaded files move from the site's files directory
into filezcache, where they can be evicted. When a remote-only file is requested,
Zotonic downloads it into the cache and can serve it while the download proceeds.
The filezcache application is shared by all sites. Its max_bytes application
setting controls cache capacity (default 10 GiB). Cache files are disposable;
retain the remote files and database registry. Keeping remote media copies does
not replace a backup of the site's database, configuration, and application code.
Deletion and moving existing files
Zotonic normally retains deleted media for five weeks to allow recovery. The
filestore's delete_interval adds a delay after a file is marked for remote
deletion. 0 means no extra delay, not deletion at the instant a page is
removed. false keeps remote files indefinitely; it does not make the remote
service itself immutable.
Use the admin's bulk actions to queue existing local media for upload or to move remote files back to the server's disk. These operations run in the background; watch the queues and logs. Moving files to disk requires enough disk space and working credentials for their existing locations. Disable uploads when bringing files back for a storage migration.
Before switching to a different service or account, bring the files back locally and verify that the download queue has completed. Then configure and test the new location and queue uploads. Changing the base URL alone does not copy existing remote objects: the registry retains their original service and location. The default reverse lookup uses credentials for the currently configured service. Remote deletion also checks that an object's URL matches the configured base URL.
Statistics and troubleshooting
The admin shows registered media, estimated local file counts and sizes, remote file counts and sizes, and upload, download, and delete queue counts. These figures come from the site's database; they are not a scan or integrity check of remote storage. Local totals are estimates, not a scan of the files directory.
If uploads do not progress, check that uploads are enabled, the module is active,
and the URL and credentials pass the settings test. Inspect logs for connection,
permission, TLS, or storage errors. For FTP, check passive data connections; for
WebDAV, check the full collection path and the webdavs: scheme. Allow for the
queue delay and backoff before assuming a newly queued file is stuck.
Integration points
mod_filestore handles these notifications:
#media_update_done{}queues inserted or updated media files.#filestore{}handles file lookup, upload, and deletion through the file registry and cache.#filestore_request{}handles direct storage upload, download, and deletion requests.#filestore_credentials_lookup{}maps a local path and optional resource ID to remote credentials and location.#filestore_credentials_revlookup{}resolves credentials for an existing remote service and location.#admin_menu{}adds the admin menu entry.
Applications can provide credential lookup observers to route files to different
services. See zotonic_file.hrl for the notification records and model#filestore
for the configuration and statistics model. Storage requests use s3filez,
ftpfilez, or webdavfilez; filezcache manages the shared download cache.