File: README.md
Online Boutique is a cloud-first microservices demo application. The application is a
web-based e-commerce app where users can browse items, add them to the cart, and purchase them.
Google uses this application to demonstrate how developers can modernize enterprise applications using Google Cloud products, including: Google Kubernetes Engine (GKE), Cloud Service Mesh (CSM), gRPC, Cloud Operations, Spanner, Memorystore, AlloyDB, and Gemini. This application works on any Kubernetes cluster.
If youβre using this demo, please β Star this repository to show your interest!
Note to Googlers: Please fill out the form at go/microservices-demo.
Architecture
Online Boutique is composed of 11 microservices written in different
languages that talk to each other over gRPC.
Find Protocol Buffers Descriptions at the ./protos directory.
| Service | Language | Description |
|---|---|---|
| frontend | Go | Exposes an HTTP server to serve the website. Does not require signup/login and generates session IDs for all users automatically. |
| cartservice | C# | Stores the items in the user's shopping cart in Redis and retrieves it. |
| productcatalogservice | Go | Provides the list of products from a JSON file and ability to search products and get individual products. |
| currencyservice | Node.js | Converts one money amount to another currency. Uses real values fetched from European Central Bank. It's the highest QPS service. |
| paymentservice | Node.js | Charges the given credit card info (mock) with the given amount and returns a transaction ID. |
| shippingservice | Go | Gives shipping cost estimates based on the shopping cart. Ships items to the given address (mock) |
| emailservice | Python | Sends users an order confirmation email (mock). |
| checkoutservice | Go | Retrieves user cart, prepares order and orchestrates the payment, shipping and the email notification. |
| recommendationservice | Python | Recommends other products based on what's given in the cart. |
| adservice | Java | Provides text ads based on given context words. |
| loadgenerator | Python/Locust | Continuously sends requests imitating realistic user shopping flows to the frontend. |
Screenshots
| Home Page | Checkout Screen |
|---|---|
Quickstart (GKE)
Ensure you have the following requirements:
- Google Cloud project.
- Shell environment with
gcloud,git, andkubectl.
Clone the latest major version.
shgit clone --depth 1 --branch v0 https://github.com/GoogleCloudPlatform/microservices-demo.git cd microservices-demo/The
--depth 1argument skips downloading git history.Set the Google Cloud project and region and ensure the Google Kubernetes Engine API is enabled.
shexport PROJECT_ID= export REGION=us-central1 gcloud services enable container.googleapis.com \ --project=${PROJECT_ID}Substitute `` with the ID of your Google Cloud project.
Create a GKE cluster and get the credentials for it.
shgcloud container clusters create-auto online-boutique \ --project=${PROJECT_ID} --region=${REGION}Creating the cluster may take a few minutes.
Deploy Online Boutique to the cluster.
shkubectl apply -f ./release/kubernetes-manifests.yamlWait for the pods to be ready.
shkubectl get podsAfter a few minutes, you should see the Pods in a
Runningstate:textNAME READY STATUS RESTARTS AGE adservice-76bdd69666-ckc5j 1/1 Running 0 2m58s cartservice-66d497c6b7-dp5jr 1/1 Running 0 2m59s checkoutservice-666c784bd6-4jd22 1/1 Running 0 3m1s currencyservice-5d5d496984-4jmd7 1/1 Running 0 2m59s emailservice-667457d9d6-75jcq 1/1 Running 0 3m2s frontend-6b8d69b9fb-wjqdg 1/1 Running 0 3m1s loadgenerator-665b5cd444-gwqdq 1/1 Running 0 3m paymentservice-68596d6dd6-bf6bv 1/1 Running 0 3m productcatalogservice-557d474574-888kr 1/1 Running 0 3m recommendationservice-69c56b74d4-7z8r5 1/1 Running 0 3m1s redis-cart-5f59546cdd-5jnqf 1/1 Running 0 2m58s shippingservice-6ccc89f8fd-v686r 1/1 Running 0 2m58sAccess the web frontend in a browser using the frontend's external IP.
shkubectl get service frontend-external | awk '{print $4}'Visit
http://EXTERNAL_IPin a web browser to access your instance of Online Boutique.Congrats! You've deployed the default Online Boutique. To deploy a different variation of Online Boutique (e.g., with Google Cloud Operations tracing, Istio, etc.), see Deploy Online Boutique variations with Kustomize.
Once you are done with it, delete the GKE cluster.
shgcloud container clusters delete online-boutique \ --project=${PROJECT_ID} --region=${REGION}Deleting the cluster may take a few minutes.
Additional deployment options
- Terraform: See these instructions to learn how to deploy Online Boutique using Terraform.
- Istio / Cloud Service Mesh: See these instructions to deploy Online Boutique alongside an Istio-backed service mesh.
- Non-GKE clusters (Minikube, Kind, etc): See the Development guide to learn how you can deploy Online Boutique on non-GKE clusters.
- AI assistant using Gemini: See these instructions to deploy a Gemini-powered AI assistant that suggests products to purchase based on an image.
- And more: The
/kustomizedirectory contains instructions for customizing the deployment of Online Boutique with other variations.
Documentation
- Development to learn how to run and develop this app locally.
Demos featuring Online Boutique
- Security hardening of the OnlineBoutique sample apps with the Docker Hardened Images (DHI)
- alpine, distroless or scratch?
- Platform Engineering in action: Deploy the Online Boutique sample apps with Score and Humanitec
- The new Kubernetes Gateway API with Istio and Anthos Service Mesh (ASM)
- Use Azure Redis Cache with the Online Boutique sample on AKS
- Sail Sharp, 8 tips to optimize and secure your .NET containers for Kubernetes
- Deploy multi-region application with Anthos and Google cloud Spanner
- Use Google Cloud Memorystore (Redis) with the Online Boutique sample on GKE
- Use Helm to simplify the deployment of Online Boutique, with a Service Mesh, GitOps, and more!
- How to reduce microservices complexity with Apigee and Anthos Service Mesh
- gRPC health probes with Kubernetes 1.24+
- Use Google Cloud Spanner with the Online Boutique sample
- Seamlessly encrypt traffic from any apps in your Mesh to Memorystore (redis)
- Strengthen your app's security with Cloud Service Mesh and Anthos Config Management
- From edge to mesh: Exposing service mesh applications through GKE Ingress
- Take the first step toward SRE with Cloud Operations Sandbox
- Deploying the Online Boutique sample application on Cloud Service Mesh
- Anthos Service Mesh Workshop: Lab Guide
- KubeCon EU 2019 - Reinventing Networking: A Deep Dive into Istio's Multicluster Gateways - Steve Dake, Independent
- Google Cloud Next'18 SF
- Day 1 Keynote showing GKE On-Prem
- Day 3 Keynote showing Stackdriver
APM (Tracing, Code Search, Profiler, Google Cloud Build) - Introduction to Service Management with Istio
- Google Cloud Next'18 London β Keynote
showing Stackdriver Incident Response Management - Microservices demo showcasing Go Micro
File: docs/releasing/README.md
Releasing Online Boutique
This document walks through the process of creating a new release of Online Boutique.
Prerequisites for tagging a release
Choose the logical next release tag, using semantic versioning:
vX.Y.Z.If this release includes significant feature changes, update the minor version (
Y). Otherwise, for bug-fix releases or standard quarterly release, update the patch versionZ).Ensure that the following commands are in your
PATH:gsed(found in thegnu-sedBrew package for macOS, or by symlinkingsedfor Linux)gcloudhelm
Make sure that your
gcloudis authenticated:shgcloud auth login gcloud auth configure-docker us-central1-docker.pkg.dev
Create the release branch and PR
The preferred way to start a new release is to run the Manual Release Builder workflow in GitHub Actions.
Trigger the release workflow
- Go to the Actions tab of the repository on GitHub.
- Select the Manual Release Builder workflow from the left sidebar.
- Click the Run workflow dropdown button.
- Fill in the parameters:
- The release version (e.g., v0.3.5): Set the version string
vX.Y.Z. - The repository prefix for container images: Defaults to
us-central1-docker.pkg.dev/online-boutique-ci/microservices-demo. - The Google Cloud Project ID for the release CI: Defaults to
online-boutique-ci.
- The release version (e.g., v0.3.5): Set the version string
- Click Run workflow.
This workflow will:
- Build and push the container images for all services.
- Regenerate YAML manifests and Kustomize bases.
- Package and push the Helm chart.
- Create and push a new branch
release/vX.Y.Zand a git tagvX.Y.Z. - Automatically open a Pull Request targeting
mainwith the release checklist.
Alternative: Manual release script
If you need to run the release process manually from your local machine, ensure you have the prerequisites installed and authenticated. Then run the make-release.sh script:
# assuming you are inside the root path of the microservices-demo repository
export TAG=vX.Y.Z # This is the new version (e.g. `v0.3.5`)
export REPO_PREFIX=us-central1-docker.pkg.dev/online-boutique-ci/microservices-demo # This is the Docker repository for tagged images
export PROJECT_ID=online-boutique-ci # This is the Google Cloud project for the release CI
./docs/releasing/make-release.shOnce the script completes, you can go to the GitHub branches list to manually create a pull request targeting main.
This process is going to trigger multiple CI checks as well as stage the release onto a temporary cluster. Once the PR has been approved and all checks are successfully passing, you can then merge the branch. Make sure to include the release draft (see next section) in the pull-request description for reviewers to see.
Once reviewed and you're ready to merge, make sure to not delete the release branch or the tags during that process.
Add notes to the release
Once the PR has been fully merged, you are ready to create a new release for the newly created tag.
- Click the breadcrumbs on the row of the latest tag that was created in the tags page
- Select the
Create releaseoption
The release notes should contain a brief description of the changes since the previous release (like bug fixed and new features). For inspiration, you can look at the list of releases.
Note: No assets need to be uploaded. They are picked up automatically from the tagged revision
Deploy on the production environment
Once the release notes are published, you should then replace the version of the production environment to the newly published version.
Connect to the online-boutique-release GKE cluster:
shgcloud container clusters get-credentials online-boutique-release \ --zone us-central1-c --project online-boutique-ciDeploy
release/kubernetes-manifests.yamlto it:shkubectl apply -f ./release/kubernetes-manifests.yamlRemove unnecessary objects:
shkubectl delete service frontend-external kubectl delete deployment loadgeneratorMake sure cymbal-shops.retail.cymbal.dev works.
Update major tags
- Update the relevant major tag (for example,
v1):
export MAJOR_TAG=v0 # Edit this as needed (to v1/v2/v3/etc)
git checkout release/${TAG}
git pull
git push --delete origin ${MAJOR_TAG} # Delete the remote tag (if it exists)
git tag --delete ${MAJOR_TAG} # Delete the local tag (if it exists)
git tag -a ${MAJOR_TAG} -m "Updating ${MAJOR_TAG} to its most recent release: ${TAG}"
git push origin ${MAJOR_TAG} # Push the new tag to originAnnounce the new release internally
Once the new release is out, you can now announce it via g/online-boutique-announce.
File: docs/adding-new-microservice.md
Adding a new microservice
This document outlines the steps required to add a new microservice to the Online Boutique application.
1. Create a new directory
Create a new directory for your microservice within the src/ directory. The directory name should be the name of your microservice.
2. Add source code
Place your microservice's source code inside the newly created directory. The structure of this directory should follow the conventions of the existing microservices. For example, a Python-based service would include at minimum the following files:
README.md: The service's description and documentation.main.py: The application's entry point.requirements.in: A list of Python dependencies.Dockerfile: To containerize the application.
Take a look at existing microservices for inspiration.
3. Create a Dockerfile
Create a Dockerfile in your microservice's directory. This file will define the steps to build a container image for your service.
Refer to this example and tweak based on your new service's needs: https://github.com/GoogleCloudPlatform/microservices-demo/blob/main/src/frontend/Dockerfile
4. Create Kubernetes manifests
Create a new directory under kustomize/components/ in the root of the repository for your microservice. Inside this directory, add the necessary Kubernetes YAML files for your new microservice. This typically includes:
- A Deployment to manage your service's pods.
- A Service to expose your microservice to other services within the cluster.
Ensure you follow the existing naming conventions and that the container image specified in the Deployment matches the one built by your cloudbuild.yaml and skaffold.yaml files.
Refer to this example and tweak based on your new service's needs: https://github.com/GoogleCloudPlatform/microservices-demo/tree/main/kustomize/components/shopping-assistant
5. Update the root `kustomization.yaml` file
Add your newly created component to the root kustomization file so it gets picked up by the deployment cycle.
The file is available here: https://github.com/GoogleCloudPlatform/microservices-demo/blob/main/kustomize/kustomization.yaml
6. Update the root `skaffold.yaml`
Add your newly created service to the root skaffold file so the images build correctly.
The file is available here: https://github.com/GoogleCloudPlatform/microservices-demo/blob/main/skaffold.yaml
7. Update the Helm chart
Add your newly created service to the Helm chart templates and default values.
The chart is available here: https://github.com/GoogleCloudPlatform/microservices-demo/tree/main/helm-chart
8. Update the documentation
Finally, update the project's documentation to reflect the addition of your new microservice. This may include:
- Adding a section to the main
README.mdif the service introduces significant new functionality. - Updating the architecture diagrams in the
docs/imgdirectory. - Adding a new document in the
docsdirectory if the service requires detailed explanation.
File: docs/cloudshell-tutorial.md
Online Boutique quickstart
This tutorial shows you how to deploy Online Boutique to a Kubernetes cluster.
You'll be able to run Online Boutique on:
- a local minikube cluster, which comes built in to the Cloud Shell instance
- a Google Kubernetes Engine cluster using a new or existing Google Cloud project
Let's get started!
Kubernetes cluster setup
Set up a Kubernetes cluster using the instructions below for either minikube or GKE.
Minikube instructions
Minikube creates a local Kubernetes cluster on Cloud Shell.
Click
minikube on the status bar located at the bottom of the editor window.The command palette will prompt you to choose which minikube cluster to control. Select minikube and, in the next prompt, click Start if the cluster has not already been started.
If prompted, authorize Cloud Shell to make a GCP API call with your credentials.
It may take a few minutes for minikube to finish starting.
Once minikube has started, you're ready to move on to the next step.
GKE instructions
In order to create a GKE cluster, you'll need to create a Google Cloud project or use an existing project.
Access the command palette by going to View > Find Command.
Run the command "Cloud Code: Create GKE cluster".
Select your GCP project.
Apply the following configurations in the GKE wizard:
- Zone: us-central1-b
- Cluster name: onlineboutique
- Node count: 4
- Machine type: e2-standard-2
- Click Create Cluster. Once your cluster has been created successfully, you can move on to the next step.
Run on Kubernetes
Now you can run Online Boutique on your Kubernetes cluster!
Launch the
Cloud Code menu from the status bar and selectRun on Kubernetes .If prompted to select a Skaffold Profile, select [default].
Select Yes to confirm your current context.
If you're using a GKE cluster, you'll need to confirm your container image registry.
If prompted, authorize Cloud Shell to make a GCP API call with your credentials.
Cloud Code uses configurations defined in
Once the app is running, the local URLs will be displayed in the
Output terminal.To access your Online Boutique frontend service, click on the
Web Preview button in the upper right of the editor window.Select Change Port and enter '4503' as the port, then click Change and Preview. Your app will open in a new window.
Stop the app
To stop running the app:
Go to the
Debug view Click the Stop icon.
Select Yes to clean up deployed resources.
You can start, stop, and debug apps from the Debug view.
Clean up
If you've deployed your app to a GKE cluster in your Google Cloud project, you'll want to delete the cluster to avoid incurring charges.
Navigate to the
Cloud Code - Kubernetes view in the Activity bar.Under the
Google Kubernetes Engine Explorer tab , right-click on your cluster and select Delete Cluster.
Conclusion
Congratulations! You've successfully deployed Online Boutique using Cloud Shell.
What's next?
Try other deployment options for Online Boutique:
- Istio/Cloud Service Mesh:
See these instructions .
Learn more about the Cloud Shell IDE environment and the Cloud Code extension.
File: docs/deploystack.md
Deploy Online Boutique with DeployStack
The "Open in Google Cloud Shell" button below will use DeployStack to deploy Online Boutique to a new Google Kubernetes Engine (GKE) cluster.
The button will open up a Cloud Shell session where you will select your Google Cloud project. After project selection, the following will happen automatically:
- a GKE cluster will be created inside the select project
- Online Boutique (and its load generator) will be deployed to that cluster
File: docs/development-guide.md
Development Guide
This doc explains how to build and run the Online Boutique source code locally using the skaffold command-line tool.
Prerequisites
- Docker for Desktop
- kubectl (can be installed via
gcloud components install kubectlfor Option 1 - GKE) - skaffold 2.0.2+ (latest version recommended), a tool that builds and deploys Docker images in bulk.
- Clone the repository.sh
git clone https://github.com/GoogleCloudPlatform/microservices-demo cd microservices-demo/ - A Google Cloud project with Google Container Registry enabled. (for Option 1 - GKE)
- Minikube (optional for Option 2 - Local Cluster)
- Kind (optional for Option 2 - Local Cluster)
Option 1: Google Kubernetes Engine (GKE)
π‘ Recommended if you're using Google Cloud and want to try it on
a realistic cluster. Note: If your cluster has Workload Identity enabled,
see these instructions
Create a Google Kubernetes Engine cluster and make sure
kubectlis pointing
to the cluster.shgcloud services enable container.googleapis.comshgcloud container clusters create-auto demo --region=us-central1textkubectl get nodesEnable Artifact Registry (AR) on your GCP project and configure the
dockerCLI to authenticate to AR:shgcloud services enable artifactregistry.googleapis.comshgcloud artifacts repositories create microservices-demo \ --repository-format=docker \ --location=us \shgcloud auth configure-docker -qIn the root of this repository, run:
textskaffold run --default-repo=us-docker.pkg.dev/PROJECT_ID/microservices-demoWhere
PROJECT_IDis replaced by your Google Cloud project ID.This command:
- Builds the container images.
- Pushes them to AR.
- Applies the
./kubernetes-manifestsdeploying the application to
Kubernetes.
Troubleshooting: If you get "No space left on device" error on Google
Cloud Shell, you can build the images on Google Cloud Build: Enable the
Cloud Build
API,
then runskaffold run -p gcb --default-repo=us-docker.pkg.dev/[PROJECT_ID]/microservices-demoinstead.Find the IP address of your application, then visit the application on your
browser to confirm installation.textkubectl get service frontend-externalNavigate to
http://EXTERNAL-IPto access the web frontend.
Option 2 - Local Cluster
Launch a local Kubernetes cluster with one of the following tools:
To launch Minikube (tested with Ubuntu Linux). Please, ensure that the
local Kubernetes cluster has at least:- 4 CPUs
- 4.0 GiB memory
- 32 GB disk space
shellminikube start --cpus=4 --memory 4096 --disk-size 32gTo launch Docker for Desktop (tested with Mac/Windows). Go to Preferences:
- choose βEnable Kubernetesβ,
- set CPUs to at least 3, and Memory to at least 6.0 GiB
- on the "Disk" tab, set at least 32 GB disk space
To launch a Kind cluster:
shellkind create cluster
Run
kubectl get nodesto verify you're connected to the respective control plane.Run
skaffold run(first time will be slow, it can take ~20 minutes).
This will build and deploy the application. If you need to rebuild the images
automatically as you refactor the code, runskaffold devcommand.Run
kubectl get podsto verify the Pods are ready and running.Run
kubectl port-forward deployment/frontend 8080:8080to forward a port to the frontend service.Navigate to
localhost:8080to access the web frontend.
Adding a new microservice
In general, the set of core microservices for Online Boutique is fairly complete and unlikely to change in the future, but it can be useful to add an additional optional microservice that can be deployed to complement the core services.
See the Adding a new microservice guide for instructions on how to add a new microservice.
Cleanup
If you've deployed the application with skaffold run command, you can runskaffold delete to clean up the deployed resources.
File: docs/product-requirements.md
Product Requirements
This document contains a list of requirements that every change made to this repository should meet.
Every change must:
- Preserve the golden user journey taken by Kubernetes beginners.
- Preserve the simplicity of demos.
- Preserve the simplicity of the GKE quickstart.
These requirements are about the default deployment (default configuration) of Online Boutique.
Changes that will violate any of these rules should not be built into the default configuration of Online Boutique.
Such changes should be opt-in only β ideally, as a Kustomize Component if they align with the purpose of Online Boutique.
1. Preserve the golden user journey taken by Kubernetes beginners
The following statement about Online Boutique should always be true:
A user outside of Google can deploy Online Boutique's default configuration on a kind Kubernetes cluster.
This statement describes the golden user journey that we expect new Kubernetes users to take while onboarding to Online Boutique.
Being able to run Online Boutique on a kind cluster ensures that Online Boutique is free and cloud-agnostic. This is aligned with Google's mission of making information universally accessible and useful. To be specific, Online Boutique should be useful and accessible to developers that are new to Kubernetes.
2. Preserve the simplicity of demos
New changes should not complicate the primary user journey showcased in live demos and tutorials.
Today, the primary user journey is as follows:
- Visit Online Boutique on a web browser.
- Select an item from the homepage and add the item to the cart.
- The checkout form is pre-populated with placeholder data (e.g. the shipping address).
- The user checks out and completes the order.
3. Preserve the simplicity of the GKE quickstart
New changes should not add additional complexity in the main Online Boutique quickstart.
In particular, new changes should not add extra required steps or additional required tools in that quickstart.
Ideally, extensions to Online Boutique's default functionality (such as a new microservice or a new cloud service integration) should be added as a Kustomize Component which users can optionally opt into.
File: docs/purpose.md
Purpose
Today, the primary purpose of Online Boutique is to demonstrate:
- Google Kubernetes Engine (GKE)
- Anthos
- Google Cloud Operations
- tools and technologies commonly used alongside the above products
while being accessible and useful to all new Kubernetes users.
Why does the purpose matter?
We filter and prioritize the work to be done in this repository based on the purpose defined above.
If you wish to make changes to this repository that do not align with the above purpose, we encourage you to maintain your own fork of Online Boutique.
File: helm-chart/README.md
Helm chart for Online Boutique
If you'd like to deploy Online Boutique via its Helm chart, you could leverage the following instructions.
Warning: Online Boutique's Helm chart is currently experimental. If you have feedback or run into issues, let us know inside GitHub Issue #1319 or by creating a new GitHub Issue.
Deploy the default setup of Online Boutique:
helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \
--installDeploy advanced scenario of Online Boutique:
helm upgrade onlineboutique oci://us-docker.pkg.dev/online-boutique-ci/charts/onlineboutique \
--install \
--create-namespace \
--set images.repository=us-docker.pkg.dev/my-project/microservices-demo \
--set frontend.externalService=false \
--set redis.create=false \
--set cartservice.database.type=spanner \
--set cartservice.database.connectionString=projects/my-project/instances/onlineboutique/databases/carts \
--set serviceAccounts.create=true \
--set authorizationPolicies.create=true \
--set networkPolicies.create=true \
--set sidecars.create=true \
--set frontend.virtualService.create=true \
--set 'serviceAccounts.annotations.iam\.gke\.io/gcp-service-account=spanner-db-user@my-project.iam.gserviceaccount.com' \
--set serviceAccounts.annotationsOnlyForCartservice=true \
-n onlineboutiqueFor the full list of configurations, see values.yaml.
You could also find advanced scenarios with these blogs below:
- Online Boutique sampleβs Helm chart, to simplify the setup of advanced and secured scenarios with Service Mesh and GitOps
- gRPC health probes with Kubernetes 1.24+
- Use Google Cloud Spanner with the Online Boutique sample
File: kubernetes-manifests/README.md
./kubernetes-manifests
:warning: Kubernetes manifests provided in this directory are not directly
deployable to a cluster. They are meant to be used with skaffold command to
insert the correct image: tags.
Use the manifests in /release directory which are configured with
pre-built public images.
