You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* renaming the local param to make it more readable
* typo and add build step
* await task
* change to nuget reference for docker build
* copy the package file to the local nuget folder
* change the build with the new namespace
* add the local nuget into source control
* add the deployment step
* forgot to push the readme
* change the csproj
* add docker file
* Update .dockerignore
* Update dotnet-azurefunction.csproj
* Update DaprExtensionTests.csproj
Copy file name to clipboardExpand all lines: samples/dotnet-azurefunction/README.md
+252-3Lines changed: 252 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -119,7 +119,7 @@ POST http://localhost:3501/v1.0/invoke/functionapp/method/CreateNewOrder
119
119
**Note**: in this sample, `DaprServiceInvocationTrigger` attribute does not specify the method name, so it defaults to use the FunctionName. Alternatively, we can use `[DaprServiceInvocationTrigger(MethodName = "newOrder")]` to specify the service invocation method name that your function should respond. In this case, then we need to use the following command:
In your terminal window, you should see logs indicating that the message was received and state was updated:
@@ -274,5 +274,254 @@ To stop your services from running, simply stop the "dapr run" process. Alternat
274
274
275
275
```bash
276
276
dapr stop --app-id functionapp
277
-
dapr stop --app-id nodeapp
278
-
```
277
+
```
278
+
279
+
# Build the Docker Container for Your Function App
280
+
281
+
Now that you're successfully having your Dapr'd function app with running locally, you probably want to deploy to kubernetes cluster. If you have update the sample code to fit your scenario, you need to create new images with your updated code. First you need to install docker on your machine. Next, follow these steps to build your custom container image for your function:
282
+
283
+
1. Update function app as you see fit!
284
+
2. There are two ways you can build the docker images. In this dotnet sample, the project file has a **project reference** for the `Dapr.AzureFunctions.Extension`, instead of a **nuget reference**.
285
+
286
+
### Approach 1: Using a Project Reference
287
+
288
+
1a. Go to the root directory of this repo, you should see a `dockerfile` under `/azure-functions-extension` folder.
289
+
290
+
2a. Continue step 3
291
+
292
+
### Approach 2: Using a Nuget Reference
293
+
294
+
1b. Navigate to `/dotnet-azurefunction` directory. You should see the default `Dockerfile` provided by Azure Functions which specify the suitable custom container for use and the selected runtime. Please check [here](https://hub.docker.com/_/microsoft-azure-functions-base) for more information on supported base image.
295
+
296
+
2b. Change the csproj file to use the nuget package. It will try to resolve the Dapr Extension package reference from the local nuget source which points to the `localnuget` folder. See the definition in `nuget.config` file.
297
+
298
+
3b. Copy the lastest `.nupkg` file from `$RepoRoot/bin/Debug/nugets` or `$RepoRoot/bin/Release/nugets` into `/dotnet-azurefunction/localNuget` folder.
299
+
300
+
3. Run docker build command and specify your image name:
301
+
```
302
+
docker build -t my-docker-id .
303
+
```
304
+
If you're planning on hosting it on docker hub, then it should be
305
+
306
+
```
307
+
docker build -t my-docker-id/mydocker-image .
308
+
```
309
+
310
+
4. Once your image has built you can see it on your machines by running `docker images`. Try run the image in a local container to test the build. Please use `-e` option to specify the app settings. Open a browser to http://localhost:8080, which should show your function app is up and running with `;-)`. You can ignore the storage connection to test this, but you might see exception thrown from your container log complaining storage is not defined.
Next step, we will show steps to get your Dapr'd function app running in a Kubernetes cluster.
322
+
323
+
## Prerequisites
324
+
Since our sample does cover multiple Dapr components, here we have a long list of requirements. Please skip any step that is not required for your own function app.
- Install [helm](https://helm.sh/docs/intro/install/) (you can skip this if your function app does not use Kafka bindings)
327
+
- A Kubernetes cluster, such as [Minikube](https://github.com/dapr/docs/blob/master/getting-started/cluster/setup-minikube.md), [AKS](https://github.com/dapr/docs/blob/master/getting-started/cluster/setup-aks.md) or [GKE](https://cloud.google.com/kubernetes-engine/)
328
+
- A [Azure Storage Account](https://docs.microsoft.com/en-us/azure/storage/common/storage-account-create?tabs=azure-portal) to host your function app
329
+
- Follow this guide to [find out the connection string](https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string#configure-a-connection-string-for-an-azure-storage-account).
330
+
- A State Store, such as [Redis Store](https://github.com/dapr/docs/blob/master/howto/configure-redis/README.md) for Dapr state store and pub/sub message delivery (you can skip this if your function does not use the aforementioned components)
331
+
332
+
## Setup Dapr on your Kubernetes Cluster
333
+
Once you have a cluster, run `dapr init --kubernetes` to deploy Dapr to it. Please follow this( guide on [how to install Dapr on your kubrtnetes](https://github.com/dapr/docs/blob/master/getting-started/environment-setup.md#installing-dapr-on-a-kubernetes-cluster) via Dapr CLI or Helm. Dapr CLI does not support non-default namespaces and only is recommended for testing purposes.
334
+
If you need a non-default namespace or in production environment, Helm has to be used.
335
+
336
+
```
337
+
⌛ Making the jump to hyperspace...
338
+
✅ Deploying the Dapr Operator to your cluster...
339
+
✅ Success! Dapr has been installed. To verify, run 'kubectl get pods -w' in your terminal
340
+
```
341
+
## Deploy your Dapr Building Blocks
342
+
#### [Optional] Configure the State Store
343
+
- Replace the hostname and password in `deploy/redis.yaml`. https://github.com/dapr/samples/tree/master/2.hello-kubernetes#step-2---create-and-configure-a-state-store
344
+
- Run `kubectl apply -f ./deploy/redis.yaml` and observe that your state store was successfully configured!
345
+
```
346
+
component.dapr.io/statestore configured
347
+
```
348
+
- Follow [secret management](https://github.com/dapr/docs/tree/master/concepts/secrets) instructions to securely manage your secrets in a production-grade application.
349
+
- More detail can be found in Dapr sample repo [2.hello-kubernetes](https://github.com/dapr/samples/tree/master/2.hello-kubernetes#step-2---create-and-configure-a-state-store)
- Run `kubectl -n kafka get pods -w` to see Kafka pods are running. This might take a few minute, but you should see.
361
+
```
362
+
NAME READY STATUS RESTARTS AGE
363
+
dapr-kafka-0 1/1 Running 0 2m7s
364
+
dapr-kafka-zookeeper-0 1/1 Running 0 2m57s
365
+
dapr-kafka-zookeeper-1 1/1 Running 0 2m13s
366
+
dapr-kafka-zookeeper-2 1/1 Running 0 109s
367
+
```
368
+
- Run `kubectl apply -f .\deploy\kafka.yaml` and observe that your kafka was successfully configured!
369
+
```
370
+
component.dapr.io/sample-topic created
371
+
```
372
+
- Follow [secret management](https://github.com/dapr/docs/tree/master/concepts/secrets) instructions to securely manage your secrets in a production-grade application.
373
+
374
+
#### [Optional] Setting up the Pub/Sub in Kubernetes
375
+
- In this demo, we use Redis Stream (Redis Version 5 and above) to enable pub/sub. Replace the hostname and password in `deploy/redis-pubsub.yaml`. https://github.com/dapr/samples/tree/master/2.hello-kubernetes#step-2---create-and-configure-a-state-store
376
+
- Run `kubectl apply -f .\deploy\redis.yaml` and observe that your state store was successfully configured!
377
+
```
378
+
component.dapr.io/messagebus configured
379
+
```
380
+
- See Dapr sample repo [4.pub-sub](https://github.com/dapr/samples/tree/master/4.pub-sub) for more instructions.
381
+
382
+
Now you should have all Dapr components up and running in your kubernetes cluster. Next we will show how to deploy your function app into your kubernetes cluster with the Dapr Side Car.
383
+
384
+
## Deploy your Dapr'd Function App
385
+
You can find your function app deployment file `deploy/function.yaml`. Let's take a look:
- Put your app settings into `data` block. Please note the value has to be Base64 encoded. For example, the `StateStoreName` value is configured to be `statestore` in `deploy/redis.yaml`, string `statestore` get encoded into `c3RhdGVzdG9yZQ==`.
399
+
- The connection string you retrieved should be formatted as `DefaultEndpointsProtocol=https;AccountName=storagesample;AccountKey=<account-key>`, which would be encoded into `RGVmYXVsdEVuZHBvaW50c1Byb3RvY29sPWh0dHBzO0FjY291bnROYW1lPXN0b3JhZ2VzYW1wbGU7QWNjb3VudEtleT08YWNjb3VudC1rZXk+`
400
+
401
+
In the second part of the deployment file, you need to put your image name and specify your app port where your Dapr Trigger will listen on.
402
+
403
+
```yaml
404
+
apiVersion: apps/v1
405
+
kind: Deployment
406
+
metadata:
407
+
name: functionapp
408
+
labels:
409
+
app: functionapp
410
+
spec:
411
+
replicas: 1
412
+
selector:
413
+
matchLabels:
414
+
app: functionapp
415
+
template:
416
+
metadata:
417
+
labels:
418
+
app: functionapp
419
+
annotations:
420
+
dapr.io/enabled: "true"
421
+
dapr.io/id: "functionapp"
422
+
dapr.io/port: "<app-port>"
423
+
spec:
424
+
containers:
425
+
- name: functionapp
426
+
image: <your-docker-hub-id>/<your-image-name>
427
+
ports:
428
+
- containerPort: <app-port>
429
+
imagePullPolicy: Always
430
+
envFrom:
431
+
- secretRef:
432
+
name: functionapp
433
+
```
434
+
435
+
Now run the following command to deploy the function app into your kubernetes cluster.
436
+
437
+
```powershell
438
+
$ kubectl apply -f ./deploy/functionapp.yaml
439
+
440
+
secret/functionapp created
441
+
deployment.apps/functionapp created
442
+
```
443
+
444
+
Run `kubectl get pods` to see your function app is up and running.
0 commit comments