Skip to content

Commit

Permalink
Adding Google Cloud Memorystore sample (GoogleCloudPlatform#1474)
Browse files Browse the repository at this point in the history
  • Loading branch information
jabubake authored and andrewsg committed May 9, 2018
1 parent 4987e3c commit 79c3f79
Show file tree
Hide file tree
Showing 9 changed files with 321 additions and 0 deletions.
15 changes: 15 additions & 0 deletions memorystore/redis/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Getting started with Googe Cloud Memorystore
Simple HTTP server example to demonstrate connecting to [Google Cloud Memorystore](https://cloud.google.com/memorystore/docs/redis).
This sample uses the [redis-py client](https://github.com/andymccurdy/redis-py).

## Running on GCE

Follow the instructions in [this guide](https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-gce) to deploy the sample application on a GCE VM.

## Running on GKE

Follow the instructions in [this guide](https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-gke) to deploy the sample application on GKE.

## Running on Google App Engine Flex

Follow the instructions in [this guide](https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-flex) to deploy the sample application on GAE Flex.
31 changes: 31 additions & 0 deletions memorystore/redis/app.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# [START memorystore_app_yaml]
runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
python_version: 3

# update with Redis instance host IP, port
env_variables:
REDISHOST: redis-ip
REDISPORT: 6379

# update with Redis instance network name
network:
name: default

#[END memorystore_app_yaml]
58 changes: 58 additions & 0 deletions memorystore/redis/gce_deployment/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash

# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START memorystore_deploy_sh]
if [ -z "$REDISHOST" ]; then
echo "Must set \$REDISHOST. For example: REDISHOST=127.0.0.1"
exit 1
fi

if [ -z "$REDISPORT" ]; then
echo "Must set \$REDISPORT. For example: REDISPORT=6379"
exit 1
fi

if [ -z "$GCS_APP_LOCATION" ]; then
echo "Must set \$GCS_APP_LOCATION. For example: GCS_APP_LOCATION=gs://my-bucket/app"
exit 1
fi

if [ -z "$ZONE" ]; then
ZONE=$(gcloud config get-value compute/zone -q)
echo $ZONE
fi

#Upload the tar to GCS
tar -cvf app.tar -C .. requirements.txt main.py
# Copy to GCS bucket
gsutil cp app.tar $GCS_APP_LOCATION

# Create an instance
gcloud compute instances create my-instance \
--image-family=debian-8 \
--image-project=debian-cloud \
--machine-type=g1-small \
--scopes cloud-platform \
--metadata-from-file startup-script=startup-script.sh \
--metadata app-location=$GCS_APP_LOCATION,redis-host=$REDISHOST,redis-port=$REDISPORT \
--zone $ZONE \
--tags http-server

gcloud compute firewall-rules create allow-http-server-8080 \
--allow tcp:8080 \
--source-ranges 0.0.0.0/0 \
--target-tags http-server \
--description "Allow port 8080 access to http-server"
# [END memorystore_deploy_sh]
65 changes: 65 additions & 0 deletions memorystore/redis/gce_deployment/startup-script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#! /bin/bash

# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START memorystore_startup_script_sh]
set -v

# Talk to the metadata server to get the project id and location of application binary.
PROJECTID=$(curl -s "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google")
GCS_APP_LOCATION=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/app-location" -H "Metadata-Flavor: Google")
REDISHOST=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/redis-host" -H "Metadata-Flavor: Google")
REDISPORT=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/redis-port" -H "Metadata-Flavor: Google")

# Install dependencies from apt
apt-get update
apt-get install -yq \
git build-essential supervisor python python-dev python-pip libffi-dev \
libssl-dev

# Install logging monitor. The monitor will automatically pickup logs send to
# syslog.
curl -s "https://storage.googleapis.com/signals-agents/logging/google-fluentd-install.sh" | bash
service google-fluentd restart &

gsutil cp $GCS_APP_LOCATION /app.tar
mkdir -p /app
tar -x -f /app.tar -C /app
cd /app

# Install the app dependencies
pip install --upgrade pip virtualenv
virtualenv /app/env
/app/env/bin/pip install -r /app/requirements.txt

# Create a pythonapp user. The application will run as this user.
getent passwd pythonapp || useradd -m -d /home/pythonapp pythonapp
chown -R pythonapp:pythonapp /app

# Configure supervisor to run the Go app.
cat >/etc/supervisor/conf.d/pythonapp.conf << EOF
[program:pythonapp]
directory=/app
environment=HOME="/home/pythonapp",USER="pythonapp",REDISHOST=$REDISHOST,REDISPORT=$REDISPORT
command=/app/env/bin/gunicorn main:app --bind 0.0.0:8080
autostart=true
autorestart=true
user=pythonapp
stdout_logfile=syslog
stderr_logfile=syslog
EOF

supervisorctl reread
supervisorctl update
# [END memorystore_startup_script_sh]
20 changes: 20 additions & 0 deletions memorystore/redis/gce_deployment/teardown.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash

# Copyright 2018 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START memorystore_teardown_sh]
gcloud compute instances delete my-instance

gcloud compute firewall-rules delete allow-http-server-8080
# [END memorystore_teardown_sh]
30 changes: 30 additions & 0 deletions memorystore/redis/gke_deployment/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# The Google App Engine python runtime is Debian Jessie with Python installed
# and various os-level packages to allow installation of popular Python
# libraries. The source is on github at:
# https://github.com/GoogleCloudPlatform/python-docker
FROM gcr.io/google_appengine/python

# Create a virtualenv for the application dependencies.
# If you want to use Python 2, add the -p python2.7 flag.
RUN virtualenv -p python3.4 /env

# Set virtualenv environment variables. This is equivalent to running
# source /env/bin/activate. This ensures the application is executed within
# the context of the virtualenv and will have access to its dependencies.
ENV VIRTUAL_ENV /env
ENV PATH /env/bin:$PATH

# Note: REDISHOST value here is only used for local testing
# See README.md on how to inject environment variable as ConfigMap on GKE
ENV REDISHOST 127.0.0.1
ENV REDISPORT 6379

# Install dependencies.
ADD requirements.txt /app/requirements.txt
RUN pip install -r /app/requirements.txt

# Add application code.
ADD . /app

CMD ["gunicorn", "-b", "0.0.0.0:8080", "main:app"]

39 changes: 39 additions & 0 deletions memorystore/redis/gke_deployment/visit-counter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: visit-counter
labels:
app: visit-counter
spec:
replicas: 1
template:
metadata:
labels:
app: visit-counter
spec:
containers:
- name: visit-counter
image: "gcr.io/<PROJECT-ID>/visit-counter:v1"
env:
- name: REDISHOST
valueFrom:
configMapKeyRef:
name: redishost
key: REDISHOST
ports:
- name: http
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: visit-counter
spec:
type: LoadBalancer
selector:
app: visit-counter
ports:
- port: 80
targetPort: 8080
protocol: TCP

46 changes: 46 additions & 0 deletions memorystore/redis/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START memorystore_main_py]
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. See entrypoint in app.yaml.
app.run(host='127.0.0.1', port=8080, debug=True)
# [END memorystore_main_py]
17 changes: 17 additions & 0 deletions memorystore/redis/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright 2018 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START memorystore_requirements]
Flask==0.12.2
gunicorn==19.7.1
redis==2.10.5
# [END memorystore_requirements]

0 comments on commit 79c3f79

Please sign in to comment.