Skip to main content
Version: main

Deploying the Sock Shop Application

In this example, we'll show how easy it is to deploy a real world application using Weave GitOps. The Sock Shop is a well known microservices application that is widely used in demonstration and testing of microservice environments such as Kubernetes. We'll actually see two different ways of deploying the Sock Shop:

  • as a plain set of Kubernetes manifests
  • as a helm chart

Prerequisites

In order to deploy the Sock Shop, you need to first deploy Weave GitOps to a Kubernetes cluster. If you'd like to test this out locally, you can set up a kind cluster by following the instructions at the link. Regardless of which cluster you'd like to use, you can install Weave GitOps by first making sure your default kubeconfig points to the chosen cluster and then running gitops install --app-config-url <configuration repository>. The configuration repository is a Git repository that will hold the resource definitions required to manage your applications via GitOps. Please note that these examples are being run with the GITOPS_TOKEN environment variable set to a valid GitHub Personal Access Token (PAT) possessing repo access. If that were not the case, you would see extra user authentication steps in the output.

gitops install --app-config-url ssh://git@github.com/example/external.git
โœš generating manifestsโœ” manifests build completedโ–บ installing components in wego-system namespaceCustomResourceDefinition/alerts.notification.toolkit.fluxcd.io createdCustomResourceDefinition/buckets.source.toolkit.fluxcd.io createdCustomResourceDefinition/gitrepositories.source.toolkit.fluxcd.io createdCustomResourceDefinition/helmcharts.source.toolkit.fluxcd.io createdCustomResourceDefinition/helmreleases.helm.toolkit.fluxcd.io createdCustomResourceDefinition/helmrepositories.source.toolkit.fluxcd.io createdCustomResourceDefinition/imagepolicies.image.toolkit.fluxcd.io createdCustomResourceDefinition/imagerepositories.image.toolkit.fluxcd.io createdCustomResourceDefinition/imageupdateautomations.image.toolkit.fluxcd.io createdCustomResourceDefinition/kustomizations.kustomize.toolkit.fluxcd.io createdCustomResourceDefinition/providers.notification.toolkit.fluxcd.io createdCustomResourceDefinition/receivers.notification.toolkit.fluxcd.io createdNamespace/wego-system createdServiceAccount/wego-system/helm-controller createdServiceAccount/wego-system/image-automation-controller createdServiceAccount/wego-system/image-reflector-controller createdServiceAccount/wego-system/kustomize-controller createdServiceAccount/wego-system/notification-controller createdServiceAccount/wego-system/source-controller createdClusterRole/crd-controller-wego-system createdClusterRoleBinding/cluster-reconciler-wego-system createdClusterRoleBinding/crd-controller-wego-system createdService/wego-system/notification-controller createdService/wego-system/source-controller createdService/wego-system/webhook-receiver createdDeployment/wego-system/helm-controller createdDeployment/wego-system/image-automation-controller createdDeployment/wego-system/image-reflector-controller createdDeployment/wego-system/kustomize-controller createdDeployment/wego-system/notification-controller createdDeployment/wego-system/source-controller createdNetworkPolicy/wego-system/allow-egress createdNetworkPolicy/wego-system/allow-scraping createdNetworkPolicy/wego-system/allow-webhooks createdโ—Ž verifying installationโœ” helm-controller: deployment readyโœ” image-automation-controller: deployment readyโœ” image-reflector-controller: deployment readyโœ” kustomize-controller: deployment readyโœ” notification-controller: deployment readyโœ” source-controller: deployment readyโœ” install finishedDeploy key generated and uploaded to git providerโ–บ Writing manifests to diskโ–บ Committing and pushing gitops updates for applicationโ–บ Pushing app changes to repositoryโ–บ Applying manifests to the clusterarete: /tmp/sock-shop>

Once you see โ–บ Applying manifests to the cluster, your cluster is ready to go with Weave GitOps.

Deploying with Weave GitOps#

Once you have a cluster running Weave GitOps, it's simple to deploy an application like Sock Shop.

To deploy the Sock Shop, we need to use gitops add app. gitops add app will store the GitOps automation support for your application in the .weave-gitops directory of the configuration repository you specified at install time. The definition of your application can be stored either in a separate repository or in the configuration repository itself (for a simple all-in-one configuration). If you want to store the application resources in the configuration repository, you only need to specify the --url flag which will be used for both application and configuration resources; however, this assumes that the application repository URL was passed to gitops install. If you want the application resources to be stored separately, you need to specify both --url and --app-config-url parameters. The --url parameter should be the URL of the repository containing the application definition and the --app-config-url parameter must be the URL that was used in gitops install.

First, let's fork the Sock Shop repository. You can simply go to the repository in GitHub and select Fork.

Now, we can add the Sock Shop application to the configuration repository so it can be managed through GitOps:

> gitops add app --url ssh://git@github.com/example/microservices-demo.git --path ./deploy/kubernetes/manifests --app-config-url
ssh://git@github.com/example/external.git --auto-mergeAdding application:
Name: microservices-demoURL: ssh://git@github.com/example/microservices-demo.gitPath: ./deploy/kubernetes/manifestsBranch: masterType: kustomize
โ—Ž Checking cluster statusโœ” GitOps installedโœš Generating application spec manifestโœš Generating GitOps automation manifestsโ–บ Adding application "microservices-demo" to cluster "kind-kind" and repositoryโ–บ Committing and pushing gitops updates for applicationโ–บ Pushing app changes to repository>

Here we see all the pods running:

> kubectl get pods -ANAMESPACE            NAME                                           READY   STATUS    RESTARTS   AGEkube-system          coredns-558bd4d5db-jgcf2                       1/1     Running   0          9dkube-system          coredns-558bd4d5db-sht4v                       1/1     Running   0          9dkube-system          etcd-kind-control-plane                        1/1     Running   0          9dkube-system          kindnet-tdcd2                                  1/1     Running   0          9dkube-system          kube-apiserver-kind-control-plane              1/1     Running   0          9dkube-system          kube-controller-manager-kind-control-plane     1/1     Running   0          9dkube-system          kube-proxy-mqvbc                               1/1     Running   0          9dkube-system          kube-scheduler-kind-control-plane              1/1     Running   0          9dlocal-path-storage   local-path-provisioner-547f784dff-mqgjc        1/1     Running   0          9dsock-shop            carts-b4d4ffb5c-g82h6                          1/1     Running   0          9dsock-shop            carts-db-6c6c68b747-xtlgk                      1/1     Running   0          9dsock-shop            catalogue-759cc6b86-jk4gf                      1/1     Running   0          9dsock-shop            catalogue-db-96f6f6b4c-865w4                   1/1     Running   0          9dsock-shop            front-end-5c89db9f57-99vw6                     1/1     Running   0          9dsock-shop            orders-7664c64d75-qlz9d                        1/1     Running   0          9dsock-shop            orders-db-659949975f-fggdb                     1/1     Running   0          9dsock-shop            payment-7bcdbf45c9-fhl8m                       1/1     Running   0          9dsock-shop            queue-master-5f6d6d4796-cs5f6                  1/1     Running   0          9dsock-shop            rabbitmq-5bcbb547d7-kfzmn                      2/2     Running   0          9dsock-shop            session-db-7cf97f8d4f-bms4c                    1/1     Running   0          9dsock-shop            shipping-7f7999ffb7-llkrw                      1/1     Running   0          9dsock-shop            user-68df64db9c-7gcg2                          1/1     Running   0          9dsock-shop            user-db-6df7444fc-7s6wp                        1/1     Running   0          9dwego-system          helm-controller-6dcbff747f-sfp97               1/1     Running   0          9dwego-system          image-automation-controller-75f784cfdc-wxwk9   1/1     Running   0          9dwego-system          image-reflector-controller-67d6bdcb59-hg2cv    1/1     Running   0          9dwego-system          kustomize-controller-5d47cf49fb-b6pmg          1/1     Running   0          9dwego-system          notification-controller-7569f7c974-824p9       1/1     Running   0          9dwego-system          source-controller-5b976b8dd6-gqrl7             1/1     Running   0          9d>

We can expose the sock shop in our browser by:

> kubectl port-forward service/front-end -n sock-shop 8080:80Forwarding from 127.0.0.1:8080 -> 8079Forwarding from [::1]:8080 -> 8079

and if we visit http://localhost:8080, we'l see:

sock shop

Pretty simple! Now, let's go back and look at that command in more detail:

gitops add app \                                                 # (1)   --url ssh://git@github.com/example/microservices-demo.git \   # (2)   --path ./deploy/kubernetes/manifests \                        # (3)   --app-config-url ssh://git@github.com/example/external.git    # (4)   --auto-merge                                                  # (5)`
  1. Add an application to a cluster under the control of Weave GitOps
  2. The application is defined in the GitHub repository at the specified URL
  3. Only the manifests at the specified path within the repository are part of the application
  4. Store the management manifests in a separate configuration repository within GitHub; the app-config-url parameter says where to store management manifests. The default location (if no app-config-url is specified) is to place them in the .weave-gitops directory within the application repository itself. An actual URL value causes them to be stored in the repository referenced by the URL
  5. Don't create a pull request for the management manifests; push them directly to the upstream repository

Using Helm Charts#

The application can also be deployed via a helm chart. Applications defined in helm charts can be deployed from either helm repositories or git repositories. In the case of the Sock Shop application, a helm chart is included in the GitHub repository. We only need to make minor changes to the command we used above to switch to a helm chart, but using a helm chart for Sock Shop requires the target namespace to exist before deploying. By default, the chart would be deployed into the wego-system namespace (since we know it exists), but we'd like to put it in the sock-shop namespace. So, before we run gitops add app, we'll run:

kubectl create namespace sock-shopnamespace/sock-shop created>

Then, we can run:

> gitops add app --url ssh://git@github.com/example/microservices-demo.git --path ./deploy/kubernetes/helm-chart --app-config-url ssh://git@github.com/example/external.git --deployment-type helm --helm-release-target-namespace sock-shop --auto-mergeAdding application:
Name: microservices-demoURL: ssh://git@github.com/example/microservices-demo.gitPath: ./deploy/kubernetes/helm-chartBranch: masterType: helm
โ—Ž Checking cluster statusโœ” GitOps installedโœš Generating application spec manifestโœš Generating GitOps automation manifestsโ–บ Adding application "microservices-demo" to cluster "kind-kind" and repositoryโ–บ Committing and pushing gitops updates for applicationโ–บ Pushing app changes to repository>

Examining this command, we see two new arguments:

gitops add app \--name microservices-demo--url ssh://git@github.com/example/microservices-demo.git \--path ./deploy/kubernetes/helm-chart \--app-config-url ssh://git@github.com/example/external.git--deployment-type helm \                   # (1)--helm-release-target-namespace sock-shop  # (2)--auto-merge
  1. Since we're pulling the chart from a git repository, we need to explicitly state that we're using a helm chart. If we were using a helm repository, we would use --chart <chart name> instead of --path <path to application> and the deployment type would be unambiguous
  2. The application will be deployed in the namespace specified by --helm-release-target-namespace

You can check the status of the application by running the gitops get app microservices-demo command.

Single Repository Usage#

As we mentioned above, it's possible to have a single repository perform hold both the application and the configuration. If you place the application manifests in the configuration repository passed to gitops install, you can leave off the separate --app-config-url parameter. In this case, we would either have had to pass the microservices-demo URL to gitops install or copy the application manifests into the external repository. Let's proceed as if we had initialized the cluster with: gitops install --app-config-url ssh://git@github.com/example/microservices-demo.git.

> gitops add app --url ssh://git@github.com/example/microservices-demo.git --path ./deploy/kubernetes/manifests --auto-mergeAdding application:
Name: microservices-demoURL: ssh://git@github.com/example/microservices-demo.gitPath: ./deploy/kubernetes/manifestsBranch: masterType: kustomize
โ—Ž Checking cluster statusโœ” GitOps installedโœš Generating application spec manifestโœš Generating GitOps automation manifestsโ–บ Adding application "microservices-demo" to cluster "kind-kind" and repositoryโ–บ Committing and pushing gitops updates for applicationโ–บ Pushing app changes to repository>

So, it's just like the example above except we didn't have to call out the location of the configuration repository. Regardless of whether or not the application manifests are stored in the configuration repository, though, the configuration itself is stored in a special directory (.weave-gitops) at the top level of the configuration repository:

> tree .weave-gitops.weave-gitopsโ”œโ”€โ”€ appsโ”‚ย ย  โ””โ”€โ”€ microservices-demoโ”‚ย ย      โ”œโ”€โ”€ app.yamlโ”‚ย ย      โ”œโ”€โ”€ kustomization.yamlโ”‚ย ย      โ”œโ”€โ”€ microservices-demo-gitops-deploy.yamlโ”‚ย ย      โ””โ”€โ”€ microservices-demo-gitops-source.yamlโ””โ”€โ”€ clusters    โ””โ”€โ”€ kind-kind        โ”œโ”€โ”€ system        โ”‚ย ย  โ”œโ”€โ”€ flux-source-resource.yaml        โ”‚ย ย  โ”œโ”€โ”€ flux-system-kustomization-resource.yaml        โ”‚ย ย  โ”œโ”€โ”€ flux-user-kustomization-resource.yaml        โ”‚ย ย  โ”œโ”€โ”€ gitops-runtime.yaml        โ”‚ย ย  โ”œโ”€โ”€ wego-app.yaml        โ”‚ย ย  โ””โ”€โ”€ wego-system.yaml        โ””โ”€โ”€ user            โ””โ”€โ”€ kustomization.yaml
6 directories, 11 files

In this case, the apps directory contains one app (microservices-demo). The app.yaml file looks like:

---apiVersion: wego.weave.works/v1alpha1kind: Applicationmetadata:  labels:    wego.weave.works/app-identifier: wego-85414ad27cd476d497d715818deda0c6  name: microservices-demo  namespace: wego-systemspec:  branch: master  config_url: ssh://git@github.com/example/external.git  deployment_type: kustomize  path: ./deploy/kubernetes/manifests  source_type: git  url: ssh://git@github.com/example/microservices-demo.git

It describes the application and includes a label derived from the URL, path, and branch to prevent multiple applications from referencing the same source within git.

The kustomization.yaml file holds a list of application components that will be deployed:

apiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomizationmetadata:  name: microservices-demo  namespace: wego-systemresources:  - app.yaml  - microservices-demo-gitops-deploy.yaml  - microservices-demo-gitops-source.yaml

The microservices-demo-gitops-source.yaml file tells flux the location (repository) containing the application. It has a special ignore section that skips .weave-gitops to support keeping an application in the configuration repository:

apiVersion: source.toolkit.fluxcd.io/v1beta1kind: GitRepositorymetadata:  name: microservices-demo  namespace: wego-systemspec:  ignore: |-    .weave-gitops/    .git/    .gitignore    .gitmodules    .gitattributes    *.jpg    *.jpeg    *.gif    *.png    *.wmv    *.flv    *.tar.gz    *.zip    .github/    .circleci/    .travis.yml    .gitlab-ci.yml    appveyor.yml    .drone.yml    cloudbuild.yaml    codeship-services.yml    codeship-steps.yml    **/.goreleaser.yml    **/.sops.yaml    **/.flux.yaml  interval: 30s  ref:    branch: master  url: https://github.com/example/microservices-demo.git

The microservices-demo-gitops-deploy.yaml file defines the path within the repository and the sync interval for the application:

---apiVersion: kustomize.toolkit.fluxcd.io/v1beta2kind: Kustomizationmetadata:  name: microservices-demo  namespace: wego-systemspec:  interval: 1m0s  path: ./deploy/kubernetes/manifests  prune: true  sourceRef:    kind: GitRepository    name: microservices-demo

(This will look different in the case of a helm chart; it will hold a HelmRelease rather than a Kustomization)

Finally, the clusters directory has a subdirectory for each cluster defining which applications will run there. The user/kustomization.yaml file in a specific cluster directory has a resources section containing a list of applications references:

resources:  - ../../../apps/microservices-demo

Using Pull Requests#

We've reached the all-singing, all-dancing case now. This is the way most people will actually use Weave GitOps in a real environment. Whether you use the default application repository model or have a separate configuration repository, you can support reviewing and auditing changes to your GitOps resources via Pull Requests. (Also, as a practical matter, many people don't allow direct merges to their repositories without pull requests anyway)

In order to use pull requests for your GitOps resources, you simply need to leave off the --auto-merge flag we've been passing so far (in other words, using pull requests is the default). For example, if we run the previous command without --auto-merge, we see different output:

> gitops add app --url ssh://git@github.com/example/microservices-demo.git --path ./deploy/kubernetes/manifestsAdding application:
Name: microservices-demoURL: ssh://git@github.com/example/microservices-demo.gitPath: ./deploy/kubernetes/manifestsBranch: masterType: kustomize
โ—Ž Checking cluster statusโœ” GitOps installedโœš Generating application spec manifestโœš Generating GitOps automation manifestsโ–บ Adding application "microservices-demo" to cluster "kind-kind" and repositoryPull Request created: https://github.com/example/external/pull/14
>

Note the line: Pull Request created: https://github.com/example/external/pull/14. If we were to go to that GitHub repository and merge the pull request, the app would then be deployed.

Hopefully, this example has given you a good understanding of how to deploy applications with Weave GitOps. Thanks for reading!