Connecting to a Redis instance from a Cloud Run service

You can connect to a Redis instance from Cloud Run by using Direct VPC egress .

Setup

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

  1. Install the gcloud CLI 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.

Prepare VPC network egress for configuration

To connect to your Redis instance, your Cloud Run service must have access to the Redis instance's authorized VPC network.

To find the name of this network, run the following command:

gcloud redis instances describe INSTANCE_ID 
--region REGION 
--format "value(authorizedNetwork)"

Make a note of the network name.

Sample application

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

Clone the repository for your chosen 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 
 . 
 Pool 
 { 
  
 MaxIdle 
 : 
  
 maxConnections 
 , 
  
 Dial 
 : 
  
 func 
 () 
  
 ( 
 redis 
 . 
 Conn 
 , 
  
 error 
 ) 
  
 { 
  
 return 
  
 redis 
 . 
 Dial 
 ( 
 "tcp" 
 , 
  
 redisAddr 
 ) 
  
 }, 
  
 } 
  
 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" 
 : 
  
 ">=16.0.0" 
  
 }, 
  
 "dependencies" 
 : 
  
 { 
  
 "redis" 
 : 
  
 "^4.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 
 == 
 3.0.3 
 gunicorn 
 == 
 23.0.0 
 redis 
 == 
 6.0.0 
 Werkzeug 
 == 
 3.0.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 
 f 
 "Visitor number: 
 { 
 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

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 by running the following command:

    gcloud builds submit --tag gcr.io/ PROJECT_ID 
    /visit-count
  3. Deploy the container to Cloud Run by running the following command:

    gcloud run deploy \
        --image gcr.io/ PROJECT_ID 
    /visit-count \
        --allow-unauthenticated \
        --region REGION 
    \
        --network NETWORK 
    \
        --subnet SUBNET 
    \
        --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 Redis instance is located.
    • NETWORK is the name of the authorized VPC network that your Redis instance is attached to.
    • SUBNET is the name of your subnet. The subnet must be /26 or larger. Direct VPC egress supports IPv4 ranges RFC 1918 , RFC 6598 , and Class E.
    • 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.

Design a Mobile Site
View Site in Mobile | Classic
Share by: