{"id":19100093,"url":"https://github.com/Masahigo/video-indexer","last_synced_at":"2025-04-18T17:32:41.919Z","repository":{"id":40871217,"uuid":"269105040","full_name":"Masahigo/video-indexer","owner":"Masahigo","description":"Building an event driven .NET Core app with Dapr","archived":false,"fork":false,"pushed_at":"2022-12-08T10:36:44.000Z","size":24,"stargazers_count":16,"open_issues_count":3,"forks_count":5,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-03-10T00:01:19.392Z","etag":null,"topics":["dapr","docker","dotnetcore3-1","kubernetes","microsoft-video-indexer-api","vscode","webapi-core"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Masahigo.png","metadata":{"files":{"readme":"README.MD","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-03T14:07:51.000Z","updated_at":"2023-02-07T15:53:02.000Z","dependencies_parsed_at":"2023-01-25T07:15:31.018Z","dependency_job_id":null,"html_url":"https://github.com/Masahigo/video-indexer","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Masahigo%2Fvideo-indexer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Masahigo%2Fvideo-indexer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Masahigo%2Fvideo-indexer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Masahigo%2Fvideo-indexer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Masahigo","download_url":"https://codeload.github.com/Masahigo/video-indexer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223783091,"owners_count":17201903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dapr","docker","dotnetcore3-1","kubernetes","microsoft-video-indexer-api","vscode","webapi-core"],"created_at":"2024-11-09T03:52:29.444Z","updated_at":"2024-11-09T03:53:02.009Z","avatar_url":"https://github.com/Masahigo.png","language":"C#","funding_links":[],"categories":["kubernetes","docker"],"sub_categories":[],"readme":"# Video indexer application using Dapr\n\n## Running locally in Standalone mode (Windows file system) \n\nRefer to [Dapr's documentation](https://github.com/dapr/docs/blob/master/getting-started/environment-setup.md) for more details.\n\n- Open PowerShell as Administrator and run: \n\n```powershell\n    powershell -Command \"iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex\"\n```\n\n- Open Command Prompt as Administrator and run:\n\n```cmd\n    dapr init\n```\n\n- Check Dapr runtime containers:\n\n```cmd\n    docker ps\n\n    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES\n    523eed39c32d        daprio/dapr         \"./placement\"            8 hours ago         Up 29 minutes       0.0.0.0:6050-\u003e50005/tcp   dapr_placement\n    7f9c30b58968        redis               \"docker-entrypoint.s…\"   8 hours ago         Up 29 minutes       0.0.0.0:6379-\u003e6379/tcp    dapr_redis\n```\n\n- [Get Ngrok](https://ngrok.com/download)\n\n- Run Ngrok with following command\n\n```\n    ngrok http -host-header=localhost 9000\n```\n\n- Configure your event grid binding (eg. `/components/eventgrid.yaml`) with [required metadata](https://github.com/dapr/docs/blob/master/reference/specs/bindings/eventgrid.md), using the HTTPS endpoint from _ngrok_ for `subscriberEndpoint`\n\n```yaml\n..\nspec\n  - name: subscriberEndpoint\n    value: \"https://xxx.ngrok.io/api/events\"    \n  - name: handshakePort\n    value: 9000\n  ..\n```\n\n- Configure your cosmosdb binding (eg. `/components/cosmosdb.yaml`) with [required metadata](https://github.com/dapr/docs/blob/master/reference/specs/bindings/cosmosdb.md)\n\n- [Start application with Dapr](https://github.com/dapr/docs/blob/master/walkthroughs/darprun.md)\n\n```\n    dapr run --app-id video-indexer --app-port 5000 --port 3500 dotnet run\n```\n\n## Steps to deploy to Kubernetes\n\n1) Create Kubernetes cluster and get admin credentials\n\n2) Install Helm 3 from script: https://helm.sh/docs/intro/install/\n\n```bash\ncurl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | sudo bash\n```\n\n3) Install Dapr using Helm3: https://github.com/dapr/docs/blob/master/getting-started/environment-setup.md#using-helm-advanced\n\n```bash\nhelm repo add dapr https://daprio.azurecr.io/helm/v1/repo\nhelm repo update\n\nkubectl create namespace dapr-system\nhelm install dapr dapr/dapr --namespace dapr-system\nkubectl get pods -n dapr-system -w\n```\n\n4) Install Redis\n\n```bash\nhelm repo add bitnami https://charts.bitnami.com/bitnami\nhelm install redis bitnami/redis --set \"usePassword=false\"\n```\n\n5) Install Nginx with Dapr annotations to default namespace\n\n```bash\nhelm repo add stable https://kubernetes-charts.storage.googleapis.com/\nhelm install nginx stable/nginx-ingress -f ./deploy/dapr-annotations.yaml -n default\n\n# Get public IP from ingress controller\nkubectl get svc -l component=controller -o jsonpath='Public IP is: {.items[0].status.loadBalancer.ingress[0].ip}{\"\\n\"}'\n```\n\n6) Configure DNS A record pointing to the public IP\n\n7) Install Cert manager to default namespace\n\n```bash\n# Install the CustomResourceDefinition resources separately\nkubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.13/deploy/manifests/00-crds.yaml\n\n# Label the ingress-basic namespace to disable resource validation\nkubectl label namespace default cert-manager.io/disable-validation=true\n\n# Add the Jetstack Helm repository\nhelm repo add jetstack https://charts.jetstack.io\n\n# Update your local Helm chart repository cache\nhelm repo update\n\n# Install the cert-manager Helm chart\nhelm install \\\n  cert-manager \\\n  --namespace default \\\n  --version v0.13.0 \\\n  jetstack/cert-manager\n```\n\n8) Create a CA cluster issuer: https://docs.microsoft.com/en-us/azure/aks/ingress-tls#create-a-ca-cluster-issuer \n\n9) Add Azure Key cert file to k8s secret for enabling secrets in Dapr bindings: https://github.com/dapr/docs/blob/master/howto/setup-secret-store/azure-keyvault.md#use-azure-key-vault-secret-store-in-kubernetes-mode\n\n```bash\nkubectl create secret generic azure-keyvault-cert --from-file=VideoIndexerCert.pfx\n```\n\n10) Deploy akv2k8s for k8s app's secrets: https://akv2k8s.io/installation/installing-with-helm/#installing-with-helm-on-azure-aks\n\n```bash\nkubectl create ns akv2k8s\nhelm repo add spv-charts http://charts.spvapi.no\nhelm repo update\n\nhelm install azure-key-vault-controller \\\n  spv-charts/azure-key-vault-controller \\\n  --namespace akv2k8s\n\nhelm install azure-key-vault-env-injector \\\n  spv-charts/azure-key-vault-env-injector \\\n  --set installCrd=false \\\n  --namespace akv2k8s\n\nkubectl apply -f ./deploy/azurekeyvaultsecrets.yaml\n\n$ kubectl get akvs\n\nNAME                           VAULT                 VAULT OBJECT              SECRET NAME   SYNCHED\nsecret-client-id               video-indexer-we-kv   clientId\nsecret-client-secret           video-indexer-we-kv   clientSecret\nsecret-storage-account-name    video-indexer-we-kv   azureStorageAccountName\nsecret-tenant-id               video-indexer-we-kv   tenantId\nsecret-video-indexer-api-key   video-indexer-we-kv   videoIndexerApiKey\n\n# Remember to authorize get permission for k8s cluster's spn: https://akv2k8s.io/tutorials/prerequisites/#add-secret---required-for-secret-tutorials\n# Otherwise akv2k8s fails to initialize along with your app's pod\n\n```\n\n10) Deploy Dapr components\n\n```bash\n$ kubectl apply -f ./deploy/azurekeyvault.yaml\n$ kubectl apply -f ./deploy/redis.yaml\n$ kubectl apply -f ./deploy/eventgrid_binding.yaml\n$ kubectl apply -f ./deploy/cosmosdb_binding.yaml\n```\n\n11) Deploy app and ingress + verify that the app works\n\n```bash\n$ kubectl apply -f ./deploy/dotnetwebapi.yaml\n$ kubectl get pods -l app=dotnetwebapi\nNAME                                                   READY   STATUS            RESTARTS   AGE\nvideo-indexer-6cb78f555c-j8vpv                         0/2     PodInitializing   0          4s\n\n$ kubectl logs video-indexer-6cb78f555c-j8vpv webapi\ntime=\"2020-06-10T06:32:34Z\" level=info msg=\"found original container command to be /usr/bin/dotnet [dotnet VideoIndexerApi.dll]\" application=env-injector component=akv2k8s custom_auth=false namespace=default\ntime=\"2020-06-10T06:32:34Z\" level=info msg=\"secret clientId injected into evn var AZURE_CLIENT_ID for executable /usr/bin/dotnet\" application=env-injector component=akv2k8s custom_auth=false namespace=default\ntime=\"2020-06-10T06:32:35Z\" level=info msg=\"secret clientSecret injected into evn var AZURE_CLIENT_SECRET for executable /usr/bin/dotnet\" application=env-injector component=akv2k8s custom_auth=false namespace=default\ntime=\"2020-06-10T06:32:35Z\" level=info msg=\"secret videoIndexerApiKey injected into evn var VIDEO_INDEXER_API_KEY for executable /usr/bin/dotnet\" application=env-injector component=akv2k8s custom_auth=false namespace=default\ntime=\"2020-06-10T06:32:35Z\" level=info msg=\"secret azureStorageAccountName injected into evn var AZURE_STORAGE_ACCOUNT_NAME for executable /usr/bin/dotnet\" application=env-injector component=akv2k8s custom_auth=false namespace=default\ntime=\"2020-06-10T06:32:35Z\" level=info msg=\"secret tenantId injected into evn var AZURE_TENANT_ID for executable /usr/bin/dotnet\" application=env-injector component=akv2k8s custom_auth=false namespace=default\ntime=\"2020-06-10T06:32:35Z\" level=info msg=\"starting process /usr/bin/dotnet [dotnet VideoIndexerApi.dll] with secrets in env vars\" application=env-injector component=akv2k8s custom_auth=false namespace=default\ninfo: VideoIndexerApi.Services.QueuedHostedService[0]\n      Queued Hosted Service is running.\n\n      Tap W to add a work item to the background queue.\n\ninfo: Microsoft.Hosting.Lifetime[0]\n      Now listening on: http://0.0.0.0:5000\ninfo: Microsoft.Hosting.Lifetime[0]\n      Application started. Press Ctrl+C to shut down.\ninfo: Microsoft.Hosting.Lifetime[0]\n      Hosting environment: Production\ninfo: Microsoft.Hosting.Lifetime[0]\n      Content root path: /app\ninfo: VideoIndexerApi.HealthChecks.LivenessHealthCheck[0]\n      LivenessHealthCheck executed.\ninfo: VideoIndexerApi.HealthChecks.ReadinessHealthCheck[0]\n      Readiness health check executed.\ninfo: VideoIndexerApi.HealthChecks.ReadinessHealthCheck[0]\n      Connection to video indexer API is working.\n\n```\n\n12) Check Nginx controller logs and restart pod if needed (https://kubernetes.github.io/ingress-nginx/troubleshooting/)\n\n```bash\n$ kubectl get pods -l app=nginx-ingress\n\nNAME                                                   READY   STATUS    RESTARTS   AGE\nnginx-nginx-ingress-controller-649df94867-fp6mg        2/2     Running   0          51m\nnginx-nginx-ingress-default-backend-6d96c457f6-4nbj5   1/1     Running   0          55m\n\n$ kubectl logs nginx-nginx-ingress-controller-649df94867-fp6mg nginx-ingress-controller\n\n# If you see 503s logged from calls to webhook endpoint '/api/events' restart the pod\n# ..\"OPTIONS /api/events HTTP/1.1\" 503..\n\nkubectl delete pod nginx-nginx-ingress-controller-649df94867-fp6mg\n```\n\n12) Observe your Event Subscription being created to Storage account\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMasahigo%2Fvideo-indexer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMasahigo%2Fvideo-indexer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMasahigo%2Fvideo-indexer/lists"}