Connecting to a Redis instance from a Cloud Run (fully managed) service

You can connect to a Redis instance from Cloud Run (fully managed) by using Serverless VPC Access. Your Cloud Run service must be in the same region as the Redis instance.

Setup

If you have already installed the Cloud SDK and have created a Redis instance, you can skip these steps.

  1. Install the Cloud SDK and initialize:

    gcloud init
    
  2. Follow the Quickstart Guide to create a Redis instance. Take note of the zone, IP address, and port of the Redis instance.

Configuring Serverless VPC Access

To connect to your Redis instance, your Cloud Run (fully managed) service needs access to the Redis instance's authorized VPC network. To enable this access, you need a Serverless VPC Access connector:

  1. Find the name of your Redis instance's authorized network with the command:

    gcloud redis instances describe INSTANCE_ID --region REGION --format "value(authorizedNetwork)"
    
  2. Follow the instructions at Creating a connector to create a Serverless VPC Access connector. Make sure you create the connector in the same region as your Redis instance, and make sure the connector is attached to the Redis instance's authorized VPC network. Remember the name of the connector.

Sample application

This sample HTTP server application establishes a connection to a Redis instance from a Cloud Run (fully managed) service.

Clone the repository for your desired programming language and navigate to the folder that contains the sample code:

Go

git clone https://github.com/GoogleCloudPlatform/golang-samples
cd golang-samples/memorystore/redis

Node.js

git clone https://github.com/GoogleCloudPlatform/nodejs-docs-samples
cd nodejs-docs-samples/memorystore/redis

Python

git clone https://github.com/GoogleCloudPlatform/python-docs-samples
cd python-docs-samples/memorystore/redis

This sample application increments a Redis counter every time the / endpoint is accessed.

Go

This application uses the github.com/gomodule/redigo/redis client. Install it by running the following command:

go get github.com/gomodule/redigo/redis

// Command redis is a basic app that connects to a managed Redis instance.
package main

import (
	"fmt"
	"log"
	"net/http"
	"os"

	"github.com/gomodule/redigo/redis"
)

var redisPool *redis.Pool

func incrementHandler(w http.ResponseWriter, r *http.Request) {
	conn := redisPool.Get()
	defer conn.Close()

	counter, err := redis.Int(conn.Do("INCR", "visits"))
	if err != nil {
		http.Error(w, "Error incrementing visitor counter", http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, "Visitor number: %d", counter)
}

func main() {
	redisHost := os.Getenv("REDISHOST")
	redisPort := os.Getenv("REDISPORT")
	redisAddr := fmt.Sprintf("%s:%s", redisHost, redisPort)

	const maxConnections = 10
	redisPool = redis.NewPool(func() (redis.Conn, error) {
		return redis.Dial("tcp", redisAddr)
	}, maxConnections)

	http.HandleFunc("/", incrementHandler)

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}
	log.Printf("Listening on port %s", port)
	if err := http.ListenAndServe(":"+port, nil); err != nil {
		log.Fatal(err)
	}
}

Node.js

This application uses the redis module.

{
  "name": "memorystore-redis",
  "description": "An example of using Memorystore(Redis) with Node.js",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": ">=8.0.0"
  },
  "dependencies": {
    "redis": "^3.0.0"
  }
}

'use strict';
const http = require('http');
const redis = require('redis');

const REDISHOST = process.env.REDISHOST || 'localhost';
const REDISPORT = process.env.REDISPORT || 6379;

const client = redis.createClient(REDISPORT, REDISHOST);
client.on('error', err => console.error('ERR:REDIS:', err));

// create a server
http
  .createServer((req, res) => {
    // increment the visit counter
    client.incr('visits', (err, reply) => {
      if (err) {
        console.log(err);
        res.status(500).send(err.message);
        return;
      }
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end(`Visitor number: ${reply}\n`);
    });
  })
  .listen(8080);

Python

This application uses Flask for web serving and the redis-py package to communicate with the Redis instance.

Flask==1.1.2
gunicorn==20.0.4
redis==3.5.3
import logging
import os

from flask import Flask
import redis

app = Flask(__name__)

redis_host = os.environ.get('REDISHOST', 'localhost')
redis_port = int(os.environ.get('REDISPORT', 6379))
redis_client = redis.StrictRedis(host=redis_host, port=redis_port)


@app.route('/')
def index():
    value = redis_client.incr('counter', 1)
    return 'Visitor number: {}'.format(value)


@app.errorhandler(500)
def server_error(e):
    logging.exception('An error occurred during a request.')
    return """
    An internal error occurred: <pre>{}</pre>
    See logs for full stacktrace.
    """.format(e), 500


if __name__ == '__main__':
    # This is used when running locally. Gunicorn is used to run the
    # application on Google App Engine and Cloud Run.
    # See entrypoint in app.yaml or Dockerfile.
    app.run(host='127.0.0.1', port=8080, debug=True)

Deploying the application to Cloud Run (fully managed)

To deploy the application:

  1. Copy the Dockerfile into the source directory:

    cp cloud_run_deployment/Dockerfile .
    
  2. Build a container image using Cloud Build with the following command:

    gcloud builds submit --tag gcr.io/PROJECT_ID/visit-count
    
  3. Deploy the container to Cloud Run (fully managed):

    gcloud run deploy \
    --image gcr.io/PROJECT_ID/visit-count \
    --platform managed \
    --allow-unauthenticated \
    --region REGION \
    --vpc-connector CONNECTOR_NAME \
    --set-env-vars REDISHOST=REDIS_IP,REDISPORT=REDIS_PORT
    

    where:

    • PROJECT_ID is your Google Cloud project's ID.
    • REGION is the region where your Serverless VPC Access connector and your Redis instance are located.
    • CONNECTOR_NAME is the name of your connector.
    • REDIS_IP and REDIS_PORT are the IP address and port number of your Redis instance.

After the deployment successfully completes, the command line displays your Cloud Run service's URL. Visit this URL in a web browser (or use a tool like curl) and see the count on your Redis instance increase each time the service is visited.