├── .github
├── CODE_OF_CONDUCT.md
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── with-dapr-build.yaml
│ └── with-fqdn-build.yaml
├── .gitignore
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── with-dapr
├── README.md
├── container-1-node
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── app.js
│ ├── bin
│ │ └── www
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ │ └── stylesheets
│ │ │ └── style.css
│ ├── routes
│ │ ├── hello.js
│ │ └── index.js
│ └── views
│ │ ├── error.jade
│ │ ├── index.jade
│ │ └── layout.jade
├── container-2-dotnet
│ ├── Dockerfile
│ ├── Program.cs
│ ├── Properties
│ │ └── launchSettings.json
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── container-2-dotnet.csproj
└── deploy
│ ├── container-app.bicep
│ ├── environment.bicep
│ └── main.bicep
└── with-fqdn
├── README.md
├── container-1-node
├── .dockerignore
├── Dockerfile
├── app.js
├── bin
│ └── www
├── package-lock.json
├── package.json
├── public
│ └── stylesheets
│ │ └── style.css
├── routes
│ ├── hello.js
│ └── index.js
└── views
│ ├── error.jade
│ ├── index.jade
│ └── layout.jade
├── container-2-dotnet
├── Dockerfile
├── Program.cs
├── Properties
│ └── launchSettings.json
├── appsettings.Development.json
├── appsettings.json
└── container-2-dotnet.csproj
└── deploy
├── container-app.bicep
├── environment.bicep
└── main.bicep
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Microsoft Open Source Code of Conduct
2 |
3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
4 |
5 | Resources:
6 |
7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/)
8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/)
9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns
10 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
4 | > Please provide us with the following information:
5 | > ---------------------------------------------------------------
6 |
7 | ### This issue is for a: (mark with an `x`)
8 | ```
9 | - [ ] bug report -> please search issues before submitting
10 | - [ ] feature request
11 | - [ ] documentation issue or request
12 | - [ ] regression (a behavior that used to work and stopped in a new release)
13 | ```
14 |
15 | ### Minimal steps to reproduce
16 | >
17 |
18 | ### Any log messages given by the failure
19 | >
20 |
21 | ### Expected/desired behavior
22 | >
23 |
24 | ### OS and Version?
25 | > Windows 7, 8 or 10. Linux (which distribution). macOS (Yosemite? El Capitan? Sierra?)
26 |
27 | ### Versions
28 | >
29 |
30 | ### Mention any other details that might be useful
31 |
32 | > ---------------------------------------------------------------
33 | > Thanks! We'll be in touch soon.
34 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Purpose
2 |
3 | * ...
4 |
5 | ## Does this introduce a breaking change?
6 |
7 | ```
8 | [ ] Yes
9 | [ ] No
10 | ```
11 |
12 | ## Pull Request Type
13 | What kind of change does this Pull Request introduce?
14 |
15 |
16 | ```
17 | [ ] Bugfix
18 | [ ] Feature
19 | [ ] Code style update (formatting, local variables)
20 | [ ] Refactoring (no functional changes, no api changes)
21 | [ ] Documentation content changes
22 | [ ] Other... Please describe:
23 | ```
24 |
25 | ## How to Test
26 | * Get the code
27 |
28 | ```
29 | git clone [repo-address]
30 | cd [repo-name]
31 | git checkout [branch-name]
32 | npm install
33 | ```
34 |
35 | * Test the code
36 |
37 | ```
38 | ```
39 |
40 | ## What to Check
41 | Verify that the following are valid
42 | * ...
43 |
44 | ## Other Information
45 |
--------------------------------------------------------------------------------
/.github/workflows/with-dapr-build.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=./with-fqdn-build.yaml
2 | name: With Dapr Build and Deploy
3 | on:
4 | workflow_run:
5 | workflows: ["With FQDN Build and Deploy"]
6 | types:
7 | - completed
8 |
9 | env:
10 | REGISTRY: ghcr.io
11 | IMAGE_NAME: ${{ github.repository }}
12 |
13 | jobs:
14 | build:
15 | runs-on: ubuntu-latest
16 | strategy:
17 | matrix:
18 | services: [ {'imageName': 'node-dapr', 'directory': './with-dapr/container-1-node'}, {'imageName': 'dotnet-dapr', 'directory': './with-dapr/container-2-dotnet'}]
19 | permissions:
20 | contents: read
21 | packages: write
22 | outputs:
23 | containerImage-node: ${{ steps.image-tag.outputs.image-node-dapr }}
24 | containerImage-dotnet: ${{ steps.image-tag.outputs.image-dotnet-dapr }}
25 | steps:
26 | - name: Checkout repository
27 | uses: actions/checkout@v2
28 |
29 | # Login against a Docker registry except on PR
30 | # https://github.com/docker/login-action
31 | - name: Log into registry ${{ env.REGISTRY }}
32 | if: github.event_name != 'pull_request'
33 | uses: docker/login-action@v1
34 | with:
35 | registry: ${{ env.REGISTRY }}
36 | username: ${{ github.actor }}
37 | password: ${{ secrets.GITHUB_TOKEN }}
38 |
39 | # Extract metadata (tags, labels) for Docker
40 | # https://github.com/docker/metadata-action
41 | - name: Extract Docker metadata
42 | id: meta
43 | uses: docker/metadata-action@v3
44 | with:
45 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.services.imageName }}
46 | tags: |
47 | type=semver,pattern={{version}}
48 | type=semver,pattern={{major}}.{{minor}}
49 | type=semver,pattern={{major}}
50 | type=ref,event=branch
51 | type=sha
52 |
53 | # Build and push Docker image with Buildx (don't push on PR)
54 | # https://github.com/docker/build-push-action
55 | - name: Build and push Docker image
56 | uses: docker/build-push-action@v2
57 | with:
58 | context: ${{ matrix.services.directory }}
59 | push: ${{ github.event_name != 'pull_request' }}
60 | tags: ${{ steps.meta.outputs.tags }}
61 | labels: ${{ steps.meta.outputs.labels }}
62 |
63 | - name: Output image tag
64 | id: image-tag
65 | run: echo "::set-output name=image-${{ matrix.services.imageName }}::${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.services.imageName }}:sha-$(git rev-parse --short HEAD)" | tr '[:upper:]' '[:lower:]'
66 |
67 | deploy:
68 | runs-on: ubuntu-latest
69 | needs: [build]
70 | steps:
71 | - name: Checkout repository
72 | uses: actions/checkout@v2
73 |
74 | - name: Azure Login
75 | uses: azure/login@v1
76 | with:
77 | creds: ${{ secrets.AZURE_CREDENTIALS }}
78 |
79 | - name: Deploy bicep
80 | uses: azure/CLI@v1
81 | with:
82 | inlineScript: |
83 | az group create -g ${{ secrets.RESOURCE_GROUP }} -l canadacentral
84 | az deployment group create -g ${{ secrets.RESOURCE_GROUP }} -f ./with-dapr/deploy/main.bicep \
85 | -p \
86 | nodeImage='${{ needs.build.outputs.containerImage-node }}' \
87 | nodePort=3000 \
88 | dotnetImage='${{ needs.build.outputs.containerImage-dotnet }}' \
89 | dotnetPort=80 \
90 | registry=${{ env.REGISTRY }} \
91 | registryUsername=${{ github.actor }} \
92 | registryPassword=${{ secrets.PACKAGES_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/with-fqdn-build.yaml:
--------------------------------------------------------------------------------
1 | # yaml-language-server: $schema=./with-fqdn-build.yaml
2 | name: With FQDN Build and Deploy
3 | on:
4 | push:
5 | branches: [ main ]
6 | # Publish semver tags as releases.
7 | tags: [ 'v*.*.*' ]
8 | workflow_dispatch:
9 |
10 | env:
11 | REGISTRY: ghcr.io
12 | IMAGE_NAME: ${{ github.repository }}
13 |
14 | jobs:
15 | build:
16 | runs-on: ubuntu-latest
17 | strategy:
18 | matrix:
19 | services: [ {'imageName': 'node', 'directory': './with-fqdn/container-1-node'}, {'imageName': 'dotnet', 'directory': './with-fqdn/container-2-dotnet'}]
20 | permissions:
21 | contents: read
22 | packages: write
23 | outputs:
24 | containerImage-node: ${{ steps.image-tag.outputs.image-node }}
25 | containerImage-dotnet: ${{ steps.image-tag.outputs.image-dotnet }}
26 | steps:
27 | - name: Checkout repository
28 | uses: actions/checkout@v2
29 |
30 | # Login against a Docker registry except on PR
31 | # https://github.com/docker/login-action
32 | - name: Log into registry ${{ env.REGISTRY }}
33 | if: github.event_name != 'pull_request'
34 | uses: docker/login-action@v1
35 | with:
36 | registry: ${{ env.REGISTRY }}
37 | username: ${{ github.actor }}
38 | password: ${{ secrets.GITHUB_TOKEN }}
39 |
40 | # Extract metadata (tags, labels) for Docker
41 | # https://github.com/docker/metadata-action
42 | - name: Extract Docker metadata
43 | id: meta
44 | uses: docker/metadata-action@v3
45 | with:
46 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.services.imageName }}
47 | tags: |
48 | type=semver,pattern={{version}}
49 | type=semver,pattern={{major}}.{{minor}}
50 | type=semver,pattern={{major}}
51 | type=ref,event=branch
52 | type=sha
53 |
54 | # Build and push Docker image with Buildx (don't push on PR)
55 | # https://github.com/docker/build-push-action
56 | - name: Build and push Docker image
57 | uses: docker/build-push-action@v2
58 | with:
59 | context: ${{ matrix.services.directory }}
60 | push: ${{ github.event_name != 'pull_request' }}
61 | tags: ${{ steps.meta.outputs.tags }}
62 | labels: ${{ steps.meta.outputs.labels }}
63 |
64 | - name: Output image tag
65 | id: image-tag
66 | run: echo "::set-output name=image-${{ matrix.services.imageName }}::${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.services.imageName }}:sha-$(git rev-parse --short HEAD)" | tr '[:upper:]' '[:lower:]'
67 |
68 | deploy:
69 | runs-on: ubuntu-latest
70 | needs: [build]
71 | steps:
72 | - name: Checkout repository
73 | uses: actions/checkout@v2
74 |
75 | - name: Azure Login
76 | uses: azure/login@v1
77 | with:
78 | creds: ${{ secrets.AZURE_CREDENTIALS }}
79 |
80 | - name: Deploy bicep
81 | uses: azure/CLI@v1
82 | with:
83 | inlineScript: |
84 | az group create -g ${{ secrets.RESOURCE_GROUP }} -l canadacentral
85 | az deployment group create -g ${{ secrets.RESOURCE_GROUP }} -f ./with-fqdn/deploy/main.bicep \
86 | -p \
87 | nodeImage='${{ needs.build.outputs.containerImage-node }}' \
88 | nodePort=3000 \
89 | dotnetImage='${{ needs.build.outputs.containerImage-dotnet }}' \
90 | dotnetPort=80 \
91 | registry=${{ env.REGISTRY }} \
92 | registryUsername=${{ github.actor }} \
93 | registryPassword=${{ secrets.PACKAGES_TOKEN }}
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | **/container-2-dotnet/bin
3 | **/container-2-dotnet/obj
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [project-title] Changelog
2 |
3 |
4 | # x.y.z (yyyy-mm-dd)
5 |
6 | *Features*
7 | * ...
8 |
9 | *Bug Fixes*
10 | * ...
11 |
12 | *Breaking Changes*
13 | * ...
14 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to [project-title]
2 |
3 | This project welcomes contributions and suggestions. Most contributions require you to agree to a
4 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
5 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
6 |
7 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide
8 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
9 | provided by the bot. You will only need to do this once across all repos using our CLA.
10 |
11 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
12 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
13 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
14 |
15 | - [Code of Conduct](#coc)
16 | - [Issues and Bugs](#issue)
17 | - [Feature Requests](#feature)
18 | - [Submission Guidelines](#submit)
19 |
20 | ## Code of Conduct
21 | Help us keep this project open and inclusive. Please read and follow our [Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
22 |
23 | ## Found an Issue?
24 | If you find a bug in the source code or a mistake in the documentation, you can help us by
25 | [submitting an issue](#submit-issue) to the GitHub Repository. Even better, you can
26 | [submit a Pull Request](#submit-pr) with a fix.
27 |
28 | ## Want a Feature?
29 | You can *request* a new feature by [submitting an issue](#submit-issue) to the GitHub
30 | Repository. If you would like to *implement* a new feature, please submit an issue with
31 | a proposal for your work first, to be sure that we can use it.
32 |
33 | * **Small Features** can be crafted and directly [submitted as a Pull Request](#submit-pr).
34 |
35 | ## Submission Guidelines
36 |
37 | ### Submitting an Issue
38 | Before you submit an issue, search the archive, maybe your question was already answered.
39 |
40 | If your issue appears to be a bug, and hasn't been reported, open a new issue.
41 | Help us to maximize the effort we can spend fixing issues and adding new
42 | features, by not reporting duplicate issues. Providing the following information will increase the
43 | chances of your issue being dealt with quickly:
44 |
45 | * **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
46 | * **Version** - what version is affected (e.g. 0.1.2)
47 | * **Motivation for or Use Case** - explain what are you trying to do and why the current behavior is a bug for you
48 | * **Browsers and Operating System** - is this a problem with all browsers?
49 | * **Reproduce the Error** - provide a live example or a unambiguous set of steps
50 | * **Related Issues** - has a similar issue been reported before?
51 | * **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be
52 | causing the problem (line of code or commit)
53 |
54 | You can file new issues by providing the above information at the corresponding repository's issues link: https://github.com/[organization-name]/[repository-name]/issues/new].
55 |
56 | ### Submitting a Pull Request (PR)
57 | Before you submit your Pull Request (PR) consider the following guidelines:
58 |
59 | * Search the repository (https://github.com/[organization-name]/[repository-name]/pulls) for an open or closed PR
60 | that relates to your submission. You don't want to duplicate effort.
61 |
62 | * Make your changes in a new git fork:
63 |
64 | * Commit your changes using a descriptive commit message
65 | * Push your fork to GitHub:
66 | * In GitHub, create a pull request
67 | * If we suggest changes then:
68 | * Make the required updates.
69 | * Rebase your fork and force push to your GitHub repository (this will update your Pull Request):
70 |
71 | ```shell
72 | git rebase master -i
73 | git push -f
74 | ```
75 |
76 | That's it! Thank you for your contribution!
77 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) Microsoft Corporation.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Azure Container Apps Sample - multi-container communication
2 |
3 | The following sample shows how to use Azure Container Apps to have one container call another within the environment. This is possible both with or without [Dapr](https://dapr.io). Dapr will provide mTLS, auto-retries, and additional telemetry if enabled.
4 |
5 | The `nodeApp` (container-1-node) is an express.js API that will call a `/hello` endpoint. This route will call the `dotnetApp` (container-2-dotnet) to return a message.
6 |
7 | To view the version of this solution that does not utilize Dapr, see the [`with-fqdn`](./with-fqdn) folder. To view the version of this solution that does utilize Dapr, see the [`with-dapr`](./with-dapr) folder.
8 | ## Deploy and Run
9 |
10 | ### Deploy via GitHub Actions (recommended)
11 | The GitHub Actions will deploy an environment that includes both the with-fqdn and with-dapr versions of the solution.
12 |
13 | 1. Fork the sample repo
14 | 2. Create the following required [encrypted secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-an-environment) for the sample
15 |
16 | | Name | Value |
17 | | ---- | ----- |
18 | | AZURE_CREDENTIALS | The JSON credentials for an Azure subscription. [Learn more](https://docs.microsoft.com/azure/developer/github/connect-from-azure?tabs=azure-portal%2Cwindows#create-a-service-principal-and-add-it-as-a-github-secret) |
19 | | RESOURCE_GROUP | The name of the resource group to create |
20 | | PACKAGES_TOKEN | A GitHub personal access token with the `packages:read` scope. [Learn more](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) |
21 |
22 | ### Deploy via Azure CLI
23 | See the README.md files within each folder for scripts to deploy the sample using the Azure CLI.
--------------------------------------------------------------------------------
/with-dapr/README.md:
--------------------------------------------------------------------------------
1 | # Calling with Dapr
2 |
3 | Calling with Dapr will leverage the Dapr sidecar to securely call the other service (dotnet-app). Dapr provides mTLS, automatic retries, and distributed tracing.
4 |
5 | ```js
6 | const dotnetAppId = process.env.DOTNET_APP_ID;
7 | const daprPort = process.env.DAPR_HTTP_PORT || 3500;
8 | // ...
9 | var data = await axios.get(`http://localhost:${daprPort}/hello`, {
10 | headers: {'dapr-app-id': `${dotnetAppId}`} //sets app name for service discovery
11 | });
12 | res.send(`${JSON.stringify(data.data)}`);
13 | ```
14 |
15 | ## Local debug
16 |
17 | #### Terminal 1
18 | ```bash
19 | export DOTNET_APP_ID=dotnet-app-dapr
20 | cd ./with-dapr/container-1-node
21 | npm install
22 | dapr run -a node-app-dapr -p 3000 -- npm run start
23 | ```
24 |
25 | #### Terminal 2
26 | ```bash
27 | cd ./with-dapr/container-2-dotnet
28 | dotnet build
29 | dapr run -a dotnet-app-dapr -p 5230 -- dotnet run
30 | ```
31 |
32 | Browse to http://localhost:3000
33 |
34 | ## Deploy with CLI
35 |
36 | ```bash
37 | # Login to the CLI
38 | az login
39 | az extension add \
40 | --source https://workerappscliextension.blob.core.windows.net/azure-cli-extension/containerapp-0.2.0-py2.py3-none-any.whl
41 | az provider register --namespace Microsoft.Web
42 |
43 | # Create a resource group
44 | az group create \
45 | --name 'sample-rg' \
46 | --location canadacentral
47 |
48 | az monitor log-analytics workspace create \
49 | --resource-group 'sample-rg' \
50 | --workspace-name 'logs-for-sample'
51 |
52 | LOG_ANALYTICS_WORKSPACE_CLIENT_ID=`az monitor log-analytics workspace show --query customerId -g 'sample-rg' -n 'logs-for-sample' --out tsv`
53 | LOG_ANALYTICS_WORKSPACE_CLIENT_SECRET=`az monitor log-analytics workspace get-shared-keys --query primarySharedKey -g 'sample-rg' -n 'logs-for-sample' --out tsv`
54 |
55 | # Create a container app environment
56 | az containerapp env create \
57 | --name 'sample-env'\
58 | --resource-group 'sample-rg' \
59 | --logs-workspace-id $LOG_ANALYTICS_WORKSPACE_CLIENT_ID \
60 | --logs-workspace-key $LOG_ANALYTICS_WORKSPACE_CLIENT_SECRET \
61 | --location canadacentral
62 |
63 | # Deploy the container-2-dotnet dotnet-app
64 | az containerapp create \
65 | --name dotnet-app-dapr \
66 | --resource-group 'sample-rg' \
67 | --environment 'sample-env' \
68 | --image 'ghcr.io/azure-samples/container-apps-connect-multiple-apps/dotnet-dapr:main' \
69 | --target-port 80 \
70 | --dapr-app-id dotnet-app-dapr \
71 | --enable-dapr true \
72 | --ingress 'internal'
73 |
74 | # Deploy the container-1-node node-app
75 | az containerapp create \
76 | --name node-app-dapr \
77 | --resource-group 'sample-rg' \
78 | --environment 'sample-env' \
79 | --image 'ghcr.io/azure-samples/container-apps-connect-multiple-apps/node-dapr:main' \
80 | --target-port 3000 \
81 | --ingress 'external' \
82 | --environment-variables DOTNET_APP_ID=dotnet-app-dapr \
83 | --dapr-app-id node-app-dapr \
84 | --enable-dapr true \
85 | --query configuration.ingress.fqdn
86 |
87 | ```
88 |
89 |
--------------------------------------------------------------------------------
/with-dapr/container-1-node/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules/
--------------------------------------------------------------------------------
/with-dapr/container-1-node/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16-alpine
2 | WORKDIR /usr/src/app
3 | COPY package*.json ./
4 | RUN npm install
5 | COPY . .
6 | EXPOSE 3000
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/with-dapr/container-1-node/app.js:
--------------------------------------------------------------------------------
1 | var createError = require('http-errors');
2 | var express = require('express');
3 | var path = require('path');
4 | var cookieParser = require('cookie-parser');
5 | var logger = require('morgan');
6 |
7 | var indexRouter = require('./routes/index');
8 | var helloRouter = require('./routes/hello');
9 |
10 | var app = express();
11 |
12 | // view engine setup
13 | app.set('views', path.join(__dirname, 'views'));
14 | app.set('view engine', 'jade');
15 |
16 | app.use(logger('dev'));
17 | app.use(express.json());
18 | app.use(express.urlencoded({ extended: false }));
19 | app.use(cookieParser());
20 | app.use(express.static(path.join(__dirname, 'public')));
21 |
22 | app.use('/', indexRouter);
23 | app.use('/hello', helloRouter);
24 |
25 | // catch 404 and forward to error handler
26 | app.use(function(req, res, next) {
27 | next(createError(404));
28 | });
29 |
30 | // error handler
31 | app.use(function(err, req, res, next) {
32 | // set locals, only providing error in development
33 | res.locals.message = err.message;
34 | res.locals.error = req.app.get('env') === 'development' ? err : {};
35 |
36 | // render the error page
37 | res.status(err.status || 500);
38 | res.render('error');
39 | });
40 |
41 | module.exports = app;
42 |
--------------------------------------------------------------------------------
/with-dapr/container-1-node/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var app = require('../app');
8 | var debug = require('debug')('container-1-node:server');
9 | var http = require('http');
10 |
11 | /**
12 | * Get port from environment and store in Express.
13 | */
14 |
15 | var port = normalizePort(process.env.PORT || '3000');
16 | app.set('port', port);
17 |
18 | /**
19 | * Create HTTP server.
20 | */
21 |
22 | var server = http.createServer(app);
23 |
24 | /**
25 | * Listen on provided port, on all network interfaces.
26 | */
27 |
28 | server.listen(port);
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort(val) {
37 | var port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError(error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | var bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port;
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | break;
71 | case 'EADDRINUSE':
72 | console.error(bind + ' is already in use');
73 | process.exit(1);
74 | break;
75 | default:
76 | throw error;
77 | }
78 | }
79 |
80 | /**
81 | * Event listener for HTTP server "listening" event.
82 | */
83 |
84 | function onListening() {
85 | var addr = server.address();
86 | var bind = typeof addr === 'string'
87 | ? 'pipe ' + addr
88 | : 'port ' + addr.port;
89 | debug('Listening on ' + bind);
90 | }
91 |
--------------------------------------------------------------------------------
/with-dapr/container-1-node/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "container-1-node",
3 | "version": "0.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.7",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
11 | "requires": {
12 | "mime-types": "~2.1.24",
13 | "negotiator": "0.6.2"
14 | }
15 | },
16 | "acorn": {
17 | "version": "2.7.0",
18 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
19 | "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
20 | },
21 | "acorn-globals": {
22 | "version": "1.0.9",
23 | "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz",
24 | "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=",
25 | "requires": {
26 | "acorn": "^2.1.0"
27 | }
28 | },
29 | "align-text": {
30 | "version": "0.1.4",
31 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
32 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
33 | "requires": {
34 | "kind-of": "^3.0.2",
35 | "longest": "^1.0.1",
36 | "repeat-string": "^1.5.2"
37 | }
38 | },
39 | "amdefine": {
40 | "version": "1.0.1",
41 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
42 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
43 | },
44 | "array-flatten": {
45 | "version": "1.1.1",
46 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
47 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
48 | },
49 | "asap": {
50 | "version": "1.0.0",
51 | "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz",
52 | "integrity": "sha1-sqRdpf36ILBJb8N2jMJ8EvqRan0="
53 | },
54 | "axios": {
55 | "version": "0.24.0",
56 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
57 | "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
58 | "requires": {
59 | "follow-redirects": "^1.14.4"
60 | }
61 | },
62 | "basic-auth": {
63 | "version": "2.0.1",
64 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
65 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
66 | "requires": {
67 | "safe-buffer": "5.1.2"
68 | }
69 | },
70 | "body-parser": {
71 | "version": "1.18.3",
72 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
73 | "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
74 | "requires": {
75 | "bytes": "3.0.0",
76 | "content-type": "~1.0.4",
77 | "debug": "2.6.9",
78 | "depd": "~1.1.2",
79 | "http-errors": "~1.6.3",
80 | "iconv-lite": "0.4.23",
81 | "on-finished": "~2.3.0",
82 | "qs": "6.5.2",
83 | "raw-body": "2.3.3",
84 | "type-is": "~1.6.16"
85 | }
86 | },
87 | "bytes": {
88 | "version": "3.0.0",
89 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
90 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
91 | },
92 | "camelcase": {
93 | "version": "1.2.1",
94 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
95 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
96 | },
97 | "center-align": {
98 | "version": "0.1.3",
99 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
100 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
101 | "requires": {
102 | "align-text": "^0.1.3",
103 | "lazy-cache": "^1.0.3"
104 | }
105 | },
106 | "character-parser": {
107 | "version": "1.2.1",
108 | "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-1.2.1.tgz",
109 | "integrity": "sha1-wN3kqxgnE7kZuXCVmhI+zBow/NY="
110 | },
111 | "clean-css": {
112 | "version": "3.4.28",
113 | "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz",
114 | "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=",
115 | "requires": {
116 | "commander": "2.8.x",
117 | "source-map": "0.4.x"
118 | },
119 | "dependencies": {
120 | "commander": {
121 | "version": "2.8.1",
122 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
123 | "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
124 | "requires": {
125 | "graceful-readlink": ">= 1.0.0"
126 | }
127 | }
128 | }
129 | },
130 | "cliui": {
131 | "version": "2.1.0",
132 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
133 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
134 | "requires": {
135 | "center-align": "^0.1.1",
136 | "right-align": "^0.1.1",
137 | "wordwrap": "0.0.2"
138 | },
139 | "dependencies": {
140 | "wordwrap": {
141 | "version": "0.0.2",
142 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
143 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
144 | }
145 | }
146 | },
147 | "commander": {
148 | "version": "2.6.0",
149 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz",
150 | "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0="
151 | },
152 | "constantinople": {
153 | "version": "3.0.2",
154 | "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.0.2.tgz",
155 | "integrity": "sha1-S5RdmTeQe82Y7ldRIsOBdRZUQUE=",
156 | "requires": {
157 | "acorn": "^2.1.0"
158 | }
159 | },
160 | "content-disposition": {
161 | "version": "0.5.2",
162 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
163 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
164 | },
165 | "content-type": {
166 | "version": "1.0.4",
167 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
168 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
169 | },
170 | "cookie": {
171 | "version": "0.4.0",
172 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
173 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
174 | },
175 | "cookie-parser": {
176 | "version": "1.4.5",
177 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
178 | "integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
179 | "requires": {
180 | "cookie": "0.4.0",
181 | "cookie-signature": "1.0.6"
182 | }
183 | },
184 | "cookie-signature": {
185 | "version": "1.0.6",
186 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
187 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
188 | },
189 | "css": {
190 | "version": "1.0.8",
191 | "resolved": "https://registry.npmjs.org/css/-/css-1.0.8.tgz",
192 | "integrity": "sha1-k4aBHKgrzMnuf7WnMrHioxfIo+c=",
193 | "requires": {
194 | "css-parse": "1.0.4",
195 | "css-stringify": "1.0.5"
196 | }
197 | },
198 | "css-parse": {
199 | "version": "1.0.4",
200 | "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.0.4.tgz",
201 | "integrity": "sha1-OLBQP7+dqfVOnB29pg4UXHcRe90="
202 | },
203 | "css-stringify": {
204 | "version": "1.0.5",
205 | "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.0.5.tgz",
206 | "integrity": "sha1-sNBClG2ylTu50pKQCmy19tASIDE="
207 | },
208 | "debug": {
209 | "version": "2.6.9",
210 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
211 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
212 | "requires": {
213 | "ms": "2.0.0"
214 | }
215 | },
216 | "decamelize": {
217 | "version": "1.2.0",
218 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
219 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
220 | },
221 | "depd": {
222 | "version": "1.1.2",
223 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
224 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
225 | },
226 | "destroy": {
227 | "version": "1.0.4",
228 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
229 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
230 | },
231 | "ee-first": {
232 | "version": "1.1.1",
233 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
234 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
235 | },
236 | "encodeurl": {
237 | "version": "1.0.2",
238 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
239 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
240 | },
241 | "escape-html": {
242 | "version": "1.0.3",
243 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
244 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
245 | },
246 | "etag": {
247 | "version": "1.8.1",
248 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
249 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
250 | },
251 | "express": {
252 | "version": "4.16.4",
253 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
254 | "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
255 | "requires": {
256 | "accepts": "~1.3.5",
257 | "array-flatten": "1.1.1",
258 | "body-parser": "1.18.3",
259 | "content-disposition": "0.5.2",
260 | "content-type": "~1.0.4",
261 | "cookie": "0.3.1",
262 | "cookie-signature": "1.0.6",
263 | "debug": "2.6.9",
264 | "depd": "~1.1.2",
265 | "encodeurl": "~1.0.2",
266 | "escape-html": "~1.0.3",
267 | "etag": "~1.8.1",
268 | "finalhandler": "1.1.1",
269 | "fresh": "0.5.2",
270 | "merge-descriptors": "1.0.1",
271 | "methods": "~1.1.2",
272 | "on-finished": "~2.3.0",
273 | "parseurl": "~1.3.2",
274 | "path-to-regexp": "0.1.7",
275 | "proxy-addr": "~2.0.4",
276 | "qs": "6.5.2",
277 | "range-parser": "~1.2.0",
278 | "safe-buffer": "5.1.2",
279 | "send": "0.16.2",
280 | "serve-static": "1.13.2",
281 | "setprototypeof": "1.1.0",
282 | "statuses": "~1.4.0",
283 | "type-is": "~1.6.16",
284 | "utils-merge": "1.0.1",
285 | "vary": "~1.1.2"
286 | },
287 | "dependencies": {
288 | "cookie": {
289 | "version": "0.3.1",
290 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
291 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
292 | }
293 | }
294 | },
295 | "finalhandler": {
296 | "version": "1.1.1",
297 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
298 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
299 | "requires": {
300 | "debug": "2.6.9",
301 | "encodeurl": "~1.0.2",
302 | "escape-html": "~1.0.3",
303 | "on-finished": "~2.3.0",
304 | "parseurl": "~1.3.2",
305 | "statuses": "~1.4.0",
306 | "unpipe": "~1.0.0"
307 | }
308 | },
309 | "follow-redirects": {
310 | "version": "1.14.5",
311 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
312 | "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA=="
313 | },
314 | "forwarded": {
315 | "version": "0.2.0",
316 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
317 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
318 | },
319 | "fresh": {
320 | "version": "0.5.2",
321 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
322 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
323 | },
324 | "graceful-readlink": {
325 | "version": "1.0.1",
326 | "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
327 | "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
328 | },
329 | "http-errors": {
330 | "version": "1.6.3",
331 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
332 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
333 | "requires": {
334 | "depd": "~1.1.2",
335 | "inherits": "2.0.3",
336 | "setprototypeof": "1.1.0",
337 | "statuses": ">= 1.4.0 < 2"
338 | }
339 | },
340 | "iconv-lite": {
341 | "version": "0.4.23",
342 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
343 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
344 | "requires": {
345 | "safer-buffer": ">= 2.1.2 < 3"
346 | }
347 | },
348 | "inherits": {
349 | "version": "2.0.3",
350 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
351 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
352 | },
353 | "ipaddr.js": {
354 | "version": "1.9.1",
355 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
356 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
357 | },
358 | "is-buffer": {
359 | "version": "1.1.6",
360 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
361 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
362 | },
363 | "is-promise": {
364 | "version": "2.2.2",
365 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
366 | "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
367 | },
368 | "jade": {
369 | "version": "1.11.0",
370 | "resolved": "https://registry.npmjs.org/jade/-/jade-1.11.0.tgz",
371 | "integrity": "sha1-nIDlOMEtP7lcjZu5VZ+gzAQEBf0=",
372 | "requires": {
373 | "character-parser": "1.2.1",
374 | "clean-css": "^3.1.9",
375 | "commander": "~2.6.0",
376 | "constantinople": "~3.0.1",
377 | "jstransformer": "0.0.2",
378 | "mkdirp": "~0.5.0",
379 | "transformers": "2.1.0",
380 | "uglify-js": "^2.4.19",
381 | "void-elements": "~2.0.1",
382 | "with": "~4.0.0"
383 | }
384 | },
385 | "jstransformer": {
386 | "version": "0.0.2",
387 | "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-0.0.2.tgz",
388 | "integrity": "sha1-eq4pqQPRls+glz2IXT5HlH7Ndqs=",
389 | "requires": {
390 | "is-promise": "^2.0.0",
391 | "promise": "^6.0.1"
392 | }
393 | },
394 | "kind-of": {
395 | "version": "3.2.2",
396 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
397 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
398 | "requires": {
399 | "is-buffer": "^1.1.5"
400 | }
401 | },
402 | "lazy-cache": {
403 | "version": "1.0.4",
404 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
405 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4="
406 | },
407 | "longest": {
408 | "version": "1.0.1",
409 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
410 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
411 | },
412 | "media-typer": {
413 | "version": "0.3.0",
414 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
415 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
416 | },
417 | "merge-descriptors": {
418 | "version": "1.0.1",
419 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
420 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
421 | },
422 | "methods": {
423 | "version": "1.1.2",
424 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
425 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
426 | },
427 | "mime": {
428 | "version": "1.4.1",
429 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
430 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
431 | },
432 | "mime-db": {
433 | "version": "1.50.0",
434 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz",
435 | "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A=="
436 | },
437 | "mime-types": {
438 | "version": "2.1.33",
439 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz",
440 | "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==",
441 | "requires": {
442 | "mime-db": "1.50.0"
443 | }
444 | },
445 | "minimist": {
446 | "version": "1.2.5",
447 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
448 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
449 | },
450 | "mkdirp": {
451 | "version": "0.5.5",
452 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
453 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
454 | "requires": {
455 | "minimist": "^1.2.5"
456 | }
457 | },
458 | "morgan": {
459 | "version": "1.9.1",
460 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
461 | "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==",
462 | "requires": {
463 | "basic-auth": "~2.0.0",
464 | "debug": "2.6.9",
465 | "depd": "~1.1.2",
466 | "on-finished": "~2.3.0",
467 | "on-headers": "~1.0.1"
468 | }
469 | },
470 | "ms": {
471 | "version": "2.0.0",
472 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
473 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
474 | },
475 | "negotiator": {
476 | "version": "0.6.2",
477 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
478 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
479 | },
480 | "on-finished": {
481 | "version": "2.3.0",
482 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
483 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
484 | "requires": {
485 | "ee-first": "1.1.1"
486 | }
487 | },
488 | "on-headers": {
489 | "version": "1.0.2",
490 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
491 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
492 | },
493 | "optimist": {
494 | "version": "0.3.7",
495 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
496 | "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=",
497 | "requires": {
498 | "wordwrap": "~0.0.2"
499 | }
500 | },
501 | "parseurl": {
502 | "version": "1.3.3",
503 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
504 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
505 | },
506 | "path-to-regexp": {
507 | "version": "0.1.7",
508 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
509 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
510 | },
511 | "promise": {
512 | "version": "6.1.0",
513 | "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz",
514 | "integrity": "sha1-LOcp9rlLRcJoka0GAsXJDgTG7vY=",
515 | "requires": {
516 | "asap": "~1.0.0"
517 | }
518 | },
519 | "proxy-addr": {
520 | "version": "2.0.7",
521 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
522 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
523 | "requires": {
524 | "forwarded": "0.2.0",
525 | "ipaddr.js": "1.9.1"
526 | }
527 | },
528 | "qs": {
529 | "version": "6.5.2",
530 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
531 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
532 | },
533 | "range-parser": {
534 | "version": "1.2.1",
535 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
536 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
537 | },
538 | "raw-body": {
539 | "version": "2.3.3",
540 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
541 | "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
542 | "requires": {
543 | "bytes": "3.0.0",
544 | "http-errors": "1.6.3",
545 | "iconv-lite": "0.4.23",
546 | "unpipe": "1.0.0"
547 | }
548 | },
549 | "repeat-string": {
550 | "version": "1.6.1",
551 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
552 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
553 | },
554 | "right-align": {
555 | "version": "0.1.3",
556 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
557 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
558 | "requires": {
559 | "align-text": "^0.1.1"
560 | }
561 | },
562 | "safe-buffer": {
563 | "version": "5.1.2",
564 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
565 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
566 | },
567 | "safer-buffer": {
568 | "version": "2.1.2",
569 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
570 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
571 | },
572 | "send": {
573 | "version": "0.16.2",
574 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
575 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
576 | "requires": {
577 | "debug": "2.6.9",
578 | "depd": "~1.1.2",
579 | "destroy": "~1.0.4",
580 | "encodeurl": "~1.0.2",
581 | "escape-html": "~1.0.3",
582 | "etag": "~1.8.1",
583 | "fresh": "0.5.2",
584 | "http-errors": "~1.6.2",
585 | "mime": "1.4.1",
586 | "ms": "2.0.0",
587 | "on-finished": "~2.3.0",
588 | "range-parser": "~1.2.0",
589 | "statuses": "~1.4.0"
590 | }
591 | },
592 | "serve-static": {
593 | "version": "1.13.2",
594 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
595 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
596 | "requires": {
597 | "encodeurl": "~1.0.2",
598 | "escape-html": "~1.0.3",
599 | "parseurl": "~1.3.2",
600 | "send": "0.16.2"
601 | }
602 | },
603 | "setprototypeof": {
604 | "version": "1.1.0",
605 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
606 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
607 | },
608 | "source-map": {
609 | "version": "0.4.4",
610 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
611 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
612 | "requires": {
613 | "amdefine": ">=0.0.4"
614 | }
615 | },
616 | "statuses": {
617 | "version": "1.4.0",
618 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
619 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
620 | },
621 | "transformers": {
622 | "version": "2.1.0",
623 | "resolved": "https://registry.npmjs.org/transformers/-/transformers-2.1.0.tgz",
624 | "integrity": "sha1-XSPLNVYd2F3Gf7hIIwm0fVPM6ac=",
625 | "requires": {
626 | "css": "~1.0.8",
627 | "promise": "~2.0",
628 | "uglify-js": "~2.2.5"
629 | },
630 | "dependencies": {
631 | "is-promise": {
632 | "version": "1.0.1",
633 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz",
634 | "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU="
635 | },
636 | "promise": {
637 | "version": "2.0.0",
638 | "resolved": "https://registry.npmjs.org/promise/-/promise-2.0.0.tgz",
639 | "integrity": "sha1-RmSKqdYFr10ucMMCS/WUNtoCuA4=",
640 | "requires": {
641 | "is-promise": "~1"
642 | }
643 | },
644 | "source-map": {
645 | "version": "0.1.43",
646 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
647 | "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
648 | "requires": {
649 | "amdefine": ">=0.0.4"
650 | }
651 | },
652 | "uglify-js": {
653 | "version": "2.2.5",
654 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.2.5.tgz",
655 | "integrity": "sha1-puAqcNg5eSuXgEiLe4sYTAlcmcc=",
656 | "requires": {
657 | "optimist": "~0.3.5",
658 | "source-map": "~0.1.7"
659 | }
660 | }
661 | }
662 | },
663 | "type-is": {
664 | "version": "1.6.18",
665 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
666 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
667 | "requires": {
668 | "media-typer": "0.3.0",
669 | "mime-types": "~2.1.24"
670 | }
671 | },
672 | "uglify-js": {
673 | "version": "2.8.29",
674 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
675 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
676 | "requires": {
677 | "source-map": "~0.5.1",
678 | "uglify-to-browserify": "~1.0.0",
679 | "yargs": "~3.10.0"
680 | },
681 | "dependencies": {
682 | "source-map": {
683 | "version": "0.5.7",
684 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
685 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
686 | }
687 | }
688 | },
689 | "uglify-to-browserify": {
690 | "version": "1.0.2",
691 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
692 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
693 | "optional": true
694 | },
695 | "unpipe": {
696 | "version": "1.0.0",
697 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
698 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
699 | },
700 | "utils-merge": {
701 | "version": "1.0.1",
702 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
703 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
704 | },
705 | "vary": {
706 | "version": "1.1.2",
707 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
708 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
709 | },
710 | "void-elements": {
711 | "version": "2.0.1",
712 | "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
713 | "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
714 | },
715 | "window-size": {
716 | "version": "0.1.0",
717 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
718 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
719 | },
720 | "with": {
721 | "version": "4.0.3",
722 | "resolved": "https://registry.npmjs.org/with/-/with-4.0.3.tgz",
723 | "integrity": "sha1-7v0VTp550sjTQXtkeo8U2f7M4U4=",
724 | "requires": {
725 | "acorn": "^1.0.1",
726 | "acorn-globals": "^1.0.3"
727 | },
728 | "dependencies": {
729 | "acorn": {
730 | "version": "1.2.2",
731 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz",
732 | "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ="
733 | }
734 | }
735 | },
736 | "wordwrap": {
737 | "version": "0.0.3",
738 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
739 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
740 | },
741 | "yargs": {
742 | "version": "3.10.0",
743 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
744 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
745 | "requires": {
746 | "camelcase": "^1.0.2",
747 | "cliui": "^2.1.0",
748 | "decamelize": "^1.0.0",
749 | "window-size": "0.1.0"
750 | }
751 | }
752 | }
753 | }
754 |
--------------------------------------------------------------------------------
/with-dapr/container-1-node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "container-1-node",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node ./bin/www"
7 | },
8 | "dependencies": {
9 | "axios": "^0.24.0",
10 | "cookie-parser": "~1.4.4",
11 | "debug": "~2.6.9",
12 | "express": "~4.16.1",
13 | "http-errors": "~1.6.3",
14 | "jade": "~1.11.0",
15 | "morgan": "~1.9.1"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/with-dapr/container-1-node/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
9 |
--------------------------------------------------------------------------------
/with-dapr/container-1-node/routes/hello.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 | const axios = require('axios').default;
4 | const dotnetAppId = process.env.DOTNET_APP_ID;
5 | const daprPort = process.env.DAPR_HTTP_PORT || 3500;
6 |
7 | /* GET users listing. */
8 | router.get('/', async function(req, res, next) {
9 |
10 | if(dotnetAppId) {
11 | // Because we're using Dapr here, it will add mTLS, retries, and advanced telemetry
12 | var data = await axios.get(`http://localhost:${daprPort}/hello`, {
13 | headers: {'dapr-app-id': `${dotnetAppId}`} //sets app name for service discovery
14 | });
15 | res.send(`${JSON.stringify(data.data)}`);
16 | }
17 | else {
18 | res.send('No DOTNET_APP_ID env variable defined. Be sure to set an env variable for the DOTNET_APP_ID for Dapr')
19 | }
20 |
21 | });
22 |
23 | module.exports = router;
--------------------------------------------------------------------------------
/with-dapr/container-1-node/routes/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 |
4 | /* GET home page. */
5 | router.get('/', function(req, res, next) {
6 | res.render('index', { title: 'Container App Sample' });
7 | });
8 |
9 | module.exports = router;
10 |
--------------------------------------------------------------------------------
/with-dapr/container-1-node/views/error.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= message
5 | h2= error.status
6 | pre #{error.stack}
7 |
--------------------------------------------------------------------------------
/with-dapr/container-1-node/views/index.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= title
5 | p Welcome to #{title}
6 |
7 | br
8 | form(action="/hello", method="get")
9 | input(type="submit", value="Say Hello to dotnetApp")
10 |
--------------------------------------------------------------------------------
/with-dapr/container-1-node/views/layout.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title= title
5 | link(rel='stylesheet', href='/stylesheets/style.css')
6 | body
7 | block content
8 |
--------------------------------------------------------------------------------
/with-dapr/container-2-dotnet/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1
2 | FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
3 | WORKDIR /app
4 |
5 | # Copy csproj and restore as distinct layers
6 | COPY *.csproj ./
7 | RUN dotnet restore
8 |
9 | # Copy everything else and build
10 | COPY . .
11 | RUN dotnet publish -c Release -o out
12 |
13 | # Build runtime image
14 | FROM mcr.microsoft.com/dotnet/aspnet:6.0
15 | WORKDIR /app
16 | COPY --from=build-env /app/out .
17 | ENTRYPOINT ["dotnet", "container-2-dotnet.dll"]
--------------------------------------------------------------------------------
/with-dapr/container-2-dotnet/Program.cs:
--------------------------------------------------------------------------------
1 | var builder = WebApplication.CreateBuilder(args);
2 | var app = builder.Build();
3 |
4 | app.MapGet("/hello", () => "Hello from the .NET 6 container!");
5 |
6 | app.Run();
7 |
--------------------------------------------------------------------------------
/with-dapr/container-2-dotnet/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:3289",
7 | "sslPort": 44327
8 | }
9 | },
10 | "profiles": {
11 | "container_2_dotnet": {
12 | "commandName": "Project",
13 | "dotnetRunMessages": true,
14 | "launchBrowser": true,
15 | "applicationUrl": "https://localhost:7245;http://localhost:5230",
16 | "environmentVariables": {
17 | "ASPNETCORE_ENVIRONMENT": "Development"
18 | }
19 | },
20 | "IIS Express": {
21 | "commandName": "IISExpress",
22 | "launchBrowser": true,
23 | "environmentVariables": {
24 | "ASPNETCORE_ENVIRONMENT": "Development"
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/with-dapr/container-2-dotnet/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/with-dapr/container-2-dotnet/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "AllowedHosts": "*"
9 | }
10 |
--------------------------------------------------------------------------------
/with-dapr/container-2-dotnet/container-2-dotnet.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 | container_2_dotnet
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/with-dapr/deploy/container-app.bicep:
--------------------------------------------------------------------------------
1 | param containerAppName string
2 | param location string
3 | param environmentId string
4 | param containerImage string
5 | param containerPort int
6 | param isExternalIngress bool = false
7 | param containerRegistry string
8 | param containerRegistryUsername string
9 |
10 | param environmentVars array = []
11 |
12 | @secure()
13 | param containerRegistryPassword string
14 |
15 | resource containerApp 'Microsoft.App/containerApps@2022-01-01-preview' = {
16 | name: containerAppName
17 | location: location
18 | properties: {
19 | managedEnvironmentId: environmentId
20 | configuration: {
21 | secrets: [
22 | {
23 | name: 'registry-password'
24 | value: containerRegistryPassword
25 | }
26 | ]
27 | registries: [
28 | {
29 | server: containerRegistry
30 | username: containerRegistryUsername
31 | passwordSecretRef: 'registry-password'
32 | }
33 | ]
34 | ingress: {
35 | external: isExternalIngress
36 | targetPort: containerPort
37 | }
38 | dapr: {
39 | enabled: true
40 | appPort: containerPort
41 | appId: containerAppName
42 | }
43 | }
44 | template: {
45 | containers: [
46 | {
47 | image: containerImage
48 | name: containerAppName
49 | env: environmentVars
50 | }
51 | ]
52 | scale: {
53 | minReplicas: 0
54 | }
55 | }
56 | }
57 | }
58 |
59 | output fqdn string = containerApp.properties.configuration.ingress.fqdn
60 |
--------------------------------------------------------------------------------
/with-dapr/deploy/environment.bicep:
--------------------------------------------------------------------------------
1 | param location string
2 | param environmentName string
3 | param logAnalyticsWorkspaceName string = 'logs-${environmentName}'
4 |
5 | resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2020-03-01-preview' = {
6 | name: logAnalyticsWorkspaceName
7 | location: location
8 | properties: any({
9 | retentionInDays: 30
10 | features: {
11 | searchVersion: 1
12 | }
13 | sku: {
14 | name: 'PerGB2018'
15 | }
16 | })
17 | }
18 |
19 | resource environment 'Microsoft.App/managedEnvironments@2022-01-01-preview' = {
20 | name: environmentName
21 | location: location
22 | properties: {
23 | appLogsConfiguration: {
24 | destination: 'log-analytics'
25 | logAnalyticsConfiguration: {
26 | customerId: logAnalyticsWorkspace.properties.customerId
27 | sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
28 | }
29 | }
30 | }
31 | }
32 |
33 | output environmentId string = environment.id
34 |
--------------------------------------------------------------------------------
/with-dapr/deploy/main.bicep:
--------------------------------------------------------------------------------
1 | param location string = resourceGroup().location
2 | param environmentName string = 'sample-env'
3 | param nodeImage string
4 | param nodePort int
5 | param dotnetImage string
6 | param dotnetPort int
7 | param registry string
8 | param registryUsername string
9 | @secure()
10 | param registryPassword string
11 |
12 | // Container Apps Environment (environment.bicep)
13 | module environment 'environment.bicep' = {
14 | name: 'container-app-environment'
15 | params: {
16 | environmentName: environmentName
17 | location: location
18 | }
19 | }
20 |
21 |
22 | // Container-2-Dotnet (container-app.bicep)
23 | // We deploy it first so we can call it from the node-app
24 | module dotnetApp 'container-app.bicep' = {
25 | name: 'dotnetApp'
26 | params: {
27 | containerAppName: 'dotnet-app-dapr'
28 | location: location
29 | environmentId: environment.outputs.environmentId
30 | containerImage: dotnetImage
31 | containerPort: dotnetPort
32 | containerRegistry: registry
33 | containerRegistryUsername: registryUsername
34 | containerRegistryPassword: registryPassword
35 | isExternalIngress: false
36 | }
37 | }
38 |
39 |
40 | // Container-1-Node (container-app.bicep)
41 | module nodeApp 'container-app.bicep' = {
42 | name: 'nodeApp'
43 | params: {
44 | containerAppName: 'node-app-dapr'
45 | location: location
46 | environmentId: environment.outputs.environmentId
47 | containerImage: nodeImage
48 | containerPort: nodePort
49 | containerRegistry: registry
50 | containerRegistryUsername: registryUsername
51 | containerRegistryPassword: registryPassword
52 | isExternalIngress: true
53 | // set an environment var for the dotnetFQDN to call
54 | environmentVars: [
55 | {
56 | name: 'DOTNET_APP_ID'
57 | value: 'dotnet-app-dapr'
58 | }
59 | ]
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/with-fqdn/README.md:
--------------------------------------------------------------------------------
1 | # Calling with FQDN
2 |
3 | I can call the dotnet-app from the node-app by calling it's FQDN. Even though I use the FQDN, **calls within the environment will stay within the environment and network traffic will not leave**.
4 |
5 | ```js
6 | const dotnetFQDN = process.env.DOTNET_FQDN;
7 | // ...
8 | var data = await axios.get(`http://${dotnetFQDN}`);
9 | res.send(`${JSON.stringify(data.data)}`);
10 | ```
11 |
12 | ## Deploy with CLI
13 |
14 | ```bash
15 | # Login to the CLI
16 | az login
17 | az extension add \
18 | --source https://workerappscliextension.blob.core.windows.net/azure-cli-extension/containerapp-0.2.0-py2.py3-none-any.whl
19 | az provider register --namespace Microsoft.Web
20 |
21 | # Create a resource group
22 | az group create \
23 | --name 'sample-rg' \
24 | --location canadacentral
25 |
26 | az monitor log-analytics workspace create \
27 | --resource-group 'sample-rg' \
28 | --workspace-name 'logs-for-sample'
29 |
30 | LOG_ANALYTICS_WORKSPACE_CLIENT_ID=`az monitor log-analytics workspace show --query customerId -g 'sample-rg' -n 'logs-for-sample' --out tsv`
31 | LOG_ANALYTICS_WORKSPACE_CLIENT_SECRET=`az monitor log-analytics workspace get-shared-keys --query primarySharedKey -g 'sample-rg' -n 'logs-for-sample' --out tsv`
32 |
33 | # Create a container app environment
34 | az containerapp env create \
35 | --name 'sample-env'\
36 | --resource-group 'sample-rg' \
37 | --logs-workspace-id $LOG_ANALYTICS_WORKSPACE_CLIENT_ID \
38 | --logs-workspace-key $LOG_ANALYTICS_WORKSPACE_CLIENT_SECRET \
39 | --location canadacentral
40 |
41 | # Deploy the container-2-dotnet dotnet-app
42 | az containerapp create \
43 | --name dotnet-app \
44 | --resource-group 'sample-rg' \
45 | --environment 'sample-env' \
46 | --image 'ghcr.io/azure-samples/container-apps-connect-multiple-apps/dotnet:main' \
47 | --target-port 80 \
48 | --ingress 'internal'
49 |
50 | DOTNET_FQDN=$(az containerapp show \
51 | --resource-group 'sample-rg' \
52 | --name dotnet-app \
53 | --query configuration.ingress.fqdn -o tsv)
54 |
55 | # Deploy the container-1-node node-app
56 | az containerapp create \
57 | --name node-app \
58 | --resource-group 'sample-rg' \
59 | --environment 'sample-env' \
60 | --image 'ghcr.io/azure-samples/container-apps-connect-multiple-apps/node:main' \
61 | --target-port 3000 \
62 | --ingress 'external' \
63 | --environment-variables DOTNET_FQDN=$DOTNET_FQDN \
64 | --query configuration.ingress.fqdn
65 | ```
66 |
67 |
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/.dockerignore:
--------------------------------------------------------------------------------
1 | node_modules/
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16-alpine
2 | WORKDIR /usr/src/app
3 | COPY package*.json ./
4 | RUN npm install
5 | COPY . .
6 | EXPOSE 3000
7 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/app.js:
--------------------------------------------------------------------------------
1 | var createError = require('http-errors');
2 | var express = require('express');
3 | var path = require('path');
4 | var cookieParser = require('cookie-parser');
5 | var logger = require('morgan');
6 |
7 | var indexRouter = require('./routes/index');
8 | var helloRouter = require('./routes/hello');
9 |
10 | var app = express();
11 |
12 | // view engine setup
13 | app.set('views', path.join(__dirname, 'views'));
14 | app.set('view engine', 'jade');
15 |
16 | app.use(logger('dev'));
17 | app.use(express.json());
18 | app.use(express.urlencoded({ extended: false }));
19 | app.use(cookieParser());
20 | app.use(express.static(path.join(__dirname, 'public')));
21 |
22 | app.use('/', indexRouter);
23 | app.use('/hello', helloRouter);
24 |
25 | // catch 404 and forward to error handler
26 | app.use(function(req, res, next) {
27 | next(createError(404));
28 | });
29 |
30 | // error handler
31 | app.use(function(err, req, res, next) {
32 | // set locals, only providing error in development
33 | res.locals.message = err.message;
34 | res.locals.error = req.app.get('env') === 'development' ? err : {};
35 |
36 | // render the error page
37 | res.status(err.status || 500);
38 | res.render('error');
39 | });
40 |
41 | module.exports = app;
42 |
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/bin/www:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var app = require('../app');
8 | var debug = require('debug')('container-1-node:server');
9 | var http = require('http');
10 |
11 | /**
12 | * Get port from environment and store in Express.
13 | */
14 |
15 | var port = normalizePort(process.env.PORT || '3000');
16 | app.set('port', port);
17 |
18 | /**
19 | * Create HTTP server.
20 | */
21 |
22 | var server = http.createServer(app);
23 |
24 | /**
25 | * Listen on provided port, on all network interfaces.
26 | */
27 |
28 | server.listen(port);
29 | server.on('error', onError);
30 | server.on('listening', onListening);
31 |
32 | /**
33 | * Normalize a port into a number, string, or false.
34 | */
35 |
36 | function normalizePort(val) {
37 | var port = parseInt(val, 10);
38 |
39 | if (isNaN(port)) {
40 | // named pipe
41 | return val;
42 | }
43 |
44 | if (port >= 0) {
45 | // port number
46 | return port;
47 | }
48 |
49 | return false;
50 | }
51 |
52 | /**
53 | * Event listener for HTTP server "error" event.
54 | */
55 |
56 | function onError(error) {
57 | if (error.syscall !== 'listen') {
58 | throw error;
59 | }
60 |
61 | var bind = typeof port === 'string'
62 | ? 'Pipe ' + port
63 | : 'Port ' + port;
64 |
65 | // handle specific listen errors with friendly messages
66 | switch (error.code) {
67 | case 'EACCES':
68 | console.error(bind + ' requires elevated privileges');
69 | process.exit(1);
70 | break;
71 | case 'EADDRINUSE':
72 | console.error(bind + ' is already in use');
73 | process.exit(1);
74 | break;
75 | default:
76 | throw error;
77 | }
78 | }
79 |
80 | /**
81 | * Event listener for HTTP server "listening" event.
82 | */
83 |
84 | function onListening() {
85 | var addr = server.address();
86 | var bind = typeof addr === 'string'
87 | ? 'pipe ' + addr
88 | : 'port ' + addr.port;
89 | debug('Listening on ' + bind);
90 | }
91 |
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "container-1-node",
3 | "version": "0.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.7",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
10 | "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
11 | "requires": {
12 | "mime-types": "~2.1.24",
13 | "negotiator": "0.6.2"
14 | }
15 | },
16 | "acorn": {
17 | "version": "2.7.0",
18 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
19 | "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
20 | },
21 | "acorn-globals": {
22 | "version": "1.0.9",
23 | "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz",
24 | "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=",
25 | "requires": {
26 | "acorn": "^2.1.0"
27 | }
28 | },
29 | "align-text": {
30 | "version": "0.1.4",
31 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
32 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
33 | "requires": {
34 | "kind-of": "^3.0.2",
35 | "longest": "^1.0.1",
36 | "repeat-string": "^1.5.2"
37 | }
38 | },
39 | "amdefine": {
40 | "version": "1.0.1",
41 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
42 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
43 | },
44 | "array-flatten": {
45 | "version": "1.1.1",
46 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
47 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
48 | },
49 | "asap": {
50 | "version": "1.0.0",
51 | "resolved": "https://registry.npmjs.org/asap/-/asap-1.0.0.tgz",
52 | "integrity": "sha1-sqRdpf36ILBJb8N2jMJ8EvqRan0="
53 | },
54 | "axios": {
55 | "version": "0.24.0",
56 | "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz",
57 | "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==",
58 | "requires": {
59 | "follow-redirects": "^1.14.4"
60 | }
61 | },
62 | "basic-auth": {
63 | "version": "2.0.1",
64 | "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
65 | "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
66 | "requires": {
67 | "safe-buffer": "5.1.2"
68 | }
69 | },
70 | "body-parser": {
71 | "version": "1.18.3",
72 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
73 | "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
74 | "requires": {
75 | "bytes": "3.0.0",
76 | "content-type": "~1.0.4",
77 | "debug": "2.6.9",
78 | "depd": "~1.1.2",
79 | "http-errors": "~1.6.3",
80 | "iconv-lite": "0.4.23",
81 | "on-finished": "~2.3.0",
82 | "qs": "6.5.2",
83 | "raw-body": "2.3.3",
84 | "type-is": "~1.6.16"
85 | }
86 | },
87 | "bytes": {
88 | "version": "3.0.0",
89 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
90 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
91 | },
92 | "camelcase": {
93 | "version": "1.2.1",
94 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
95 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
96 | },
97 | "center-align": {
98 | "version": "0.1.3",
99 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
100 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
101 | "requires": {
102 | "align-text": "^0.1.3",
103 | "lazy-cache": "^1.0.3"
104 | }
105 | },
106 | "character-parser": {
107 | "version": "1.2.1",
108 | "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-1.2.1.tgz",
109 | "integrity": "sha1-wN3kqxgnE7kZuXCVmhI+zBow/NY="
110 | },
111 | "clean-css": {
112 | "version": "3.4.28",
113 | "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-3.4.28.tgz",
114 | "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=",
115 | "requires": {
116 | "commander": "2.8.x",
117 | "source-map": "0.4.x"
118 | },
119 | "dependencies": {
120 | "commander": {
121 | "version": "2.8.1",
122 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
123 | "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
124 | "requires": {
125 | "graceful-readlink": ">= 1.0.0"
126 | }
127 | }
128 | }
129 | },
130 | "cliui": {
131 | "version": "2.1.0",
132 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
133 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
134 | "requires": {
135 | "center-align": "^0.1.1",
136 | "right-align": "^0.1.1",
137 | "wordwrap": "0.0.2"
138 | },
139 | "dependencies": {
140 | "wordwrap": {
141 | "version": "0.0.2",
142 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
143 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
144 | }
145 | }
146 | },
147 | "commander": {
148 | "version": "2.6.0",
149 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.6.0.tgz",
150 | "integrity": "sha1-nfflL7Kgyw+4kFjugMMQQiXzfh0="
151 | },
152 | "constantinople": {
153 | "version": "3.0.2",
154 | "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.0.2.tgz",
155 | "integrity": "sha1-S5RdmTeQe82Y7ldRIsOBdRZUQUE=",
156 | "requires": {
157 | "acorn": "^2.1.0"
158 | }
159 | },
160 | "content-disposition": {
161 | "version": "0.5.2",
162 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
163 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
164 | },
165 | "content-type": {
166 | "version": "1.0.4",
167 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
168 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
169 | },
170 | "cookie": {
171 | "version": "0.4.0",
172 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
173 | "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
174 | },
175 | "cookie-parser": {
176 | "version": "1.4.5",
177 | "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.5.tgz",
178 | "integrity": "sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==",
179 | "requires": {
180 | "cookie": "0.4.0",
181 | "cookie-signature": "1.0.6"
182 | }
183 | },
184 | "cookie-signature": {
185 | "version": "1.0.6",
186 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
187 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
188 | },
189 | "css": {
190 | "version": "1.0.8",
191 | "resolved": "https://registry.npmjs.org/css/-/css-1.0.8.tgz",
192 | "integrity": "sha1-k4aBHKgrzMnuf7WnMrHioxfIo+c=",
193 | "requires": {
194 | "css-parse": "1.0.4",
195 | "css-stringify": "1.0.5"
196 | }
197 | },
198 | "css-parse": {
199 | "version": "1.0.4",
200 | "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.0.4.tgz",
201 | "integrity": "sha1-OLBQP7+dqfVOnB29pg4UXHcRe90="
202 | },
203 | "css-stringify": {
204 | "version": "1.0.5",
205 | "resolved": "https://registry.npmjs.org/css-stringify/-/css-stringify-1.0.5.tgz",
206 | "integrity": "sha1-sNBClG2ylTu50pKQCmy19tASIDE="
207 | },
208 | "debug": {
209 | "version": "2.6.9",
210 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
211 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
212 | "requires": {
213 | "ms": "2.0.0"
214 | }
215 | },
216 | "decamelize": {
217 | "version": "1.2.0",
218 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
219 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
220 | },
221 | "depd": {
222 | "version": "1.1.2",
223 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
224 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
225 | },
226 | "destroy": {
227 | "version": "1.0.4",
228 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
229 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
230 | },
231 | "ee-first": {
232 | "version": "1.1.1",
233 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
234 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
235 | },
236 | "encodeurl": {
237 | "version": "1.0.2",
238 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
239 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
240 | },
241 | "escape-html": {
242 | "version": "1.0.3",
243 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
244 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
245 | },
246 | "etag": {
247 | "version": "1.8.1",
248 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
249 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
250 | },
251 | "express": {
252 | "version": "4.16.4",
253 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
254 | "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
255 | "requires": {
256 | "accepts": "~1.3.5",
257 | "array-flatten": "1.1.1",
258 | "body-parser": "1.18.3",
259 | "content-disposition": "0.5.2",
260 | "content-type": "~1.0.4",
261 | "cookie": "0.3.1",
262 | "cookie-signature": "1.0.6",
263 | "debug": "2.6.9",
264 | "depd": "~1.1.2",
265 | "encodeurl": "~1.0.2",
266 | "escape-html": "~1.0.3",
267 | "etag": "~1.8.1",
268 | "finalhandler": "1.1.1",
269 | "fresh": "0.5.2",
270 | "merge-descriptors": "1.0.1",
271 | "methods": "~1.1.2",
272 | "on-finished": "~2.3.0",
273 | "parseurl": "~1.3.2",
274 | "path-to-regexp": "0.1.7",
275 | "proxy-addr": "~2.0.4",
276 | "qs": "6.5.2",
277 | "range-parser": "~1.2.0",
278 | "safe-buffer": "5.1.2",
279 | "send": "0.16.2",
280 | "serve-static": "1.13.2",
281 | "setprototypeof": "1.1.0",
282 | "statuses": "~1.4.0",
283 | "type-is": "~1.6.16",
284 | "utils-merge": "1.0.1",
285 | "vary": "~1.1.2"
286 | },
287 | "dependencies": {
288 | "cookie": {
289 | "version": "0.3.1",
290 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
291 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
292 | }
293 | }
294 | },
295 | "finalhandler": {
296 | "version": "1.1.1",
297 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
298 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
299 | "requires": {
300 | "debug": "2.6.9",
301 | "encodeurl": "~1.0.2",
302 | "escape-html": "~1.0.3",
303 | "on-finished": "~2.3.0",
304 | "parseurl": "~1.3.2",
305 | "statuses": "~1.4.0",
306 | "unpipe": "~1.0.0"
307 | }
308 | },
309 | "follow-redirects": {
310 | "version": "1.14.5",
311 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz",
312 | "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA=="
313 | },
314 | "forwarded": {
315 | "version": "0.2.0",
316 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
317 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
318 | },
319 | "fresh": {
320 | "version": "0.5.2",
321 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
322 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
323 | },
324 | "graceful-readlink": {
325 | "version": "1.0.1",
326 | "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz",
327 | "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU="
328 | },
329 | "http-errors": {
330 | "version": "1.6.3",
331 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
332 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
333 | "requires": {
334 | "depd": "~1.1.2",
335 | "inherits": "2.0.3",
336 | "setprototypeof": "1.1.0",
337 | "statuses": ">= 1.4.0 < 2"
338 | }
339 | },
340 | "iconv-lite": {
341 | "version": "0.4.23",
342 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
343 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
344 | "requires": {
345 | "safer-buffer": ">= 2.1.2 < 3"
346 | }
347 | },
348 | "inherits": {
349 | "version": "2.0.3",
350 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
351 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
352 | },
353 | "ipaddr.js": {
354 | "version": "1.9.1",
355 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
356 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
357 | },
358 | "is-buffer": {
359 | "version": "1.1.6",
360 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
361 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
362 | },
363 | "is-promise": {
364 | "version": "2.2.2",
365 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
366 | "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
367 | },
368 | "jade": {
369 | "version": "1.11.0",
370 | "resolved": "https://registry.npmjs.org/jade/-/jade-1.11.0.tgz",
371 | "integrity": "sha1-nIDlOMEtP7lcjZu5VZ+gzAQEBf0=",
372 | "requires": {
373 | "character-parser": "1.2.1",
374 | "clean-css": "^3.1.9",
375 | "commander": "~2.6.0",
376 | "constantinople": "~3.0.1",
377 | "jstransformer": "0.0.2",
378 | "mkdirp": "~0.5.0",
379 | "transformers": "2.1.0",
380 | "uglify-js": "^2.4.19",
381 | "void-elements": "~2.0.1",
382 | "with": "~4.0.0"
383 | }
384 | },
385 | "jstransformer": {
386 | "version": "0.0.2",
387 | "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-0.0.2.tgz",
388 | "integrity": "sha1-eq4pqQPRls+glz2IXT5HlH7Ndqs=",
389 | "requires": {
390 | "is-promise": "^2.0.0",
391 | "promise": "^6.0.1"
392 | }
393 | },
394 | "kind-of": {
395 | "version": "3.2.2",
396 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
397 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
398 | "requires": {
399 | "is-buffer": "^1.1.5"
400 | }
401 | },
402 | "lazy-cache": {
403 | "version": "1.0.4",
404 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
405 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4="
406 | },
407 | "longest": {
408 | "version": "1.0.1",
409 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
410 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
411 | },
412 | "media-typer": {
413 | "version": "0.3.0",
414 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
415 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
416 | },
417 | "merge-descriptors": {
418 | "version": "1.0.1",
419 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
420 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
421 | },
422 | "methods": {
423 | "version": "1.1.2",
424 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
425 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
426 | },
427 | "mime": {
428 | "version": "1.4.1",
429 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
430 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
431 | },
432 | "mime-db": {
433 | "version": "1.50.0",
434 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz",
435 | "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A=="
436 | },
437 | "mime-types": {
438 | "version": "2.1.33",
439 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz",
440 | "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==",
441 | "requires": {
442 | "mime-db": "1.50.0"
443 | }
444 | },
445 | "minimist": {
446 | "version": "1.2.5",
447 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
448 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
449 | },
450 | "mkdirp": {
451 | "version": "0.5.5",
452 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
453 | "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
454 | "requires": {
455 | "minimist": "^1.2.5"
456 | }
457 | },
458 | "morgan": {
459 | "version": "1.9.1",
460 | "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
461 | "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==",
462 | "requires": {
463 | "basic-auth": "~2.0.0",
464 | "debug": "2.6.9",
465 | "depd": "~1.1.2",
466 | "on-finished": "~2.3.0",
467 | "on-headers": "~1.0.1"
468 | }
469 | },
470 | "ms": {
471 | "version": "2.0.0",
472 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
473 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
474 | },
475 | "negotiator": {
476 | "version": "0.6.2",
477 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
478 | "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
479 | },
480 | "on-finished": {
481 | "version": "2.3.0",
482 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
483 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
484 | "requires": {
485 | "ee-first": "1.1.1"
486 | }
487 | },
488 | "on-headers": {
489 | "version": "1.0.2",
490 | "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
491 | "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
492 | },
493 | "optimist": {
494 | "version": "0.3.7",
495 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
496 | "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=",
497 | "requires": {
498 | "wordwrap": "~0.0.2"
499 | }
500 | },
501 | "parseurl": {
502 | "version": "1.3.3",
503 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
504 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
505 | },
506 | "path-to-regexp": {
507 | "version": "0.1.7",
508 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
509 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
510 | },
511 | "promise": {
512 | "version": "6.1.0",
513 | "resolved": "https://registry.npmjs.org/promise/-/promise-6.1.0.tgz",
514 | "integrity": "sha1-LOcp9rlLRcJoka0GAsXJDgTG7vY=",
515 | "requires": {
516 | "asap": "~1.0.0"
517 | }
518 | },
519 | "proxy-addr": {
520 | "version": "2.0.7",
521 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
522 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
523 | "requires": {
524 | "forwarded": "0.2.0",
525 | "ipaddr.js": "1.9.1"
526 | }
527 | },
528 | "qs": {
529 | "version": "6.5.2",
530 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
531 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
532 | },
533 | "range-parser": {
534 | "version": "1.2.1",
535 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
536 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
537 | },
538 | "raw-body": {
539 | "version": "2.3.3",
540 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
541 | "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
542 | "requires": {
543 | "bytes": "3.0.0",
544 | "http-errors": "1.6.3",
545 | "iconv-lite": "0.4.23",
546 | "unpipe": "1.0.0"
547 | }
548 | },
549 | "repeat-string": {
550 | "version": "1.6.1",
551 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
552 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
553 | },
554 | "right-align": {
555 | "version": "0.1.3",
556 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
557 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
558 | "requires": {
559 | "align-text": "^0.1.1"
560 | }
561 | },
562 | "safe-buffer": {
563 | "version": "5.1.2",
564 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
565 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
566 | },
567 | "safer-buffer": {
568 | "version": "2.1.2",
569 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
570 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
571 | },
572 | "send": {
573 | "version": "0.16.2",
574 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
575 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
576 | "requires": {
577 | "debug": "2.6.9",
578 | "depd": "~1.1.2",
579 | "destroy": "~1.0.4",
580 | "encodeurl": "~1.0.2",
581 | "escape-html": "~1.0.3",
582 | "etag": "~1.8.1",
583 | "fresh": "0.5.2",
584 | "http-errors": "~1.6.2",
585 | "mime": "1.4.1",
586 | "ms": "2.0.0",
587 | "on-finished": "~2.3.0",
588 | "range-parser": "~1.2.0",
589 | "statuses": "~1.4.0"
590 | }
591 | },
592 | "serve-static": {
593 | "version": "1.13.2",
594 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
595 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
596 | "requires": {
597 | "encodeurl": "~1.0.2",
598 | "escape-html": "~1.0.3",
599 | "parseurl": "~1.3.2",
600 | "send": "0.16.2"
601 | }
602 | },
603 | "setprototypeof": {
604 | "version": "1.1.0",
605 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
606 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
607 | },
608 | "source-map": {
609 | "version": "0.4.4",
610 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
611 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
612 | "requires": {
613 | "amdefine": ">=0.0.4"
614 | }
615 | },
616 | "statuses": {
617 | "version": "1.4.0",
618 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
619 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
620 | },
621 | "transformers": {
622 | "version": "2.1.0",
623 | "resolved": "https://registry.npmjs.org/transformers/-/transformers-2.1.0.tgz",
624 | "integrity": "sha1-XSPLNVYd2F3Gf7hIIwm0fVPM6ac=",
625 | "requires": {
626 | "css": "~1.0.8",
627 | "promise": "~2.0",
628 | "uglify-js": "~2.2.5"
629 | },
630 | "dependencies": {
631 | "is-promise": {
632 | "version": "1.0.1",
633 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-1.0.1.tgz",
634 | "integrity": "sha1-MVc3YcBX4zwukaq56W2gjO++duU="
635 | },
636 | "promise": {
637 | "version": "2.0.0",
638 | "resolved": "https://registry.npmjs.org/promise/-/promise-2.0.0.tgz",
639 | "integrity": "sha1-RmSKqdYFr10ucMMCS/WUNtoCuA4=",
640 | "requires": {
641 | "is-promise": "~1"
642 | }
643 | },
644 | "source-map": {
645 | "version": "0.1.43",
646 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
647 | "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
648 | "requires": {
649 | "amdefine": ">=0.0.4"
650 | }
651 | },
652 | "uglify-js": {
653 | "version": "2.2.5",
654 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.2.5.tgz",
655 | "integrity": "sha1-puAqcNg5eSuXgEiLe4sYTAlcmcc=",
656 | "requires": {
657 | "optimist": "~0.3.5",
658 | "source-map": "~0.1.7"
659 | }
660 | }
661 | }
662 | },
663 | "type-is": {
664 | "version": "1.6.18",
665 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
666 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
667 | "requires": {
668 | "media-typer": "0.3.0",
669 | "mime-types": "~2.1.24"
670 | }
671 | },
672 | "uglify-js": {
673 | "version": "2.8.29",
674 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
675 | "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
676 | "requires": {
677 | "source-map": "~0.5.1",
678 | "uglify-to-browserify": "~1.0.0",
679 | "yargs": "~3.10.0"
680 | },
681 | "dependencies": {
682 | "source-map": {
683 | "version": "0.5.7",
684 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
685 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
686 | }
687 | }
688 | },
689 | "uglify-to-browserify": {
690 | "version": "1.0.2",
691 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
692 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
693 | "optional": true
694 | },
695 | "unpipe": {
696 | "version": "1.0.0",
697 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
698 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
699 | },
700 | "utils-merge": {
701 | "version": "1.0.1",
702 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
703 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
704 | },
705 | "vary": {
706 | "version": "1.1.2",
707 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
708 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
709 | },
710 | "void-elements": {
711 | "version": "2.0.1",
712 | "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
713 | "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
714 | },
715 | "window-size": {
716 | "version": "0.1.0",
717 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
718 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
719 | },
720 | "with": {
721 | "version": "4.0.3",
722 | "resolved": "https://registry.npmjs.org/with/-/with-4.0.3.tgz",
723 | "integrity": "sha1-7v0VTp550sjTQXtkeo8U2f7M4U4=",
724 | "requires": {
725 | "acorn": "^1.0.1",
726 | "acorn-globals": "^1.0.3"
727 | },
728 | "dependencies": {
729 | "acorn": {
730 | "version": "1.2.2",
731 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz",
732 | "integrity": "sha1-yM4n3grMdtiW0rH6099YjZ6C8BQ="
733 | }
734 | }
735 | },
736 | "wordwrap": {
737 | "version": "0.0.3",
738 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
739 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
740 | },
741 | "yargs": {
742 | "version": "3.10.0",
743 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
744 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
745 | "requires": {
746 | "camelcase": "^1.0.2",
747 | "cliui": "^2.1.0",
748 | "decamelize": "^1.0.0",
749 | "window-size": "0.1.0"
750 | }
751 | }
752 | }
753 | }
754 |
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "container-1-node",
3 | "version": "0.0.0",
4 | "private": true,
5 | "scripts": {
6 | "start": "node ./bin/www"
7 | },
8 | "dependencies": {
9 | "axios": "^0.24.0",
10 | "cookie-parser": "~1.4.4",
11 | "debug": "~2.6.9",
12 | "express": "~4.16.1",
13 | "http-errors": "~1.6.3",
14 | "jade": "~1.11.0",
15 | "morgan": "~1.9.1"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/public/stylesheets/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 50px;
3 | font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
4 | }
5 |
6 | a {
7 | color: #00B7FF;
8 | }
9 |
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/routes/hello.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 | const axios = require('axios').default;
4 | const dotnetFQDN = process.env.DOTNET_FQDN;
5 |
6 | /* GET users listing. */
7 | router.get('/', async function(req, res, next) {
8 |
9 | if(dotnetFQDN != null) {
10 | // Even though we use the FQDN, because both containers are in the
11 | // same environment, traffic will not leave the environment.
12 | var data = await axios.get(`http://${dotnetFQDN}`);
13 | res.send(`${JSON.stringify(data.data)}`);
14 | }
15 | else {
16 | res.send('No DOTNET_FQDN env variable defined. Be sure to set an env variable for the dotnetApp FQDN')
17 | }
18 |
19 | });
20 |
21 | module.exports = router;
22 |
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/routes/index.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var router = express.Router();
3 |
4 | /* GET home page. */
5 | router.get('/', function(req, res, next) {
6 | res.render('index', { title: 'Container App Sample' });
7 | });
8 |
9 | module.exports = router;
10 |
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/views/error.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= message
5 | h2= error.status
6 | pre #{error.stack}
7 |
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/views/index.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | h1= title
5 | p Welcome to #{title}
6 |
7 | br
8 | form(action="/hello", method="get")
9 | input(type="submit", value="Say Hello to dotnetApp")
10 |
--------------------------------------------------------------------------------
/with-fqdn/container-1-node/views/layout.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title= title
5 | link(rel='stylesheet', href='/stylesheets/style.css')
6 | body
7 | block content
8 |
--------------------------------------------------------------------------------
/with-fqdn/container-2-dotnet/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1
2 | FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
3 | WORKDIR /app
4 |
5 | # Copy csproj and restore as distinct layers
6 | COPY *.csproj ./
7 | RUN dotnet restore
8 |
9 | # Copy everything else and build
10 | COPY . .
11 | RUN dotnet publish -c Release -o out
12 |
13 | # Build runtime image
14 | FROM mcr.microsoft.com/dotnet/aspnet:6.0
15 | WORKDIR /app
16 | COPY --from=build-env /app/out .
17 | ENTRYPOINT ["dotnet", "container-2-dotnet.dll"]
--------------------------------------------------------------------------------
/with-fqdn/container-2-dotnet/Program.cs:
--------------------------------------------------------------------------------
1 | var builder = WebApplication.CreateBuilder(args);
2 | var app = builder.Build();
3 |
4 | app.MapGet("/", () => "Hello from the .NET 6 container!");
5 |
6 | app.Run();
7 |
--------------------------------------------------------------------------------
/with-fqdn/container-2-dotnet/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "iisSettings": {
3 | "windowsAuthentication": false,
4 | "anonymousAuthentication": true,
5 | "iisExpress": {
6 | "applicationUrl": "http://localhost:3289",
7 | "sslPort": 44327
8 | }
9 | },
10 | "profiles": {
11 | "container_2_dotnet": {
12 | "commandName": "Project",
13 | "dotnetRunMessages": true,
14 | "launchBrowser": true,
15 | "applicationUrl": "https://localhost:7245;http://localhost:5230",
16 | "environmentVariables": {
17 | "ASPNETCORE_ENVIRONMENT": "Development"
18 | }
19 | },
20 | "IIS Express": {
21 | "commandName": "IISExpress",
22 | "launchBrowser": true,
23 | "environmentVariables": {
24 | "ASPNETCORE_ENVIRONMENT": "Development"
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/with-fqdn/container-2-dotnet/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/with-fqdn/container-2-dotnet/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "AllowedHosts": "*"
9 | }
10 |
--------------------------------------------------------------------------------
/with-fqdn/container-2-dotnet/container-2-dotnet.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net6.0
5 | enable
6 | enable
7 | container_2_dotnet
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/with-fqdn/deploy/container-app.bicep:
--------------------------------------------------------------------------------
1 | param containerAppName string
2 | param location string
3 | param environmentId string
4 | param containerImage string
5 | param containerPort int
6 | param isExternalIngress bool = false
7 | param containerRegistry string
8 | param containerRegistryUsername string
9 |
10 | param environmentVars array = []
11 |
12 | @secure()
13 | param containerRegistryPassword string
14 |
15 | resource containerApp 'Microsoft.App/containerApps@2022-01-01-preview' = {
16 | name: containerAppName
17 | location: location
18 | properties: {
19 | managedEnvironmentId: environmentId
20 | configuration: {
21 | secrets: [
22 | {
23 | name: 'registry-password'
24 | value: containerRegistryPassword
25 | }
26 | ]
27 | registries: [
28 | {
29 | server: containerRegistry
30 | username: containerRegistryUsername
31 | passwordSecretRef: 'registry-password'
32 | }
33 | ]
34 | ingress: {
35 | external: isExternalIngress
36 | targetPort: containerPort
37 | }
38 | }
39 | template: {
40 | containers: [
41 | {
42 | image: containerImage
43 | name: containerAppName
44 | env: environmentVars
45 | }
46 | ]
47 | scale: {
48 | minReplicas: 0
49 | }
50 | }
51 | }
52 | }
53 |
54 | output fqdn string = containerApp.properties.configuration.ingress.fqdn
55 |
--------------------------------------------------------------------------------
/with-fqdn/deploy/environment.bicep:
--------------------------------------------------------------------------------
1 | param location string
2 | param environmentName string
3 | param logAnalyticsWorkspaceName string = 'logs-${environmentName}'
4 |
5 | resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2020-03-01-preview' = {
6 | name: logAnalyticsWorkspaceName
7 | location: location
8 | properties: any({
9 | retentionInDays: 30
10 | features: {
11 | searchVersion: 1
12 | }
13 | sku: {
14 | name: 'PerGB2018'
15 | }
16 | })
17 | }
18 |
19 | resource environment 'Microsoft.App/managedEnvironments@2022-01-01-preview' = {
20 | name: environmentName
21 | location: location
22 | properties: {
23 | appLogsConfiguration: {
24 | destination: 'log-analytics'
25 | logAnalyticsConfiguration: {
26 | customerId: logAnalyticsWorkspace.properties.customerId
27 | sharedKey: logAnalyticsWorkspace.listKeys().primarySharedKey
28 | }
29 | }
30 | }
31 | }
32 |
33 | output environmentId string = environment.id
34 |
--------------------------------------------------------------------------------
/with-fqdn/deploy/main.bicep:
--------------------------------------------------------------------------------
1 | param location string = resourceGroup().location
2 | param environmentName string = 'sample-env'
3 | param nodeImage string
4 | param nodePort int
5 | param dotnetImage string
6 | param dotnetPort int
7 | param registry string
8 | param registryUsername string
9 | @secure()
10 | param registryPassword string
11 |
12 | // Container Apps Environment (environment.bicep)
13 | module environment 'environment.bicep' = {
14 | name: 'container-app-environment'
15 | params: {
16 | environmentName: environmentName
17 | location: location
18 | }
19 | }
20 |
21 |
22 | // Container-2-Dotnet (container-app.bicep)
23 | // We deploy it first so we can call it from the node-app
24 | module dotnetApp 'container-app.bicep' = {
25 | name: 'dotnetApp'
26 | params: {
27 | containerAppName: 'dotnet-app'
28 | location: location
29 | environmentId: environment.outputs.environmentId
30 | containerImage: dotnetImage
31 | containerPort: dotnetPort
32 | containerRegistry: registry
33 | containerRegistryUsername: registryUsername
34 | containerRegistryPassword: registryPassword
35 | isExternalIngress: false
36 | }
37 | }
38 |
39 |
40 | // Container-1-Node (container-app.bicep)
41 | module nodeApp 'container-app.bicep' = {
42 | name: 'nodeApp'
43 | params: {
44 | containerAppName: 'node-app'
45 | location: location
46 | environmentId: environment.outputs.environmentId
47 | containerImage: nodeImage
48 | containerPort: nodePort
49 | containerRegistry: registry
50 | containerRegistryUsername: registryUsername
51 | containerRegistryPassword: registryPassword
52 | isExternalIngress: true
53 | // set an environment var for the dotnetFQDN to call
54 | environmentVars: [
55 | {
56 | name: 'DOTNET_FQDN'
57 | value: dotnetApp.outputs.fqdn
58 | }
59 | ]
60 | }
61 | }
62 |
--------------------------------------------------------------------------------