Non-Official Google Cloud Storage Provider for Strapi Upload
Install the package from your app root directory
with npm
npm install @strapi-community/strapi-provider-upload-google-cloud-storage --save
or yarn
yarn add @strapi-community/strapi-provider-upload-google-cloud-storage
The bucket should be created with fine grained access control, as the plugin will configure uploaded files with public read access.
If you are deploying to a Google Cloud Platform product that supports Application Default Credentials (such as App Engine, Cloud Run, and Cloud Functions etc.), then you can skip this step.
If you are deploying outside GCP, then follow these steps to set up authentication:
- In the GCP Console, go to the Create service account key page.
- From the Service account list, select New service account.
- In the Service account name field, enter a name.
- From the Role list, select Cloud Storage > Storage Admin.
- Select
JSON
for Key Type - Click Create. A JSON file that contains your key downloads to your computer.
- Copy the full content of the downloaded JSON file
- Open the Strapi configuration file
- Paste it into the "Service Account JSON" field (as
string
orJSON
, be careful with indentation)
You will find below many examples of configurations, for each example :
- If you are deploying outside GCP, then follow the steps above Setting up Google authentication
- Set the
#bucketName#
field and replaceBucket-name
by yours previously create - Default
baseUrl
is working, but you can replace it by yours (if you use a custom baseUrl) - Save the configuration file
- Enjoy !
Example with application default credentials (minimal setup)
This works only for deployment to GCP products such as App Engine, Cloud Run, and Cloud Functions etc.
Edit ./config/plugins.js
module.exports = {
upload: {
config: {
provider: '@strapi-community/strapi-provider-upload-google-cloud-storage',
providerOptions: {
bucketName: '#bucketName#',
publicFiles: false,
uniform: false,
basePath: '',
},
},
},
//...
}
If you set publicFiles
to false
, the assets will be signed on the Content Manager (not the Content API). Consequently, they will only be visible to users who are authenticated.
You can set the expiry time of the signed URL by setting the expires
option in the providerOptions
object. See more in expires.
Example with credentials for outside GCP account
Edit ./config/plugins.js
module.exports = {
upload: {
config: {
provider: '@strapi-community/strapi-provider-upload-google-cloud-storage',
providerOptions: {
bucketName: '#bucketName#',
publicFiles: true,
uniform: false,
serviceAccount: {}, // replace `{}` with your serviceAccount JSON object
baseUrl: 'https://storage.googleapis.com/{bucket-name}',
basePath: '',
},
},
},
//...
}
If you have different upload provider by environment, you can override plugins.js
file by environment :
config/env/development/plugins.js
config/env/production/plugins.js
This file, under config/env/{env}/
will be overriding default configuration present in main folder config
.
Example with environment variable
module.exports = ({ env }) => ({
upload: {
config: {
provider: '@strapi-community/strapi-provider-upload-google-cloud-storage',
providerOptions: {
serviceAccount: env.json('GCS_SERVICE_ACCOUNT'),
bucketName: env('GCS_BUCKET_NAME'),
basePath: env('GCS_BASE_PATH'),
baseUrl: env('GCS_BASE_URL'),
publicFiles: env('GCS_PUBLIC_FILES'),
uniform: env('GCS_UNIFORM'),
},
},
},
//...
});
Environment variable can be changed has your way.
Edit ./config/middlewares.js
- In the field
img-src
andmedia-src
add your own CDN url, by default it'sstorage.googleapis.com
but you need to add your own CDN url
module.exports = [
'strapi::errors',
{
name: 'strapi::security',
config: {
contentSecurityPolicy: {
useDefaults: true,
directives: {
'connect-src': ["'self'", 'https:'],
'img-src': ["'self'", 'data:', 'blob:', 'storage.googleapis.com'],
'media-src': ["'self'", 'data:', 'blob:', 'storage.googleapis.com'],
upgradeInsecureRequests: null,
},
},
},
},
'strapi::cors',
'strapi::poweredBy',
'strapi::logger',
'strapi::query',
'strapi::body',
'strapi::favicon',
'strapi::public',
];
JSON data provide by Google Account (explained before). If you are deploying to a GCP product that supports Application Default credentials, you can leave this omitted, and authentication will work automatically.
Can be set as a String, JSON Object, or omitted.
The name of the bucket on Google Cloud Storage.
- Required
You can find more information on Google Cloud documentation.
Define your base Url, first is default value :
- https://storage.googleapis.com/{bucket-name}
- https://{bucket-name}
- http://{bucket-name}
Define base path to save each media document.
- Optional
Boolean to define a public attribute to file when upload file to storage.
- Default value :
true
- Optional
Boolean to define uniform
access, when uniform bucket-level access is enabled.
- Default value :
false
- Optional
Boolean to define skipCheckBucket
, when skipCheckBucket is enabled, we skip to check if the bucket exist. It's useful for private bucket.
- Default value :
false
- Optional
Number to set the cache-control header for uploaded files.
- Default value :
3600
- Optional
Value to define if files are uploaded and stored with gzip compression.
- Possible values:
true
,false
,auto
- Default value :
auto
- Optional
Value to define expiration time for signed URLS. Files are signed when publicFiles
is set to false
.
- Possible values:
Date
,number
,string
- Default value :
900000
(15 minutes) - Max value :
604800000
(7 days) - Optional
Function that is executed to compute the metadata for a file when it is uploaded.
When no function is provided, the following metadata is used:
{
contentDisposition: `inline; filename="${file.name}"`,
cacheControl: `public, max-age=${config.cacheMaxAge || 3600}`,
}
- Default value:
undefined
- Optional
Example:
metadata: (file) => ({
cacheControl: `public, max-age=${60 * 60 * 24 * 7}`, // One week
contentLanguage: 'en-US',
contentDisposition: `attachment; filename="${file.name}"`,
}),
The available properties can be found in the Cloud Storage JSON API documentation.
Function that is executed to generate the name of the uploaded file. This method can give more control over the file name and can for example be used to include a custom hashing function or dynamic path.
When no function is provided, the default algorithm is used.
- Default value:
undefined
- Optional
Example:
generateUploadFileName: async (file) => {
const hash = await ...; // Some hashing function, for example MD-5
const extension = file.ext.toLowerCase().substring(1);
return `${extension}/${slugify(path.parse(file.name).name)}-${hash}.${extension}`;
},
Error uploading file to Google Cloud Storage: Cannot insert legacy ACL for an object when uniform bucket-level access is enabled
When this error occurs, you need to set uniform
variable to true
.
Error: Error parsing data "Service Account JSON", please be sure to copy/paste the full JSON file
When this error occurs, it's probably because you have missed something with the service account json configuration.
Follow this step :
- Open your
ServiceAccount
json file - Copy the full content of the file
- Paste it under the variable
ServiceAccount
inplugins.js
config file in JSON
Due to release of Strapi v4, you need to migrate your databases files informations. Follow our migration guide.
- GitHub (Bug reports, contributions)
You can also used official support platform of Strapi, and search @Lith
(maintainer)
- Discord (For live discussion with the Community and Strapi team)
- Community Forum (Questions and Discussions)
See the MIT License file for licensing information.