# eShopOnContainers - Microservices Architecture and Containers based Reference Application (**BETA state** - Visual Studio 2017 and CLI environments compatible)
# eShopOnContainers - Microservices Architecture and Containers based Reference Application (**BETA state** - Visual Studio and CLI environments compatible)
Sample .NET Core reference application, powered by Microsoft, based on a simplified microservices architecture and Docker containers.
Sample .NET Core reference application, powered by Microsoft, based on a simplified microservices architecture and Docker containers.
[![Build status (Linux images)](https://msftdevtools.visualstudio.com/eShopOnContainers/_apis/build/status/All%20Microservices%20Linux)](https://msftdevtools.visualstudio.com/eShopOnContainers/_build/latest?definitionId=184)
## Linux Build Status for 'dev' branch
Dev branch contains the latest "stable" code, and their images are tagged with `:dev` in our [Docker Hub](https://cloud.docker.com/u/eshop/repository/list):
| Basket API | Catalog API | Identity API | Location API |
**You can use either the latest version of Visual Studio or simply Docker CLI and .NET CLI for Windows, Mac and Linux**.
**You can use either the latest version of Visual Studio or simply Docker CLI and .NET CLI for Windows, Mac and Linux**.
@ -63,6 +80,12 @@ The architecture proposes a microservice oriented architecture implementation wi
> <p> A similar case is defined in regard to Redis cache running as a container for the development environment. Or a No-SQL database (MongoDB) running as a container.
> <p> A similar case is defined in regard to Redis cache running as a container for the development environment. Or a No-SQL database (MongoDB) running as a container.
> <p> However, in a real production environment it is recommended to have your databases (SQL Server, Redis, and the NO-SQL database, in this case) in HA (High Available) services like Azure SQL Database, Redis as a service and Azure CosmosDB instead the MongoDB container (as both systems share the same access protocol). If you want to change to a production configuration, you'll just need to change the connection strings once you have set up the servers in an HA cloud or on-premises.
> <p> However, in a real production environment it is recommended to have your databases (SQL Server, Redis, and the NO-SQL database, in this case) in HA (High Available) services like Azure SQL Database, Redis as a service and Azure CosmosDB instead the MongoDB container (as both systems share the same access protocol). If you want to change to a production configuration, you'll just need to change the connection strings once you have set up the servers in an HA cloud or on-premises.
> ### Important Note on EventBus
> In this solution's current EventBus is a simplified implementation, mainly used for learning purposes (development and testing), so it doesn't handle all production scenarios, most notably on error handling. <p>
> The following forks provide production environment level implementation examples with eShopOnContainers :
> * Implementation with [CAP](https://github.com/dotnetcore/CAP) : https://github.com/yang-xiaodong/eShopOnContainers
> * Implementation with [NServiceBus](https://github.com/Particular/NServiceBus) : https://github.com/Particular/eShopOnContainers
## Related documentation and guidance
## Related documentation and guidance
While developing this reference application, we've been creating a reference <b>Guide/eBook</b> focusing on <b>architecting and developing containerized and microservice based .NET Applications</b> (download link available below) which explains in detail how to develop this kind of architectural style (microservices, Docker containers, Domain-Driven Design for certain microservices) plus other simpler architectural styles, like monolithic apps that can also live as Docker containers.
While developing this reference application, we've been creating a reference <b>Guide/eBook</b> focusing on <b>architecting and developing containerized and microservice based .NET Applications</b> (download link available below) which explains in detail how to develop this kind of architectural style (microservices, Docker containers, Domain-Driven Design for certain microservices) plus other simpler architectural styles, like monolithic apps that can also live as Docker containers.
<p>
<p>
@ -106,7 +129,7 @@ Finally, those microservices are consumed by multiple client web and mobile apps
<imgsrc="img/xamarin-mobile-App.png">
<imgsrc="img/xamarin-mobile-App.png">
## Setting up your development environment for eShopOnContainers
## Setting up your development environment for eShopOnContainers
### Visual Studio 2017 and Windows based
### Visual Studio 2017 (or above) and Windows based
This is the more straightforward way to get started:
This is the more straightforward way to get started:
This folder contains the Azure Devops build definitions in YAML format. Each folder contains one `azure-pipelines.yml` that contains the build definition for one microservice (usually a Docker image, but some microservices generates more than one Docker image).
For more information about YAML builds read the [Azure DevOps documentation](https://docs.microsoft.com/en-us/azure/devops/pipelines/get-started-yaml?view=azure-devops).
@ -8,7 +8,7 @@ The ARM template `sbusdeploy.json` and its parameter file (`sbusdeploy.parameter
## Editing sbusdeploy.parameters.json file
## Editing sbusdeploy.parameters.json file
You can edit the `sbusdeploy.parameters.parameters.json` file to set your values, but is not needed. The only parameter than can
You can edit the `sbusdeploy.parameters.json` file to set your values, but is not needed. The only parameter than can
be set is:
be set is:
1. `namespaceprefix` is a string that is used to create the namespace. ARM script creates unique values by appending a unique string to this parameter value, so you can leave the default value.
1. `namespaceprefix` is a string that is used to create the namespace. ARM script creates unique values by appending a unique string to this parameter value, so you can leave the default value.
@ -21,4 +21,4 @@ i. e. if you are in windows, to deploy servicebus in a new resourcegroup located
# An external IP or DNS name has to be used (instead localhost and the 10.0.75.1 IP) when testing the Web apps and the Xamarin apps from remote machines/devices using the same WiFi, for instance.
# An external IP or DNS name has to be used (instead localhost and the 10.0.75.1 IP) when testing the Web apps and the Xamarin apps from remote machines/devices using the same WiFi, for instance.
This article contains a brief introduction to centralized structured logging with [Serilog](https://serilog.net/) and event viewing with [ELK](https://www.elastic.co/elk-stack) in eShopOnContainers. ELK is an acronym of ElasticSearch, LogStash and Kibana. This is one of the most used tools in the industry standards.
![](img/elk/kibana-working.png)
## Wiring eshopOnContainers with ELK in Localhost
eshopOnContainers is ready for work with ELK, you only need to setup the configuration parameter **LogstashUrl**, in **Serilog** Section, for achieve this, you can do it modifing this parameter in every appsettings.json of every service, or via Environment Variable **Serilog:LogstashUrl**.
There is another option, a zero-configuration environment for testing the integration launching via ```docker-compose``` command, on the root directory of eshopOnContainers:
docker-compose -f docker-compose.yml -f docker-compose.override.yml -f docker-compose.elk.yml up
```
### Configuring Logstash index on Kibana
Once time you have started and configured your application, you only need to configure the logstash index on kibana.
You can address to Kibana, with docker-compose setup is at [http://localhost:5601](http://localhost:5601)
If you have accessed to kibana too early, you can see this error. It's normal, depending of your machine the kibana stack needs a bit of time to startup.
![](img/elk/kibana_startup.png)
You can wait a bit and refresh the page, the first time you enter, you need to configure and index pattern, in the ```docker-compose``` configuration, the index pattern name is **eshops-\***.
![](img/elk/kibana_eshops_index.png)
With the index pattern configured, you can enter in the discover section and start viewing how the tool is recollecting the logging information.
![](img/elk/kibana_result.png)
## Configuring ELK on Azure VM
Another option is to use a preconfigured virtual machine with Logstash, ElasticSearch and Kibana and point the configuration parameter **LogstashUrl**. For doing this you can address to Microsoft Azure, and start searching a Certified ELK Virtual Machine
![](img/elk/create-vm-elk-azure.png)
This options it have a certified preconfigured options (Network, VirtualMachine type, OS, RAM, Disks) for having a good starting point of ELK with good performance.
![](img/elk/create-vm-elk-azure-summary.png)
When you have configured the main aspects of your virtual machine, you will have a "review & create" last step like this:
![](img/elk/create-vm-elk-azure-last-step.png)
### Configuring the bitnami environment
This virtual machine has a lot of configuration pipeing done. If you want to change something of the default configuration you can address this documentation:
The only thing you have to change is the logstash configuration inside the machine. This configuration is at the file ```/opt/bitnami/logstash/conf/logstash.conf```
You must edit the file and overwrite with this configuration:
```conf
input {
http {
#default host 0.0.0.0:8080
codec => json
}
}
## Add your filters / logstash plugins configuration here
filter {
split {
field => "events"
target => "e"
remove_field => "events"
}
}
output {
elasticsearch {
hosts => "elasticsearch:9200"
index=>"eshops-%{+xxxx.ww}"
}
}
```
For doing this you can connect via ssh to the vm and edit the file using the vi editor for example.
When the file will be edited, check there are Inbound Port Rules created for the logstash service. You can do it going to Networking Menu on your ELK Virtual Machine Resource in Azure.
![](img/elk/azure-nsg-inboundportsConfig.png)
The only thing that remains is to connect to your vm vía browser. And check the bitnami splash page is showing.
![](img/elk/bitnami_splash.png)
You can get the password for accessing going to your virtual machine in azure and check the boot diagnostics, theres a message that shows to you which is your password.
When you have the user and password you can access to the kibana tool, and create the ```eshops-*``` index pattern that is well documented at the beggining of this documentation and then start to discover.
echo"#################### Begin AKS discovery based on the --dns aks setting. ####################"
if[[ -z $aks_name]]||[[ -z $aks_rg]];then
echo"Error: When using -dns aks, MUST set -aksName and -aksRg too."
echo''
usage
exit1
fi
echo"Getting DNS of AKS of AKS $aks_name (in resource group $aks_rg)"
dns="$(az aks show -n $aks_name -g $aks_rg --query addonProfiles.httpApplicationRouting.config.HTTPApplicationRoutingZoneName)"
if[[ -z dns ]];then
echo"Error: when getting DNS of AKS $aks_name (in resource group $aks_rg). Please ensure AKS has httpRouting enabled AND Azure CLI is logged in and is of version 2.0.37 or higher."
exit1
fi
$dns=${dns//[\"]/""}
echo"DNS base found is $dns. Will use $aks_name.$dns for the app!"
fi
# Initialization & check commands
if[[ -z $dns]];then
echo"No DNS specified. Ingress resources will be bound to public IP."
# Using Helm Charts to deploy eShopOnContainers to AKS with ISTIO
It is possible to deploy eShopOnContainers on a AKS using [Helm](https://helm.sh/) instead of custom scripts (that will be deprecated soon).
## Create Kubernetes cluster in AKS
You can create the AKS cluster by using two ways:
- A. Use Azure CLI: Follow a procedure suing [Azure CLI like here](https://docs.microsoft.com/en-us/azure/aks/kubernetes-walkthrough), but make sure you **enable RBAC** with `--enable-rbac` in `az aks create` command.
- B. Use Azure's portal
The following steps are using the Azure portal to create the AKS cluster:
- Start the process by providing the general data, like in the following screenshot:
In addition to having an AKS cluster created in Azure and having kubectl and Azure CLI installed in your local machine and configured to use your Azure subscription, you also need the following pre-requisites:
### Install Helm
You need to have helm installed on your machine, and Tiller must be installed on the AKS. Follow these instructions on how to ['Install applications with Helm in Azure Kubernetes Service (AKS)'](https://docs.microsoft.com/en-us/azure/aks/kubernetes-helm) to setup Helm and Tiller for AKS.
**Note**: If your ASK cluster is not RBAC-enabled (default option in portal) you may receive following error when running a helm command:
```
Error: Get http://localhost:8080/api/v1/namespaces/kube-system/configmaps?labelSelector=OWNER%!D(MISSING)TILLER: dial tcp [::1]:8080: connect: connection refused
Your default text editor will popup with the YAML definition of the tiller deploy. Search for:
```
automountServiceAccountToken: false
```
And change it to:
```
automountServiceAccountToken: true
```
Save the file and close the editor. This should reapply the deployment in the cluster. Now Helm commands should work.
## Install eShopOnContainers with Istio using Helm
All steps need to be performed on `/k8s/helm` folder. The easiest way is to use the `deploy-all-istio.ps1` script from a Powershell window:
```
.\deploy-all-istio.ps1 -dnsname eshoptestistio -externalDns aks -aksName eshoptest -aksRg eshoptest -imageTag dev
```
This will install all the [eShopOnContainers public images](https://hub.docker.com/u/eshop/) with tag `dev` on the AKS named `eshoptest` in the resource group `eshoptest` and with the dns url: http://**eshoptestistio**.westus.cloudapp.azure.com/ . By default all infrastructure (sql, mongo, rabbit and redis) is installed also in the cluster.
Once the script is run, you should see following output when using `kubectl get deployment`:
```
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
eshop-apigwmm 1 1 1 1 4d
eshop-apigwms 1 1 1 1 4d
eshop-apigwwm 1 1 1 1 4d
eshop-apigwws 1 1 1 1 4d
eshop-basket-api 1 1 1 1 4d
eshop-basket-data 1 1 1 1 4d
eshop-catalog-api 1 1 1 1 4d
eshop-identity-api 1 1 1 1 4d
eshop-keystore-data 1 1 1 1 4d
eshop-locations-api 1 1 1 1 4d
eshop-marketing-api 1 1 1 1 4d
eshop-mobileshoppingagg 1 1 1 1 4d
eshop-nosql-data 1 1 1 1 4d
eshop-ordering-api 1 1 1 1 4d
eshop-ordering-backgroundtasks 1 1 1 1 4d
eshop-ordering-signalrhub 1 1 1 1 4d
eshop-payment-api 1 1 1 1 4d
eshop-rabbitmq 1 1 1 1 4d
eshop-sql-data 1 1 1 1 4d
eshop-webmvc 1 1 1 1 4d
eshop-webshoppingagg 1 1 1 1 4d
eshop-webspa 1 1 1 1 4d
eshop-webstatus 1 1 1 1 4d
```
Every public service is exposed through the istio ingress gateway.
Yo can see the ingress gateway public ip doing `kubectl get services -n istio-system`
To use your own images instead of the public ones, you have to pass following additional parameters to the `deploy-all-istio.ps1` script:
* `registry`: Login server for the Docker registry
* `dockerUser`: User login for the Docker registry
* `dockerPassword`: User password for the Docker registry
This will deploy a secret on the cluster to connect to the specified server, and all image names deployed will be prepended with `registry/` value.
### Not deploying infrastructure containers
If you want to use external resources, use `-deployInfrastructure $false` to not deploy infrastructure containers. However **you still have to manually update the scripts to provide your own configuration** (see next section).
### Providing your own configuration
The file `inf.yaml` contains the description of the infrastructure used. File is docummented so take a look on it to understand all of its entries. If using external resources you need to edit this file according to your needs. You'll need to edit:
* `inf.sql.host` with the host name of the SQL Server
* `inf.sql.common` entries to provide your SQL user, password. `Pid` is not used when using external resources (it is used to set specific product id for the SQL Server container).
* `inf.sql.catalog`, `inf.sql.ordering`, `inf.sql.identity`: To provide the database names for catalog, ordering and identity services
* `mongo.host`: With the host name of the Mongo DB
* `mongo.locations`, `mongo.marketing` with the database names for locations and marketing services
* `redis.basket.constr` with the connection string to Redis for Basket Service. Note that `redis.basket.svc` is not used when using external services
* `redis.keystore.constr` with the connection string to Redis for Keystore Service. Note that `redis.keystore.svc` is not used when using external services
* `eventbus.constr` with the connection string to Azure Service Bus and `eventbus.useAzure` to `true` to use Azure service bus. Note that `eventbus.svc` is not used when using external services
### Using Azure storage for Catalog Photos
Using Azure storage for catalog (and marketing) photos is not directly supported, but you can accomplish it by editing the file `k8s/helm/catalog-api/templates/configmap.yaml`. Search for lines:
In the same way, to use Azure storage for the marketing service, have to edit the file `k8s/helm/marketing-api/templates/configmap.yaml` and replacing the line:
# Using Helm Charts to deploy eShopOnContainers to a local Kubernetes in Windows with 'Docker for Windows'
## Additional pre-requisites
In addition to having Docker for Windows/Mac with Kubernetes enabled and having kubectl ayou also need the following pre-requisites:
### Install Helm
You need to have helm installed on your machine, and Tiller must be installed on the local Docker Kubernetes cluster. Once you have [Helm downloaded](https://helm.sh/) and installed on your machine you must:
1. Create the tiller service account, by running `kubectl apply -f helm-rbac.yaml` from `/k8s` folder
2. Install tiller and configure it to use the tiller service account by typing `helm init --service-account tiller`
## Install eShopOnContainers with Istio using Helm
All steps need to be performed on `/k8s/helm` folder. The easiest way is to use the `deploy-all-istio.ps1` script from a Powershell window:
```
.\deploy-all-istio.ps1 -imageTag dev -useLocalk8s $true
```
The parameter `useLocalk8s` to $true, forces the script to use `localhost` as the DNS for all Helm charts.
This will install all the [eShopOnContainers public images](https://hub.docker.com/u/eshop/) with tag `dev` on the Docker local Kubernetes cluster. By default all infrastructure (sql, mongo, rabbit and redis) is installed also in the cluster.
Once the script is run, you should see following output when using `kubectl get deployment`:
```
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
eshop-apigwmm 1 1 1 1 2h
eshop-apigwms 1 1 1 1 2h
eshop-apigwwm 1 1 1 1 2h
eshop-apigwws 1 1 1 1 2h
eshop-basket-api 1 1 1 1 2h
eshop-basket-data 1 1 1 1 2h
eshop-catalog-api 1 1 1 1 2h
eshop-identity-api 1 1 1 1 2h
eshop-keystore-data 1 1 1 1 2h
eshop-locations-api 1 1 1 1 2h
eshop-marketing-api 1 1 1 1 2h
eshop-mobileshoppingagg 1 1 1 1 2h
eshop-nosql-data 1 1 1 1 2h
eshop-ordering-api 1 1 1 1 2h
eshop-ordering-backgroundtasks 1 1 1 1 2h
eshop-ordering-signalrhub 1 1 1 1 2h
eshop-payment-api 1 1 1 1 2h
eshop-rabbitmq 1 1 1 1 2h
eshop-sql-data 1 1 1 1 2h
eshop-webmvc 1 1 1 1 2h
eshop-webshoppingagg 1 1 1 1 2h
eshop-webspa 1 1 1 1 2h
eshop-webstatus 1 1 1 1 2h
```
Note that istio ingress gateway is bound to DNS localhost and the host is also "localhost". So, you can access the webspa by typing `http://localhost` and the MVC by typing `http://localhost/`
As this is the Docker local K8s cluster, you can see also the containers running on your machine. If you type `docker ps` you'll see all them:
```
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fec1e3499416 a3f21ec4bd11 "/entrypoint.sh /ngi…" 9 minutes ago Up 9 minutes k8s_nginx-ingress-controller_nginx-ingress-controller-f88c75bc6-5xs2n_ingress-nginx_f1cc7094-e68f-11e8-b4b6-00155d016146_0
76485867f032 eshop/payment.api "dotnet Payment.API.…" 2 hours ago Up 2 hours k8s_payment-api_eshop-payment-api-75d5f9bdf6-6zx2v_default_4a3cdab4-e67f-11e8-b4b6-00155d016146_1
c2c4640ed610 eshop/marketing.api "dotnet Marketing.AP…" 2 hours ago Up 2 hours k8s_marketing-api_eshop-marketing-api-6b8c5989fd-jpxqv_default_45780626-e67f-11e8-b4b6-00155d016146_1
85301d538574 eshop/ordering.signalrhub "dotnet Ordering.Sig…" 2 hours ago Up 2 hours k8s_ordering-signalrhub_eshop-ordering-signalrhub-58cf5ff6-cnlm8_default_4932c344-e67f-11e8-b4b6-00155d016146_1
7a408a98000e eshop/ordering.backgroundtasks "dotnet Ordering.Bac…" 2 hours ago Up 2 hours k8s_ordering-backgroundtasks_eshop-ordering-backgroundtasks-cc8f6d4d8-ztfk7_default_47f9cf10-e67f-11e8-b4b6-00155d016146_1
12c64b3a13e0 eshop/basket.api "dotnet Basket.API.d…" 2 hours ago Up 2 hours k8s_basket-api_eshop-basket-api-658546684d-6hlvd_default_4262d022-e67f-11e8-b4b6-00155d016146_1
133fccfeeff3 eshop/webstatus "dotnet WebStatus.dll" 2 hours ago Up 2 hours k8s_webstatus_eshop-webstatus-7f46479dc4-bqnq7_default_4dc13eb2-e67f-11e8-b4b6-00155d016146_0
00c6e4c52135 eshop/webspa "dotnet WebSPA.dll" 2 hours ago Up 2 hours k8s_webspa_eshop-webspa-64cb8df9cb-dcbwg_default_4cd47376-e67f-11e8-b4b6-00155d016146_0
d4507f1f6b1a eshop/webshoppingagg "dotnet Web.Shopping…" 2 hours ago Up 2 hours k8s_webshoppingagg_eshop-webshoppingagg-cc94fc86-sxd2v_default_4be6cdb9-e67f-11e8-b4b6-00155d016146_0
9178e26703da eshop/webmvc "dotnet WebMVC.dll" 2 hours ago Up 2 hours k8s_webmvc_eshop-webmvc-985779684-4br5z_default_4addd4d6-e67f-11e8-b4b6-00155d016146_0
1088c281c710 eshop/ordering.api "dotnet Ordering.API…" 2 hours ago Up 2 hours k8s_ordering-api_eshop-ordering-api-fb8c548cb-k68x9_default_4740958a-e67f-11e8-b4b6-00155d016146_0
12424156d5c9 eshop/mobileshoppingagg "dotnet Mobile.Shopp…" 2 hours ago Up 2 hours k8s_mobileshoppingagg_eshop-mobileshoppingagg-b54645d7b-rlrgh_default_46c00017-e67f-11e8-b4b6-00155d016146_0
65463ffd437d eshop/locations.api "dotnet Locations.AP…" 2 hours ago Up 2 hours k8s_locations-api_eshop-locations-api-577fc94696-dfhq8_default_44929c4b-e67f-11e8-b4b6-00155d016146_0
5b3431873763 eshop/identity.api "dotnet Identity.API…" 2 hours ago Up 2 hours k8s_identity-api_eshop-identity-api-85d9b79f4-s5ks7_default_43d6eb7c-e67f-11e8-b4b6-00155d016146_0
7c8e77252459 eshop/catalog.api "dotnet Catalog.API.…" 2 hours ago Up 2 hours k8s_catalog-api_eshop-catalog-api-59fd444fb-ztvhz_default_4356705a-e67f-11e8-b4b6-00155d016146_0
94d95d0d3653 eshop/ocelotapigw "dotnet OcelotApiGw.…" 2 hours ago Up 2 hours k8s_apigwws_eshop-apigwws-65474b979d-n99jw_default_41395473-e67f-11e8-b4b6-00155d016146_0
bc4bbce71d5f eshop/ocelotapigw "dotnet OcelotApiGw.…" 2 hours ago Up 2 hours k8s_apigwwm_eshop-apigwwm-857c549dd8-8w5gv_default_4098d770-e67f-11e8-b4b6-00155d016146_0
840aabcceaa9 eshop/ocelotapigw "dotnet OcelotApiGw.…" 2 hours ago Up 2 hours k8s_apigwms_eshop-apigwms-5b94dfb54b-dnmr9_default_401fc611-e67f-11e8-b4b6-00155d016146_0
aabed7646f5b eshop/ocelotapigw "dotnet OcelotApiGw.…" 2 hours ago Up 2 hours k8s_apigwmm_eshop-apigwmm-85f96cbdb4-dhfwr_default_3ed7967a-e67f-11e8-b4b6-00155d016146_0
49c5700def5a f06a5773f01e "docker-entrypoint.s…" 2 hours ago Up 2 hours k8s_basket-data_eshop-basket-data-66fbc788cc-csnlw_default_3e0c45fe-e67f-11e8-b4b6-00155d016146_0
a5db4c521807 f06a5773f01e "docker-entrypoint.s…" 2 hours ago Up 2 hours k8s_keystore-data_eshop-keystore-data-5c9c85cb99-8k56s_default_3ce1a273-e67f-11e8-b4b6-00155d016146_0
aae88fd2d810 d69a5113ceae "docker-entrypoint.s…" 2 hours ago Up 2 hours k8s_rabbitmq_eshop-rabbitmq-6b68647bc4-gr565_default_3c37ee6a-e67f-11e8-b4b6-00155d016146_0
65d49ca9589d bbed8d0e01c1 "docker-entrypoint.s…" 2 hours ago Up 2 hours k8s_nosql-data_eshop-nosql-data-579c9d89f8-mtt95_default_3b9c1f89-e67f-11e8-b4b6-00155d016146_0
090e0dde2ec4 bbe2822dfe38 "/opt/mssql/bin/sqls…" 2 hours ago Up 2 hours k8s_sql-data_eshop-sql-data-5c4fdcccf4-bscdb_default_3afd29b8-e67f-11e8-b4b6-00155d016146_0
```
## Known issues
Login from the webmvc results in following error: HttpRequestException: Response status code does not indicate success: 404 (Not Found).
The reason is because MVC needs to access the Identity Server from both outside the container (browser) and inside the container (C# code). Thus, the configuration uses always the *external url* of the Identity Server, which in this case is just `http://localhost/identity-api`. But this external url is incorrect when used from C# code, and the web mvc can't access the identity api. This is the only case when this issue happens (and is the reason why we use 10.0.75.1 for local address in web mvc in local development mode)
Solving this requires some manual steps:
Update the configmap of Web MVC by typing (**line breaks are mandatory**) and your cluster dns name has to be the same of your environment:
```
kubectl patch cm cfg-eshop-webmvc --type strategic --patch @'