{"id":21277967,"url":"https://github.com/b13/distributed-flysystem","last_synced_at":"2025-07-11T08:32:20.062Z","repository":{"id":52466867,"uuid":"326058416","full_name":"b13/distributed-flysystem","owner":"b13","description":"Syncs files between frontend nodes in a multi-head environment based on PHP League / Flysystem","archived":false,"fork":false,"pushed_at":"2023-01-25T10:56:30.000Z","size":34,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-09-23T07:08:19.368Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/b13.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-01T21:24:50.000Z","updated_at":"2024-09-11T10:56:10.000Z","dependencies_parsed_at":"2023-02-14T06:45:38.269Z","dependency_job_id":null,"html_url":"https://github.com/b13/distributed-flysystem","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b13%2Fdistributed-flysystem","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b13%2Fdistributed-flysystem/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b13%2Fdistributed-flysystem/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/b13%2Fdistributed-flysystem/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/b13","download_url":"https://codeload.github.com/b13/distributed-flysystem/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225708281,"owners_count":17511635,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-21T10:08:28.773Z","updated_at":"2024-11-21T10:08:29.290Z","avatar_url":"https://github.com/b13.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Distributed Flysystem for TYPO3 Core\n\nImagine you run a multi-head environment with TYPO3. Each application\nserver is a \"node\".\n\nAs usual, there are caveats, and hurdles to work around with. Typically\nyou have local cache files (\"var/\"), and (ideally) a FAL driver via a\nremote shared storage for \"fileadmin\". The database is on a cluster,\nand you run a Redis sentinel for shared caches.\n\nBut what about the other files that TYPO3 sometimes generates?\n\nIn an ideal world, TYPO3 would be handling most of the logic already, but due to\nsome extensions or \"compressed\" files, some files get generated on e.g. \"node 20\" in\ntypo3temp/ which aren't available on the other nodes.\n\nIn the past, we had NFS to work around this usually, but when NFS is not an option,\nwe built a \"workaround\" extension for this, based on Frank De Jonge's [Flysystem](https://flysystem.thephpleague.com/v3/docs/)\nabstraction layer.\n\nEvery time a file in e.g. `typo3temp` gets accessed, and the file is not available\non this node, the other nodes are checked via SFTP and if one node has the\nfile, it is downloaded on the current nodes' typo3temp/ folder.\n\nCurrently, this extension is a \"pull\" solution - fetching the files\nif needed - but a deeper integration with the Local driver of the File Abstraction\nLayer should monitor this behavior as well in a separate step.\n\n## Installation\n\nSet it up via composer: `composer req b13/distributed-flysystem`.\n\n## Configuration\n\nAdd a proper configuration for your SFTP connection to all your nodes in your\nLocalConfiguration for example:\n\n    $GLOBALS['TYPO3_CONF_VARS']['FILE']['flysystem'] = [\n        'default' =\u003e [\n            'rootPath' =\u003e '/path/from/sftp/ch-root/to/public/path/',\n            'username' =\u003e 'b13',\n            'password' =\u003e null,\n            'port' =\u003e 2222,\n            'privateKey' =\u003e Environment::getVarPath() . '/my-sftp_privkey',\n            'passphrase' =\u003e 'take it or leave it',\n            'timeout' =\u003e 10\n        ],\n        'nodes' =\u003e [\n            'node01' =\u003e [\n                'host' =\u003e '1.2.3.4'\n                'alias' =\u003e 'primary'\n            ],\n            'node02' =\u003e [\n                'host' =\u003e '1.2.3.5',\n                'username' =\u003e 'b14',\n            ],\n        ],\n    ];\n\nModify your .htaccess file on each node to activate the \"pulling\" mechanism:\n\n    # Rewrite non-existent fileadmin and typo3temp files to a custom eID script\n\tRewriteCond %{REQUEST_URI} \"^(/fileadmin|/typo3temp/assets/).*\" [NC]\n\tRewriteCond %{REQUEST_FILENAME} !-f\n\tRewriteCond %{REQUEST_FILENAME} !-d\n\tRewriteCond %{REQUEST_FILENAME} !-l\n\tRewriteRule ^.*$ %{ENV:CWD}index.php?eID=flysystem [QSA,L]\n\n\n## Caveats\n\nIt is expected that the `rootPath` variable is set to the folder of the public\ndirectory of TYPO3's installation.\n\n## License\n\nAs TYPO3 Core, _distributed flysystem_ is licensed under GPL2 or later. See the LICENSE file for more details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb13%2Fdistributed-flysystem","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fb13%2Fdistributed-flysystem","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fb13%2Fdistributed-flysystem/lists"}