{"id":13527827,"url":"https://github.com/humanmade/S3-Uploads","last_synced_at":"2025-04-01T10:32:52.499Z","repository":{"id":11996926,"uuid":"14574404","full_name":"humanmade/S3-Uploads","owner":"humanmade","description":"The WordPress Plugin to Store Uploads on Amazon S3","archived":false,"fork":false,"pushed_at":"2025-02-12T14:22:59.000Z","size":10408,"stargazers_count":2005,"open_issues_count":170,"forks_count":395,"subscribers_count":85,"default_branch":"master","last_synced_at":"2025-03-25T18:14:49.261Z","etag":null,"topics":["s3","wordpress","wordpress-plugin"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/humanmade.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-11-21T01:26:22.000Z","updated_at":"2025-03-21T09:22:36.000Z","dependencies_parsed_at":"2023-01-13T16:44:59.977Z","dependency_job_id":"e34dba2a-ec08-47cc-93d4-fe9004794413","html_url":"https://github.com/humanmade/S3-Uploads","commit_stats":{"total_commits":374,"total_committers":64,"mean_commits":5.84375,"dds":0.4278074866310161,"last_synced_commit":"6c80d596c51affe8b8cb9c1a22dec9c9031353b1"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humanmade%2FS3-Uploads","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humanmade%2FS3-Uploads/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humanmade%2FS3-Uploads/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/humanmade%2FS3-Uploads/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/humanmade","download_url":"https://codeload.github.com/humanmade/S3-Uploads/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246135747,"owners_count":20729057,"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":["s3","wordpress","wordpress-plugin"],"created_at":"2024-08-01T06:02:03.010Z","updated_at":"2025-04-01T10:32:52.487Z","avatar_url":"https://github.com/humanmade.png","language":"PHP","readme":"\u003ctable width=\"100%\"\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd align=\"left\" width=\"70\"\u003e\n\t\t\t\u003cstrong\u003eS3 Uploads\u003c/strong\u003e\u003cbr /\u003e\n\t\t\tLightweight \"drop-in\" for storing WordPress uploads on Amazon S3 instead of the local filesystem.\n\t\t\u003c/td\u003e\n\t\t\u003ctd align=\"right\" width=\"20%\"\u003e\n\t\t\t\u003ca href=\"https://shepherd.dev/github/humanmade/S3-Uploads/\"\u003e\n\t\t\t\t\u003cimg src=\"https://shepherd.dev/github/humanmade/S3-Uploads/coverage.svg\" alt=\"Psalm coverage\"\u003e\n\t\t\t\u003c/a\u003e\n\t\t\t\u003ca href=\"https://travis-ci.com/humanmade/S3-Uploads\"\u003e\n\t\t\t\t\u003cimg src=\"https://travis-ci.com/humanmade/S3-Uploads.svg?branch=master\" alt=\"Build status\"\u003e\n\t\t\t\u003c/a\u003e\n\t\t\t\u003ca href=\"http://codecov.io/github/humanmade/S3-Uploads?branch=master\"\u003e\n\t\t\t\t\u003cimg src=\"http://codecov.io/github/humanmade/S3-Uploads/coverage.svg?branch=master\" alt=\"Coverage via codecov.io\" /\u003e\n\t\t\t\u003c/a\u003e\n\t\t\u003c/td\u003e\n\t\u003c/tr\u003e\n\t\u003ctr\u003e\n\t\t\u003ctd\u003e\n\t\t\tA \u003cstrong\u003e\u003ca href=\"https://hmn.md/\"\u003eHuman Made\u003c/a\u003e\u003c/strong\u003e project. Maintained by @joehoyle.\n\t\t\u003c/td\u003e\n\t\t\u003ctd align=\"center\"\u003e\n\t\t\t\u003cimg src=\"https://humanmade.com/content/themes/hmnmd/assets/images/hm-logo.svg\" width=\"100\" /\u003e\n\t\t\u003c/td\u003e\n\t\u003c/tr\u003e\n\u003c/table\u003e\n\nS3 Uploads is a WordPress plugin to store uploads on S3. S3 Uploads aims to be a lightweight \"drop-in\" for storing uploads on Amazon S3 instead of the local filesystem.\n\nIt's focused on providing a highly robust S3 interface with no \"bells and whistles\", WP-Admin UI or much otherwise. It comes with some helpful WP-CLI commands for generating IAM users, listing files on S3 and Migrating your existing library to S3.\n\n## Requirements\n\n- PHP \u003e= 7.1\n- WordPress \u003e= 5.3\n\n## Getting Set Up\n\nS3 Uploads requires installation via Composer:\n\n```\ncomposer require humanmade/s3-uploads\n```\n\n**Note:** [Composer's autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading) must be loaded before S3 Uploads is loaded. We recommend loading it in your `wp-config.php` before `wp-settings.php` is loaded as shown below.\n\n```php\nrequire_once __DIR__ . '/vendor/autoload.php';\n```\n\n## Configuration\n\nOnce you've installed the plugin, add the following constants to your `wp-config.php`:\n\n```PHP\ndefine( 'S3_UPLOADS_BUCKET', 'my-bucket' );\ndefine( 'S3_UPLOADS_REGION', '' ); // the s3 bucket region (excluding the rest of the URL)\n\n// You can set key and secret directly:\ndefine( 'S3_UPLOADS_KEY', '' );\ndefine( 'S3_UPLOADS_SECRET', '' );\n\n// Or if using IAM instance profiles, you can use the instance's credentials:\ndefine( 'S3_UPLOADS_USE_INSTANCE_PROFILE', true );\n```\nPlease refer to this region list http://docs.aws.amazon.com/general/latest/gr/rande.html#s3_region for the S3_UPLOADS_REGION values.\n\nUse of path prefix after the bucket name is allowed and is optional. For example, if you want to upload all files to 'my-folder' inside a bucket called 'my-bucket', you can use:\n\n```PHP\ndefine( 'S3_UPLOADS_BUCKET', 'my-bucket/my-folder' );\n```\n\nYou must then enable the plugin. To do this via WP-CLI use command:\n\n```\nwp plugin activate S3-Uploads\n```\n\nThe plugin name must match the directory you have cloned S3 Uploads into;\nIf you're using Composer, use\n```\nwp plugin activate s3-uploads\n```\n\n\nThe next thing that you should do is to verify your setup. You can do this using the `verify` command\nlike so:\n\n```\nwp s3-uploads verify\n```\n\nYou will need to create your IAM user yourself, or attach the necessary permissions to an existing user, you can output the policy via `wp s3-uploads generate-iam-policy`\n\n\n## Listing files on S3\n\nS3-Uploads comes with a WP-CLI command for listing files in the S3 bucket for debugging etc.\n\n```\nwp s3-uploads ls [\u003cpath\u003e]\n```\n\n## Uploading files to S3\n\nIf you have an existing media library with attachment files, use the below command to copy them all to S3 from local disk.\n\n```\nwp s3-uploads upload-directory \u003cfrom\u003e \u003cto\u003e [--verbose]\n```\n\nFor example, to migrate your whole uploads directory to S3, you'd run:\n\n```\nwp s3-uploads upload-directory /path/to/uploads/ uploads\n```\n\nThere is also an all purpose `cp` command for arbitrary copying to and from S3.\n\n```\nwp s3-uploads cp \u003cfrom\u003e \u003cto\u003e\n```\n\nNote: as either `\u003cfrom\u003e` or `\u003cto\u003e` can be S3 or local locations, you must specify the full S3 location via `s3://mybucket/mydirectory` for example `cp ./test.txt s3://mybucket/test.txt`.\n\n## Private Uploads\n\nWordPress (and therefor S3 Uploads) default behaviour is that all uploaded media files are publicly accessible. In certain cases which may not be desireable. S3 Uploads supports setting S3 Objects to a `private` ACL and providing temporarily signed URLs for all files that are marked as private.\n\nS3 Uploads does not make assumptions or provide UI for marking attachments as private, instead you should integrate the `s3_uploads_is_attachment_private` WordPress filter to control the behaviour. For example, to mark _all_ attachments as private:\n\n```php\nadd_filter( 's3_uploads_is_attachment_private', '__return_true' );\n```\n\nPrivate uploads can be transitioned to public by calling `S3_Uploads::set_attachment_files_acl( $id, 'public-read' )` or vica-versa. For example:\n\n```php\nS3_Uploads::get_instance()-\u003eset_attachment_files_acl( 15, 'public-read' );\n```\n\nThe default expiry for all private file URLs is 6 hours. You can modify this by using the `s3_uploads_private_attachment_url_expiry` WordPress filter. The value can be any string interpreted by `strtotime`. For example:\n\n```php\nadd_filter( 's3_uploads_private_attachment_url_expiry', function ( $expiry ) {\n\treturn '+1 hour';\n} );\n```\n\n## Cache Control\n\nYou can define the default HTTP `Cache-Control` header for uploaded media using the\nfollowing constant:\n\n```PHP\ndefine( 'S3_UPLOADS_HTTP_CACHE_CONTROL', 30 * 24 * 60 * 60 );\n\t// will expire in 30 days time\n```\n\nYou can also configure the `Expires` header using the `S3_UPLOADS_HTTP_EXPIRES` constant\nFor instance if you wanted to set an asset to effectively not expire, you could\nset the Expires header way off in the future.  For example:\n\n```PHP\ndefine( 'S3_UPLOADS_HTTP_EXPIRES', gmdate( 'D, d M Y H:i:s', time() + (10 * 365 * 24 * 60 * 60) ) .' GMT' );\n\t// will expire in 10 years time\n```\n\n## Default Behaviour\n\nAs S3 Uploads is a plug and play plugin, activating it will start rewriting image URLs to S3, and also put\nnew uploads on S3. Sometimes this isn't required behaviour as a site owner may want to upload a large\namount of media to S3 using the `wp-cli` commands before enabling S3 Uploads to direct all uploads requests\nto S3. In this case one can define the `S3_UPLOADS_AUTOENABLE` to `false`. For example, place the following\nin your `wp-config.php`:\n\n```PHP\ndefine( 'S3_UPLOADS_AUTOENABLE', false );\n```\n\nTo then enable S3 Uploads rewriting, use the wp-cli command: `wp s3-uploads enable` / `wp s3-uploads disable`\nto toggle the behaviour.\n\n## URL Rewrites\n\nBy default, S3 Uploads will use the canonical S3 URIs for referencing the uploads, i.e. `[bucket name].s3.amazonaws.com/uploads/[file path]`. If you want to use another URL to serve the images from (for instance, if you [wish to use S3 as an origin for CloudFlare](https://support.cloudflare.com/hc/en-us/articles/200168926-How-do-I-use-CloudFlare-with-Amazon-s-S3-Service-)), you should define `S3_UPLOADS_BUCKET_URL` in your `wp-config.php`:\n\n```PHP\n// Define the base bucket URL (without trailing slash)\ndefine( 'S3_UPLOADS_BUCKET_URL', 'https://your.origin.url.example/path' );\n```\nS3 Uploads' URL rewriting feature can be disabled if the current website does not require it, nginx proxy to s3 etc. In this case the plugin will only upload files to the S3 bucket.\n```PHP\n// disable URL rewriting alltogether\ndefine( 'S3_UPLOADS_DISABLE_REPLACE_UPLOAD_URL', true );\n```\n\n## S3 Object Permissions\n\nThe object permission of files uploaded to S3 by this plugin can be controlled by setting the `S3_UPLOADS_OBJECT_ACL`\nconstant. The default setting if not specified is `public-read` to allow objects to be read by anyone. If you don't\nwant the uploads to be publicly readable then you can define `S3_UPLOADS_OBJECT_ACL` as one of `private` or `authenticated-read`\nin you wp-config file:\n\n```PHP\n// Set the S3 object permission to private\ndefine('S3_UPLOADS_OBJECT_ACL', 'private');\n```\n\nFor more information on S3 permissions please see the Amazon S3 permissions documentation.\n\n## Custom Endpoints\n\nDepending on your requirements you may wish to use an alternative S3 compatible object storage system such as Minio, Ceph,\nDigital Ocean Spaces, Scaleway and others.\n\nYou can configure the endpoint by adding the following code to a file in the `wp-content/mu-plugins/` directory, for example `wp-content/mu-plugins/s3-endpoint.php`:\n\n```php\n\u003c?php\n// Filter S3 Uploads params.\nadd_filter( 's3_uploads_s3_client_params', function ( $params ) {\n\t$params['endpoint'] = 'https://your.endpoint.com';\n\t$params['use_path_style_endpoint'] = true;\n\t$params['debug'] = false; // Set to true if uploads are failing.\n\treturn $params;\n} );\n```\n\n**Note:** As of AWS SDK 3.337, S3 uses a [new type of integrity protection](https://github.com/aws/aws-sdk-php/issues/3062) which is not supported by all third-party S3-compatible APIs. If you experience errors, you may need to disable the new checksum functionality:\n\n```php\nadd_filter( 's3_uploads_s3_client_params', function ( $params ) {\n\t// ...\n\t$params['request_checksum_calculation'] = 'when_required';\n\t$params['response_checksum_validation'] = 'when_required';\n\treturn $params;\n} );\n```\n\n## Temporary Session Tokens\n\nIf your S3 access is configured to require a temporary session token in addition to the access key and secret, you should configure the credentials using the following code:\n\n```php\n// Filter S3 Uploads params.\nadd_filter( 's3_uploads_s3_client_params', function ( $params ) {\n\t$params['credentials']['token'] = 'your session token here';\n\treturn $params;\n} );\n```\n\n## Offline Development\n\nWhile it's possible to use S3 Uploads for local development (this is actually a nice way to not have to sync all uploads from production to development),\nif you want to develop offline you have a couple of options.\n\n1. Just disable the S3 Uploads plugin in your development environment.\n2. Define the `S3_UPLOADS_USE_LOCAL` constant with the plugin active.\n\nOption 2 will allow you to run the S3 Uploads plugin for production parity purposes, it will essentially mock\nAmazon S3 with a local stream wrapper and actually store the uploads in your WP Upload Dir `/s3/`.\n\n## Credits\n\nCreated by Human Made for high volume and large-scale sites. We run S3 Uploads on sites with millions of monthly page views, and thousands of sites.\n\nWritten and maintained by [Joe Hoyle](https://github.com/joehoyle). Thanks to all our [contributors](https://github.com/humanmade/S3-Uploads/graphs/contributors).\n\nInterested in joining in on the fun? [Join us, and become human!](https://hmn.md/is/hiring/)\n","funding_links":[],"categories":["PHP"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhumanmade%2FS3-Uploads","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhumanmade%2FS3-Uploads","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhumanmade%2FS3-Uploads/lists"}