{"result":{"depiction_url":null,"edges":{"observes":{"objects":[{"created":"2026-09-09T13:47:44Z","object_id":{"id":1466,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_admin_menu","title":"observe_admin_menu\/3","uri":"https:\/\/zotonic.com\/id\/1466"},"seq":1},{"created":"2026-09-09T13:47:44Z","object_id":{"id":1738,"is_a":["text","documentation","reference","notification"],"name":"doc_notification_media_update_done","title":"observe_media_update_done\/2","uri":"https:\/\/zotonic.com\/id\/1738"},"seq":2}],"predicate":{"id":2550,"is_a":["meta","predicate"],"name":"observes","title":{"_type":"trans","tr":{"en":"Observes"}},"uri":"https:\/\/zotonic.com\/id\/observes"}},"refers":{"objects":[{"created":"2026-10-07T21:20:03Z","object_id":{"id":2140,"is_a":["text","documentation","reference","model"],"name":"doc_model_model_filestore","title":"filestore","uri":"https:\/\/zotonic.com\/id\/2140"},"seq":1000000}],"predicate":{"id":2409,"is_a":["meta","predicate"],"name":"refers","title":{"_type":"trans","tr":{"en":"Refers"}},"uri":"https:\/\/zotonic.com\/id\/refers"}},"relation":{"objects":[{"created":"2020-05-30T05:48:17Z","object_id":{"id":2140,"is_a":["text","documentation","reference","model"],"name":"doc_model_model_filestore","title":"filestore","uri":"https:\/\/zotonic.com\/id\/2140"},"seq":1000000}],"predicate":{"id":303,"is_a":["meta","predicate"],"name":"relation","title":{"_type":"trans","tr":{"nl":"Relatie","en":"Relation"}},"uri":"http:\/\/purl.org\/dc\/terms\/relation"}},"subject":{"objects":[{"created":"2026-09-09T13:47:44Z","object_id":{"id":2555,"is_a":["categorization","keyword","keyword_information_type"],"name":"zotonic_topic_reference","title":"Reference","uri":"https:\/\/zotonic.com\/id\/2555"},"seq":1},{"created":"2026-09-09T13:47:44Z","object_id":{"id":2566,"is_a":["categorization","keyword","keyword_audience"],"name":"zotonic_topic_operator","title":"Operator","uri":"https:\/\/zotonic.com\/id\/2566"},"seq":2},{"created":"2026-09-09T13:47:44Z","object_id":{"id":2580,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_file_uploads","title":"File uploads","uri":"https:\/\/zotonic.com\/id\/2580"},"seq":3},{"created":"2026-09-09T13:47:44Z","object_id":{"id":2581,"is_a":["categorization","keyword","keyword_domain"],"name":"zotonic_topic_file_storage","title":"File storage","uri":"https:\/\/zotonic.com\/id\/2581"},"seq":4},{"created":"2026-09-09T13:47:44Z","object_id":{"id":2632,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_file_store","title":"File store","uri":"https:\/\/zotonic.com\/id\/2632"},"seq":5},{"created":"2026-09-09T13:47:44Z","object_id":{"id":2635,"is_a":["categorization","keyword","keyword_architecture"],"name":"zotonic_topic_module","title":"Module","uri":"https:\/\/zotonic.com\/id\/2635"},"seq":6},{"created":"2026-09-09T13:47:44Z","object_id":{"id":2689,"is_a":["categorization","keyword","keyword_quality"],"name":"zotonic_topic_reliability","title":"Reliability","uri":"https:\/\/zotonic.com\/id\/2689"},"seq":7}],"predicate":{"id":308,"is_a":["meta","predicate"],"name":"subject","title":{"_type":"trans","tr":{"en":"Keyword"}},"uri":"http:\/\/purl.org\/dc\/elements\/1.1\/subject"}}},"id":1329,"is_a":["text","documentation","reference","module"],"links":[{"rel":"self","target":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1329"},{"rel":"hub","target":"https:\/\/zotonic.com\/.zotonic\/websub"}],"medium":null,"medium_url":null,"name":"doc_module_mod_filestore","page_url":{"en":"https:\/\/zotonic.com\/docs\/1329\/mod_filestore","x-default":"https:\/\/zotonic.com\/docs\/1329\/mod_filestore"},"preview_url":null,"resource":{"version":4092,"pivot_location_lat":null,"title":"mod_filestore","is_authoritative":true,"body":"<p>Store uploaded media and generated previews on S3-compatible storage, FTP\/FTPS,\nor WebDAV. Zotonic keeps a database registry of remote files and serves them\nthrough a shared local cache when they are no longer on the site&#39;s disk.<\/p>\n<h2>Set up remote storage<\/h2>\n<ol><li>Enable <code>mod_filestore<\/code> for the site.<\/li><li>Open <strong>System → Cloud File Store<\/strong> in the admin. Changing settings and starting\nbulk moves require the <code>use mod_admin_config<\/code> permission.<\/li><li>Enter the base URL and credentials for your storage service using the table below.\nFor S3, enter the provider&#39;s region to enable Signature V4, or leave it empty\nto use legacy Signature V2.<\/li><li>Select <strong>Upload new media files to the cloud file store<\/strong>. Decide whether to\n<strong>Keep local files after upload<\/strong> and choose the remote deletion delay.<\/li><li>Save the settings. Zotonic writes, reads back, and deletes a temporary\n<code>-zotonic-filestore-test-file-<\/code> beneath the base URL. Settings are saved only\nwhen this test succeeds.<\/li><li>Upload a test image, allow the upload queue to run, and check both the original\nand a resized preview. Use the bulk action to upload existing media when ready.<\/li><\/ol>\n<p>A successful credential test checks these operations at the configured location;\ncheck normal media delivery as well. The test needs delete permission even when\nremote deletion is set to <strong>Never<\/strong>.<\/p>\n<h3>Supported services and URLs<\/h3>\n<table class=\"table\"><thead><tr><th>Service<\/th><th>Base URL example<\/th><th>Credentials<\/th><th><code>service<\/code> value<\/th><\/tr><\/thead><tbody><tr><td>S3-compatible<\/td><td><code>https:\/\/mybucket.s3.amazonaws.com\/mysite<\/code><\/td><td>Access key and secret key<\/td><td><code>s3<\/code><\/td><\/tr><tr><td>FTP over TLS<\/td><td><code>ftps:\/\/files.example.com\/mysite<\/code><\/td><td>Username and password<\/td><td><code>ftp<\/code><\/td><\/tr><tr><td>WebDAV over HTTPS<\/td><td><code>webdavs:\/\/files.example.com\/remote.php\/dav\/files\/alice\/mysite<\/code><\/td><td>Username and password<\/td><td><code>webdav<\/code><\/td><\/tr><\/tbody><\/table>\n<p>The admin derives the service from the URL scheme. <code>http:<\/code> and <code>https:<\/code> select\nS3, not WebDAV. For WebDAV use <code>webdav:<\/code> or <code>webdavs:<\/code>; <code>dav:<\/code> and <code>davs:<\/code> are\naliases. Use <code>webdavs:<\/code> or <code>davs:<\/code> to protect the WebDAV credentials with HTTPS.<\/p>\n<p>Both <code>ftp:<\/code> and <code>ftps:<\/code> select the FTP backend. The server must support TLS:\nthe client uses passive FTP with explicit TLS by default, or implicit TLS when\nport 990 is specified, for example <code>ftps:\/\/files.example.com:990\/mysite<\/code>.\nAllow the server&#39;s passive data connections through the firewall. SFTP (SSH file\ntransfer) is not supported by this backend.<\/p>\n<p>FTP and WebDAV create missing directories during upload. Their accounts need\npermission to create directories and write, read, and delete files in the chosen\nlocation. For S3, the admin can try to create a private bucket if it is missing;\nthis requires permission to create a bucket. The checkbox is a setup action, not\na saved configuration option.<\/p>\n<h3>S3 signature version and region<\/h3>\n<p>The <strong>S3 region<\/strong> field (<code>s3region<\/code>) selects the signature version automatically:<\/p>\n<table class=\"table\"><thead><tr><th>Effective region<\/th><th>Signature version<\/th><\/tr><\/thead><tbody><tr><td>Empty, including whitespace-only values<\/td><td>Signature V2 (legacy)<\/td><\/tr><tr><td>Nonempty, for example <code>eu-west-1<\/code><\/td><td>Signature V4, signed for that region<\/td><\/tr><\/tbody><\/table>\n<p>Leading and trailing whitespace is removed. Use the region supplied by your\nstorage provider; Zotonic does not infer it from the endpoint URL. There is no\nseparate signature-version setting and no automatic fallback to V2 if a V4\nrequest fails. Providers requiring V4 need a nonempty, correct region.<\/p>\n<p>This selection applies to settings tests and all S3 file operations, including\nuploads, downloads, streaming, deletion, and bucket-creation requests. FTP and\nWebDAV ignore the region.<\/p>\n<p>An unset site region inherits the system-wide <code>s3region<\/code> default. An explicitly\nempty site region overrides that default and selects V2. When configuration is\nlocked, the system-wide region determines the signature version. Existing\ninstallations without a region continue to use V2.<\/p>\n<h3>S3 permissions<\/h3>\n<p>Use a bucket or prefix dedicated to the site. Grant bucket listing where required\nby the provider and grant the following object permissions beneath the base URL:<\/p>\n<table class=\"table\"><thead><tr><th>Path<\/th><th>Permissions<\/th><\/tr><\/thead><tbody><tr><td><code>-zotonic-filestore-test-file-<\/code><\/td><td><code>s3:GetObject<\/code>, <code>s3:PutObject<\/code>, <code>s3:DeleteObject<\/code><\/td><\/tr><tr><td><code>archive\/*<\/code><\/td><td><code>s3:GetObject<\/code>, <code>s3:PutObject<\/code>; <code>s3:DeleteObject<\/code> when remote deletion is enabled<\/td><\/tr><tr><td><code>preview\/*<\/code><\/td><td><code>s3:GetObject<\/code>, <code>s3:PutObject<\/code>; <code>s3:DeleteObject<\/code> when remote deletion is enabled<\/td><\/tr><\/tbody><\/table>\n<p>Other applications using the filestore may write additional paths. Give those\npaths the corresponding permissions. Files do not need public-read access:\nZotonic retrieves them using the configured credentials.<\/p>\n<h2>Configuration reference<\/h2>\n<p>Site settings are stored under <code>mod_filestore<\/code> in <code>m_config<\/code>. The historical\n<code>s3<\/code> prefixes also apply to FTP and WebDAV, except <code>s3region<\/code>, which only applies to S3.\nAn explicitly empty site region selects V2 instead of inheriting a global region.\nAn unset site region inherits the global setting; locked configuration always uses the global setting.<\/p>\n<table class=\"table\"><thead><tr><th>Key<\/th><th>Meaning<\/th><\/tr><\/thead><tbody><tr><td><code>service<\/code><\/td><td>Backend identifier: <code>s3<\/code>, <code>ftp<\/code>, or <code>webdav<\/code>. Set it explicitly outside the admin; an empty value falls back to <code>s3<\/code>. TLS variants are URL schemes, not backend identifiers.<\/td><\/tr><tr><td><code>s3url<\/code><\/td><td>Base URL, including the bucket or directory and optional site prefix.<\/td><\/tr><tr><td><code>s3region<\/code><\/td><td>S3 signing region, for example <code>eu-west-1<\/code>. A nonempty region enables Signature V4; empty uses legacy Signature V2.<\/td><\/tr><tr><td><code>s3key<\/code><\/td><td>S3 access key, or FTP\/WebDAV username.<\/td><\/tr><tr><td><code>s3secret<\/code><\/td><td>S3 secret key, or FTP\/WebDAV password.<\/td><\/tr><tr><td><code>is_read_only<\/code><\/td><td>Download-only mode. Blocks uploads, remote deletion and write-based credential tests for every backend. Default <code>false<\/code>. A global or site-file <code>true<\/code> cannot be overridden by other settings.<\/td><\/tr><tr><td><code>is_upload_enabled<\/code><\/td><td>Allow background uploads. Set explicitly when configuring storage outside the admin. Disabling this does not disable reads, queued downloads, or remote deletion.<\/td><\/tr><tr><td><code>is_local_keep<\/code><\/td><td>Keep local files after successful upload. When false, uploaded files move into the evictable cache.<\/td><\/tr><tr><td><code>delete_interval<\/code><\/td><td>Extra delay before deleting files marked for remote deletion: <code>0<\/code> (the default, no extra delay), <code>false<\/code> (never), seconds, or a value such as <code>1 week<\/code>, <code>2 days<\/code>, or <code>3 months<\/code>.<\/td><\/tr><tr><td><code>tls_options<\/code><\/td><td>Erlang list of TLS options passed to the selected storage client. Not an admin form field; an empty list uses the client&#39;s defaults.<\/td><\/tr><\/tbody><\/table>\n<h3>System-wide defaults and locked settings<\/h3>\n<p>The same keys can be set in the <code>zotonic_mod_filestore<\/code> application environment in\nthe system configuration. Nonempty site settings override these defaults unless\n<code>is_config_locked<\/code> is true. For <code>s3region<\/code>, an explicitly empty site setting also\noverrides the default, selecting Signature V2. This lock is a <strong>system-wide<\/strong> option: it makes sites\nuse the application settings and prevents editing them through the filestore form.<\/p>\n<p><code>is_read_only<\/code> is an exception to this override rule: setting it to <code>true<\/code> in the\n<strong>global <code>zotonic_mod_filestore<\/code> configuration makes storage read-only for every\nsite<\/strong>, including sites with their own endpoints or credentials. A site cannot\nturn it off with <code>false<\/code>. This restriction works independently of\n<code>is_config_locked<\/code>; locking configuration is not required to enforce read-only\nstorage. A site can also enable read-only mode when the global value is false.<\/p>\n<p>For example, merge this application entry into the system&#39;s Erlang configuration\nlist, using your own endpoint and credentials:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">{zotonic_mod_filestore, [\n    {service, &lt;&lt;&quot;webdav&quot;&gt;&gt;},\n    {s3url, &lt;&lt;&quot;webdavs:\/\/files.example.com\/zotonic\/{{site}}&quot;&gt;&gt;},\n    {s3key, &lt;&lt;&quot;storage-user&quot;&gt;&gt;},\n    {s3secret, &lt;&lt;&quot;replace-with-password&quot;&gt;&gt;},\n    {is_read_only, false},\n    {is_upload_enabled, true},\n    {is_local_keep, true},\n    {delete_interval, &lt;&lt;&quot;false&quot;&gt;&gt;},\n    {is_config_locked, true}\n]}\n<\/code><\/pre>\n<p>The example permits uploads. Set <code>{is_read_only, true}<\/code> in the same application\nentry to make all sites download-only. It takes precedence over\n<code>{is_upload_enabled, true}<\/code> and any <code>delete_interval<\/code>: uploads and remote deletes\nare blocked without changing those saved settings. This is useful when a staging\nor recovery installation needs to read existing storage without modifying it.<\/p>\n<p>In a <strong>system-configured<\/strong> base URL, <code>{{site}}<\/code> is replaced with the site name.\nIf the placeholder is absent, Zotonic appends the site name as a directory.\nA base URL saved in the site&#39;s admin is used as entered, without this expansion.\nConfigure <code>service<\/code> alongside the URL: URL-based service detection happens when\nsaving the admin form, not when reading application configuration.<\/p>\n<h3>Read-only storage<\/h3>\n<p>To allow downloads while preventing remote writes for <strong>all sites<\/strong>, merge this\nentry into the Zotonic global Erlang configuration list (or add the key to its\nexisting <code>zotonic_mod_filestore<\/code> entry):<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">{zotonic_mod_filestore, [\n    {is_read_only, true}\n]}\n<\/code><\/pre>\n<p>For one site, add this to its site configuration:<\/p>\n<pre class=\"notranslate\"><code class=\"notranslate language-erlang\">{mod_filestore, [\n    {is_read_only, true}\n]}\n<\/code><\/pre>\n<p>These examples show the entry to merge into the existing configuration list.\nThe setting can also be stored as <code>mod_filestore.is_read_only<\/code> in <code>m_config<\/code>.\nRestrictions are additive: a global or site-file <code>true<\/code> remains effective even\nif another source says <code>false<\/code>, or the service configuration is locked. The\ndefault is <code>false<\/code>. To restore writes, remove or disable every active read-only\nrestriction; changing only a site setting cannot lift a global restriction.<\/p>\n<p>Read-only mode blocks background uploads, remote deletion, direct filestore\nupload\/delete requests and the admin&#39;s write-based credential test. Direct writes\nreturn <code>{error, read_only}<\/code>. Existing upload and deletion queues are retained and\ncan resume when read-only mode is disabled. Local registry deletion marks can still\nbe recorded. Already dispatched remote operations cannot be revoked by changing\nconfiguration; enable read-only mode before starting the site when that matters.<\/p>\n<p>Normal downloads, cached reads and copying remote files to local disk remain\navailable. The admin shows the effective mode and disables upload\/test buttons.\nSettings can be saved without a write test; verify credentials by downloading an\nexisting file. Read-only accounts need only the provider&#39;s read permissions for\nthose objects. No test object or bucket is created in this mode.<\/p>\n<h2>Uploads, local copies, and the cache<\/h2>\n<p>New media files and previews are queued for asynchronous upload. Queue entries\nbecome eligible after one minute. Processing runs on a minute tick, with bounded\nbatches, database-load checks, and backoff, so completion can take longer.<\/p>\n<p>With <code>is_local_keep<\/code> enabled, remote storage holds an additional copy of local\nmedia. Otherwise, successfully uploaded files move from the site&#39;s files directory\ninto <code>filezcache<\/code>, where they can be evicted. When a remote-only file is requested,\nZotonic downloads it into the cache and can serve it while the download proceeds.<\/p>\n<p>The <code>filezcache<\/code> application is shared by all sites. Its <code>max_bytes<\/code> application\nsetting controls cache capacity (default 10 GiB). Cache files are disposable;\nretain the remote files and database registry. Keeping remote media copies does\nnot replace a backup of the site&#39;s database, configuration, and application code.<\/p>\n<h2>Read failures and retries<\/h2>\n<p>A failed remote cache read remains in the file registry and is retried when the\nfile is requested again. This includes <code>forbidden<\/code> and <code>enoent<\/code>: a permission or\naccount problem can be temporary, and S3 can return <code>forbidden<\/code> for missing files.<\/p>\n<p>Each file has its own exponential retry delay: nominally 5, 10, 20, 40 seconds,\nand so on, capped at ten minutes. Jitter varies each delay between 80% and 100%\nof that value. During the cooldown, requests do not start another remote read;\nan existing local or cached copy remains usable. A successful remote read clears\nthe error and resets the delay. There is no automatic permanent cutoff, and files\nthat are not requested generate no read retries.<\/p>\n<p>Retry eligibility is not a scheduled download time. Zotonic&#39;s file-serving\nnegative cache can add up to 60 seconds before another lookup occurs. Retry state\nsurvives restarts. An expiring database claim limits concurrent attempts across\nnodes; abandoned claims expire after ten minutes.<\/p>\n<p>This policy applies to remote reads into <code>filezcache<\/code>. Background queue processing\nhas separate batch-size backoff. Direct <code>#filestore_request{}<\/code> calls do not use\nthis persistent read-retry policy.<\/p>\n<h2>Deletion and moving existing files<\/h2>\n<p>Zotonic normally retains deleted media for five weeks to allow recovery. The\nfilestore&#39;s <code>delete_interval<\/code> adds a delay after a file is marked for remote\ndeletion. <code>0<\/code> means no <strong>extra<\/strong> delay, not deletion at the instant a page is\nremoved. <code>false<\/code> keeps remote files indefinitely; it does not make the remote\nservice itself immutable.<\/p>\n<p>Use the admin&#39;s bulk actions to queue existing local media for upload or to move\nremote files back to the server&#39;s disk. These operations run in the background;\nwatch the queues and logs. Moving files to disk requires enough disk space and\nworking credentials for their existing locations. Disable uploads when bringing\nfiles back for a storage migration.<\/p>\n<p>Before switching to a different service or account, bring the files back locally\nand verify that the download queue has completed. Then configure and test the new\nlocation and queue uploads. Changing the base URL alone does not copy existing\nremote objects: the registry retains their original service and location. The\ndefault reverse lookup uses credentials for the currently configured service.\nRemote deletion also checks that an object&#39;s URL matches the configured base URL.<\/p>\n<h2>Statistics and troubleshooting<\/h2>\n<p>The admin shows registered media, estimated local file counts and sizes, remote\nfile counts and sizes, and upload, download, and delete queue counts. These figures\ncome from the site&#39;s database; they are not a scan or integrity check of remote\nstorage. Local totals are estimates, not a scan of the files directory.<\/p>\n<p>If uploads do not progress, check that uploads are enabled, the module is active,\nand the URL and credentials pass the settings test. Inspect logs for connection,\npermission, TLS, or storage errors. For FTP, check passive data connections; for\nWebDAV, check the full collection path and the <code>webdavs:<\/code> scheme. Allow for the\nqueue delay and backoff before assuming a newly queued file is stuck.<\/p>\n<h3>Health warnings and error details<\/h3>\n<p>The admin dashboard and filestore configuration page warn administrators when:<\/p>\n<ul><li>At least five remote cache reads failed and failures account for at least 20%\nof completed reads in the current and preceding fourteen minute buckets.<\/li><li>At least one active, unresolved read error is older than 24 hours.<\/li><\/ul>\n<p>The read-error rate is shared across nodes. It counts completed remote attempts,\nnot cache hits or requests suppressed by the cooldown. The 24-hour age runs from\nthe first failure in the current unresolved sequence; repeated failures do not\nrestart that clock.<\/p>\n<p>Follow <strong>View errors<\/strong> to the filestore page for details. The list shows <strong>50 files\nper page<\/strong>, oldest first, with Previous\/Next navigation. Each row shows the relative\nfile path, storage service, latest recorded error, consecutive failure count,\nfailing-since time, and retry eligibility. Only errors older than 24 hours are\nlisted, including entries explicitly marked unrecoverable. Remote URLs and\ncredentials are not included in the list.<\/p>\n<h3>Marking a file unrecoverable<\/h3>\n<p>Only the administrator account, <strong>user 1<\/strong>, sees the <strong>Mark unrecoverable<\/strong> action.\nAfter confirmation, the server rechecks both the user ID and that the entry still\nhas an unresolved error older than 24 hours. Other administrators cannot perform\nthis action, and a recovered or recently failed entry is not eligible.<\/p>\n<p>Marking an entry unrecoverable stops automatic remote cache-read retries and\nremoves it from active unresolved-error counts. Its row remains in the error list\nwith an <strong>Unrecoverable<\/strong> label. The file registry record and error details are\nretained; no local or remote files are deleted. Historical read-rate statistics\nare unchanged, so a high-error-rate warning can remain until those attempts leave\nthe reporting window. Late callbacks from an attempt already in flight cannot\nclear the unrecoverable state. A new successful upload of the path resets it.<\/p>\n<h2>Integration points<\/h2>\n<p><code>mod_filestore<\/code> handles these notifications:<\/p>\n<ul><li><code>#media_update_done{}<\/code> queues inserted or updated media files.<\/li><li><code>#filestore{}<\/code> handles file lookup, upload, and deletion through the file registry and cache.<\/li><li><code>#filestore_request{}<\/code> handles direct storage upload, download, and deletion requests.<\/li><li><code>#filestore_credentials_lookup{}<\/code> maps a local path and optional resource ID to remote credentials and location.<\/li><li><code>#filestore_credentials_revlookup{}<\/code> resolves credentials for an existing remote service and location.<\/li><li><code>#admin_menu{}<\/code> adds the admin menu entry.<\/li><\/ul>\n<p>Applications can provide credential lookup observers to route files to different\nservices. See <code>zotonic_file.hrl<\/code> for the notification records and <a href=\"\/id\/doc_model_model_filestore\" class=\"doc-reference doc-reference-model\"><code>model#filestore<\/code><\/a>\nfor the configuration and statistics model. Storage requests use <code>s3filez<\/code>,\n<code>ftpfilez<\/code>, or <code>webdavfilez<\/code>; <code>filezcache<\/code> manages the shared download cache.<\/p>","slug":"mod_filestore","doc_module_config":[{"default":"[]","description":"The service to use for storing files. One of: s3, ftp, webdav. TLS is selected by the URL scheme","has_default":true,"key":"service","module":"mod_filestore","type":"string"},{"default":"[]","description":"The base URL of the S3, FTP\/FTPS, or WebDAV service, including its bucket or directory","has_default":true,"key":"s3url","module":"mod_filestore","type":"string"},{"default":"[]","description":"S3 signing region. A nonempty region enables Signature V4; empty uses Signature V2","has_default":true,"key":"s3region","module":"mod_filestore","type":"string"},{"default":"[]","description":"The S3 access key or FTP\/WebDAV username, used for authentication.","has_default":true,"key":"s3key","module":"mod_filestore","type":"string"},{"default":"[]","description":"The S3 secret key or FTP\/WebDAV password, used for authentication","has_default":true,"key":"s3secret","module":"mod_filestore","type":"string"},{"default":"false","description":"Keep a local copy of the files that are uploaded to the remote server. If set, the storage server is used as a backup for the locally uploaded files.","has_default":true,"key":"is_local_keep","module":"mod_filestore","type":"boolean"},{"default":"false","description":"Allow downloads only. Block uploads, remote deletion and write-based credential tests.","has_default":true,"key":"is_read_only","module":"mod_filestore","type":"boolean"},{"default":"true","description":"Enable the upload of new files to the remote server.","has_default":true,"key":"is_upload_enabled","module":"mod_filestore","type":"boolean"},{"default":"&lt;&lt;&quot;0&quot;&gt;&gt;","description":"The interval at which to delete files marked as deleted. Set to &#39;false&#39; to disable deletion of remote files. Use seconds, &#39;false&#39;, or &#39;N days\/weeks\/months&#39; to specify the interval. The default is &#39;0&#39;, which means no extra delay after a file is marked for remote deletion.","has_default":true,"key":"delete_interval","module":"mod_filestore","type":"string"}],"is_protected":false,"visible_for":0,"tz":"UTC","language":["en"],"doc_source_hash":"57409e78966f1aae72f25c0258cf6442976524413ab70f89866b55b67d3c9024","is_featured":false,"content_group_id":{"id":2551,"is_a":["meta","content_group"],"name":"content_group_imported_docs","title":"Imported documentation","uri":"https:\/\/zotonic.com\/id\/content_group_imported_docs"},"category_id":{"id":320,"is_a":["meta","category"],"name":"module","title":"Modules","uri":"https:\/\/test.zotonic.com\/id\/320"},"doc_source_path":"apps\/zotonic_mod_filestore\/src\/mod_filestore.erl","publication_start":"2023-06-24T08:17:53Z","github_url":"https:\/\/github.com\/zotonic\/zotonic\/blob\/master\/apps\/zotonic_mod_filestore\/src\/mod_filestore.erl","pivot_location_lng":null,"doc_source_kind":"module","name":"doc_module_mod_filestore","is_unfindable":false,"is_published":true,"pivot_geocode":null,"created":"2020-05-30T05:47:18Z","uri":null,"doc_status":"current","is_dependent":false,"erlang_app":"zotonic_mod_filestore","publication_end":"9999-06-01T00:00:00Z","modifier_id":{"id":1,"is_a":["person"],"name":"administrator","title":"Site Administrator","uri":"https:\/\/zotonic.com\/id\/1"},"privacy":0,"doc_source_commit":"bb8c4bfc7674f55f71ccc1d9130a01760b8031bc\n","creator_id":{"id":336,"is_a":["person","robot"],"name":"gitbot","title":"Git","uri":"https:\/\/zotonic.com\/id\/336"},"modified":"2026-10-24T06:46:48Z","title_slug":"mod_filestore"},"uri":"https:\/\/zotonic.com\/id\/1329","uri_template":"https:\/\/zotonic.com\/id\/:id","websub":{"hub":"https:\/\/zotonic.com\/.zotonic\/websub","topic":"https:\/\/zotonic.com\/.zotonic\/websub\/topic\/1329"}},"status":"ok"}