grow / grow-ext-google-cloud-images

Store images on Google Cloud Storage and serve them via Google's high-performance dynamic image serving and image transformation infrastructure.
MIT License
26 stars 2 forks source link

grow-ext-google-cloud-images

Build Status

An extension for hosting images in Google Cloud Storage and serving them via Google's high-performance dynamic image-serving infrastructure.

Concept

Google offers an API for serving images uploaded to Google Cloud Storage through a high-performance, dynamic image-serving infrastructure. The system provides users with a way to perform a number of operations on images on-the-fly – making it extremely well-suited for developers to implement assets sized, cropped, formatted, etc. in the right way for the user – with no added work.

For example, the image-serving infrastructure can reformat (JPG, PNG, WEBP), resize or crop, and transform the image in a number of ways on-the-fly.

Here's the workflow:

  1. Upload an image to Google Cloud Storage.
  2. Ensure the backend microservice has read access to the object in GCS. (More on this below).
  3. Use the template function or YAML extension provided in this extension.
  4. Supply options to the extension to generate the right URL.

Here are a few live examples:

# Resize to 100 pixels wide
s100

# Smart crop, border 100%, format PNG, size 200
pp-br100-rp-s200

# Size 200, rotate 90
s200-r90

# Width 100, height 300, crop, smart crop, quality 100, format JPG
w100-h300-c-pp-l100-rj

Features

Usage

Microservice setup

The extension requires a microservice to upload the images to Google Cloud Storage and create the dynamic image service URLs. We recommend each project (or organization) set up their own instance of the microservice.

Clone this repository, then follow these steps.

cd backend
make install
make project=GOOGLE_CLOUD_PROJECT_ID deploy

# If using the default configuration, ensure the bucket is publicly readable by default.
# A different bucket can be used by editing `BUCKET_NAME` in `main.py`.
gsutil defacl set public-read gs://APPID.appspot.com

Once deployed, you will receive a URL like https://ext-cloud-images-dot-APPID.appspot.com. This is the backend service URL used in the next step.

Grow setup

  1. Create an extensions.txt file within your pod.
  2. Add to the file: git+git://github.com/grow/grow-ext-google-cloud-images
  3. Run grow install.
  4. Add the following section to podspec.yaml:
extensions:
  jinja2:
  - extensions.google_cloud_images.GoogleCloudImagesExtension
  preprocessors:
  - extensions.google_cloud_images.GoogleCloudImagesPreprocessor

preprocessors:
- kind: google_cloud_images
  backend: `<insert the backend URL from the microservice step>`
  # NOTE: We run an instance at https://gci.grow.io/
  # but we recommend you deploy your own instance, and just use ours for testing.

  # Optional. Allows usage of assets from one locale for another. In the below
  # example, all `en_AU` pages use `en_GB` assets.
  rewrite_locales:
  - rewrite: en_AU
    to: en_GB

Google Cloud Storage setup

Note that this extension requires you to grant OWNER access on your GCS objects to a service account corresponding to the microservice responsible for generating URLs. The account you grant access to depends upon the microservice.

  1. Visit the backend to learn which service account to grant access to. A sample backend runs at https://gci.grow.io. A service account might look like the following: grow-prod@appspot.gserviceaccount.com.

  2. Create or reuse an existing Google Cloud Storage bucket. Note that since OWNER access is required by the URL generation API, we recommend using a bucket specifically for uploading assets to this service.

# Create a new bucket.
gsutil mb -p <project> gs://<bucket>

# Set the default ACL for objects uploaded to the bucket. Note the below
# command grants OWNER access to the service account.
gsutil defacl ch -u account@example.com:O gs://<bucket>

# If using the web uploader you will also need to grant access to the service
# account to create objects.
gsutil acl ch -u account@example.com:O gs://<bucket>

# Ensure that the files are set with `public-read` permissions. URLs generated
# by the images service respect GCS object permissions so if you intend to serve
# them publicly, they will need to be `public-read`. Adjust the default ACL with
# the command below.
gsutil defacl set public-read gs://<bucket>

# Upload assets to the Google Cloud Storage bucket.
gsutil cp file.jpg gs://<bucket>/<path>/

NOTE: Ensure the service account has Storage Admin permission on the bucket. Storage Legacy Bucket Owner is not sufficient. The permissions can be modified from the "Permissions" tab on the GCS Console.

Usage in templates

(WIP)

# Default image URL.
{{google_image("/bucket/folder/path.jpg").url()}}

# Image URL with 1440 size option appended.
{{google_image("/bucket/folder/path.jpg").url(['s1440'])}}

# Localized image URL.
{{google_image("/bucket/folder/path@{locale}.jpg").url()}}

# Object properties.
{% set image = google_image("/bucket/folder/path.jpg") %}
{{image.content_type}}
{{image.created}}
{{image.dimensions}}
{{image.etag}}
{{image.height}}
{{image.locale}}
{{image.size}}
{{image.url()}}
{{image.width}}

URL options

The url method of GoogleCloudImage objects accepts a list of options to append to the URLs generated by Google's image-serving infrastructure. The options determine the behavior of the image served.

The following optios can be provided to the url method. See details on StackOverflow.

Size and crop

Rotation

Format

Animated GIF

Miscellaneous