scripts to build individual services, readme files for all services and clients, compose in all projects, fix build problems (Dependent seeds), solve some kwnon build problems in solution (identity on localhost, ...)
56
README.md
@ -1,3 +1,57 @@
|
||||
# Containerized eShop
|
||||
Sample reference containerized application, cross-platform and microservices architecture.
|
||||
Powered by .NET Core, Docker and Docker Swarm mode
|
||||
Powered by Microsoft
|
||||
|
||||
<img src="img/eshop_cover.png">
|
||||
|
||||
#Overview
|
||||
In this repo you will fin samples that will help you to get introduced into <b>.net core</b>, microservices environment and <b>docker</b>.
|
||||
|
||||
|
||||
#Tools
|
||||
#### Windows
|
||||
<a href='https://github.com/docker/toolbox/releases/download/v1.12.3/DockerToolbox-1.12.3.exe'>Docker tools for windows</a>
|
||||
|
||||
####Mac
|
||||
<a href='https://github.com/docker/toolbox/releases/download/v1.12.3/DockerToolbox-1.12.3.pkg'>Docker tools for Mac</a>
|
||||
|
||||
##Set up Cpu and Memory
|
||||
In this demo we will run 3 instances of SQL Server, 6 asp.net core applications and 1 redis server it's important to set up properly the Cpu and Ram assigned to docker. This can be set, once installed docker in your device through the whale icon, right click, settings and in the Advanced option you will need to adjust the default to the new values shown in the image:
|
||||
|
||||
<img src="img/docker_settings.png">
|
||||
|
||||
#Demo
|
||||
The demo scenario is based on a ecommerce shop, each service is a .net core web application (basket, catalog, ordering, identity) and this services are consumed by differents web and mobile applications.
|
||||
|
||||
MVC Application: Its an Mvc 6 development where you can find good samples about how to work with microservices in a MVC asp.net core application.
|
||||
|
||||
SPA Application: Developed with Angular2, Typescript and Mvc 6, is another different aproach in web on how to work in a Microservices oriented solution.
|
||||
|
||||
Xamarin Application (Ios, Windows, Android): Its a client application that run in mobile devices (ios, android, windows) and you can find another example on how to build a microservices oriented application.
|
||||
|
||||
#Deploy goblal
|
||||
In the global directory you will find the scripts needed to run and deploy the demo into your local docker infraestructure. The steps:
|
||||
|
||||
|
||||
- <a href='build-images.ps1'>build-images.ps1</a> <b>Build .net applications and docker images</b>: This power shell script that you will find in the <u>root directory of the solution</u> is the responsible of building .net applications and package in a pub folder and use docker commands to build the images needed to run the previously packaged .net applications.
|
||||
|
||||
- <b>Compose containers in your docker local VM</b>: Finally you have to open your favourite command tool <u>pointing to the root directory of the solution</u> where docker-compose.yml file is located and run the command `docker-compose up`
|
||||
|
||||
#Run
|
||||
Once the deploy process of docker-compose finishes you have to be able to access the services in this urls from your machine:
|
||||
- Web: http://localhost:5100
|
||||
- Web Spa: http://localhost:5104
|
||||
- Catalog service: http://localhost:5101
|
||||
- Orders service: http://localhost:5102
|
||||
- Basket service: http://localhost:5103
|
||||
- Identity service: http://localhost:5105
|
||||
- Orders data (SQL Server): Server=tcp:localhost,5432;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;
|
||||
- Catalog data (SQL Server): Server=tcp:localhost,5434;Database=CatalogDB;User Id=sa;Password=Pass@word
|
||||
- Identity data (SQL Server): Server=localhost,5433;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
- Basket data (Redis): listening in localhost:6379
|
||||
|
||||
#Deploy individiual services into docker
|
||||
Under each project root you will find a readme.md file as this that describes how to run and deploy the service individually into a docker container.
|
||||
|
||||
|
||||
|
||||
|
19
add-host-entry.ps1
Normal file
@ -0,0 +1,19 @@
|
||||
param([switch]$Elevated)
|
||||
function Check-Admin {
|
||||
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
|
||||
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
|
||||
}
|
||||
if ((Check-Admin) -eq $false) {
|
||||
if ($elevated)
|
||||
{
|
||||
# could not elevate, quit
|
||||
}
|
||||
|
||||
else {
|
||||
|
||||
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -noexit -file "{0}" -elevated' -f ($myinvocation.MyCommand.Definition))
|
||||
}
|
||||
exit
|
||||
}
|
||||
|
||||
ac -Encoding UTF8 C:\Windows\system32\drivers\etc\hosts "127.0.0.1 identity.service"
|
16
build-image-service-basket.ps1
Normal file
@ -0,0 +1,16 @@
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
|
||||
Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow
|
||||
|
||||
#*** Basket service image ***
|
||||
$basketPathToJson = $scriptPath + "\src\Services\Basket\Basket.API\project.json"
|
||||
Write-Host "basketPathToJson is $basketPathToJson" -ForegroundColor Yellow
|
||||
$basketPathToPub = $scriptPath + "\pub\basket"
|
||||
Write-Host "basketPathToPub is $basketPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $basketPathToJson
|
||||
dotnet build $basketPathToJson
|
||||
dotnet publish $basketPathToJson -o $basketPathToPub
|
||||
|
||||
docker build -t eshop/basket.api $basketPathToPub
|
16
build-image-service-catalog.ps1
Normal file
@ -0,0 +1,16 @@
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
|
||||
Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow
|
||||
|
||||
#*** Catalog service image ***
|
||||
$catalogPathToJson = $scriptPath + "\src\Services\Catalog\Catalog.API\project.json"
|
||||
Write-Host "catalogPathToJson is $catalogPathToJson" -ForegroundColor Yellow
|
||||
$catalogPathToPub = $scriptPath + "\pub\catalog"
|
||||
Write-Host "catalogPathToPub is $catalogPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $catalogPathToJson
|
||||
dotnet build $catalogPathToJson
|
||||
dotnet publish $catalogPathToJson -o $catalogPathToPub
|
||||
|
||||
docker build -t eshop/catalog.api $catalogPathToPub
|
16
build-image-service-identity.ps1
Normal file
@ -0,0 +1,16 @@
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
|
||||
Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow
|
||||
|
||||
# *** identitySvc image ***
|
||||
$identitySvcPathToJson = $scriptPath + "\src\Services\Identity\eShopOnContainers.Identity\project.json"
|
||||
Write-Host "identitySvcPathToJson is $identitySvcPathToJson" -ForegroundColor Yellow
|
||||
$identitySvcPathToPub = $scriptPath + "\pub\identity"
|
||||
Write-Host "identitySvcPathToPub is $identitySvcPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $identitySvcPathToJson
|
||||
dotnet build $identitySvcPathToJson
|
||||
dotnet publish $identitySvcPathToJson -o $identitySvcPathToPub
|
||||
|
||||
docker build -t eshop/identity $identitySvcPathToPub
|
16
build-image-service-orders.ps1
Normal file
@ -0,0 +1,16 @@
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
|
||||
Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow
|
||||
|
||||
#*** Ordering service image ***
|
||||
$orderingPathToJson = $scriptPath + "\src\Services\Ordering\Ordering.API\project.json"
|
||||
Write-Host "orderingPathToJson is $orderingPathToJson" -ForegroundColor Yellow
|
||||
$orderingPathToPub = $scriptPath + "\pub\ordering"
|
||||
Write-Host "orderingPathToPub is $orderingPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $orderingPathToJson
|
||||
dotnet build $orderingPathToJson
|
||||
dotnet publish $orderingPathToJson -o $orderingPathToPub
|
||||
|
||||
docker build -t eshop/ordering.api $orderingPathToPub
|
77
build-image-web-spa.ps1
Normal file
@ -0,0 +1,77 @@
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
|
||||
Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow
|
||||
|
||||
$pubFolderToDelete = $scriptPath + "\pub"
|
||||
remove-item -path $pubFolderToDelete -Force -Recurse -ErrorAction SilentlyContinue
|
||||
|
||||
# *** WebSPA image ***
|
||||
$webSPAPathToJson = $scriptPath + "\src\Web\WebSPA\eShopOnContainers.WebSPA\project.json"
|
||||
Write-Host "webSPAPathToJson is $webSPAPathToJson" -ForegroundColor Yellow
|
||||
$webSPAPathToPub = $scriptPath + "\pub\webSPA"
|
||||
$webSPAPathToNpmBat = $scriptPath + "\src\Web\WebSPA\eShopOnContainers.WebSPA\buildspa.bat"
|
||||
Write-Host "webSPAPathToPub is $webSPAPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $webSPAPathToJson
|
||||
dotnet build $webSPAPathToJson
|
||||
# Start-Process "cmd.exe" "/c " + $webSPAPathToNpmBat
|
||||
dotnet publish $webSPAPathToJson -o $webSPAPathToPub
|
||||
|
||||
# *** identitySvc image ***
|
||||
$identitySvcPathToJson = $scriptPath + "\src\Services\Identity\eShopOnContainers.Identity\project.json"
|
||||
Write-Host "identitySvcPathToJson is $identitySvcPathToJson" -ForegroundColor Yellow
|
||||
$identitySvcPathToPub = $scriptPath + "\pub\identity"
|
||||
Write-Host "identitySvcPathToPub is $identitySvcPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $identitySvcPathToJson
|
||||
dotnet build $identitySvcPathToJson
|
||||
dotnet publish $identitySvcPathToJson -o $identitySvcPathToPub
|
||||
|
||||
|
||||
#*** Catalog service image ***
|
||||
$catalogPathToJson = $scriptPath + "\src\Services\Catalog\Catalog.API\project.json"
|
||||
Write-Host "catalogPathToJson is $catalogPathToJson" -ForegroundColor Yellow
|
||||
$catalogPathToPub = $scriptPath + "\pub\catalog"
|
||||
Write-Host "catalogPathToPub is $catalogPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $catalogPathToJson
|
||||
dotnet build $catalogPathToJson
|
||||
dotnet publish $catalogPathToJson -o $catalogPathToPub
|
||||
|
||||
#*** Ordering service image ***
|
||||
$orderingPathToJson = $scriptPath + "\src\Services\Ordering\Ordering.API\project.json"
|
||||
Write-Host "orderingPathToJson is $orderingPathToJson" -ForegroundColor Yellow
|
||||
$orderingPathToPub = $scriptPath + "\pub\ordering"
|
||||
Write-Host "orderingPathToPub is $orderingPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $orderingPathToJson
|
||||
dotnet build $orderingPathToJson
|
||||
dotnet publish $orderingPathToJson -o $orderingPathToPub
|
||||
|
||||
#*** Basket service image ***
|
||||
$basketPathToJson = $scriptPath + "\src\Services\Basket\Basket.API\project.json"
|
||||
Write-Host "basketPathToJson is $basketPathToJson" -ForegroundColor Yellow
|
||||
$basketPathToPub = $scriptPath + "\pub\basket"
|
||||
Write-Host "basketPathToPub is $basketPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $basketPathToJson
|
||||
dotnet build $basketPathToJson
|
||||
dotnet publish $basketPathToJson -o $basketPathToPub
|
||||
|
||||
#!/bin/bash
|
||||
# Delete all containers
|
||||
docker rm $(docker ps -a -q) -f
|
||||
# Delete all images
|
||||
docker rmi $(docker images -q)
|
||||
|
||||
#*** build docker images ***
|
||||
docker build -t eshop/catalog.api $catalogPathToPub
|
||||
docker build -t eshop/ordering.api $orderingPathToPub
|
||||
docker build -t eshop/basket.api $basketPathToPub
|
||||
docker build -t eshop/webspa $webSPAPathToPub
|
||||
docker build -t eshop/identity $identitySvcPathToPub
|
75
build-image-web.ps1
Normal file
@ -0,0 +1,75 @@
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
|
||||
Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow
|
||||
|
||||
$pubFolderToDelete = $scriptPath + "..\..\pub"
|
||||
remove-item -path $pubFolderToDelete -Force -Recurse -ErrorAction SilentlyContinue
|
||||
#cmd /c "rd /s pub" /q
|
||||
|
||||
# *** WebMVC image ***
|
||||
$webPathToJson = $scriptPath + "\src\Web\WebMVC\project.json"
|
||||
Write-Host "webPathToJson is $webPathToJson" -ForegroundColor Yellow
|
||||
$webPathToPub = $scriptPath + "\pub\webMVC"
|
||||
Write-Host "webPathToPub is $webPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $webPathToJson
|
||||
dotnet build $webPathToJson
|
||||
dotnet publish $webPathToJson -o $webPathToPub
|
||||
|
||||
# *** identitySvc image ***
|
||||
$identitySvcPathToJson = $scriptPath + "\src\Services\Identity\eShopOnContainers.Identity\project.json"
|
||||
Write-Host "identitySvcPathToJson is $identitySvcPathToJson" -ForegroundColor Yellow
|
||||
$identitySvcPathToPub = $scriptPath + "\pub\identity"
|
||||
Write-Host "identitySvcPathToPub is $identitySvcPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $identitySvcPathToJson
|
||||
dotnet build $identitySvcPathToJson
|
||||
dotnet publish $identitySvcPathToJson -o $identitySvcPathToPub
|
||||
|
||||
#*** Catalog service image ***
|
||||
$catalogPathToJson = $scriptPath + "\src\Services\Catalog\Catalog.API\project.json"
|
||||
Write-Host "catalogPathToJson is $catalogPathToJson" -ForegroundColor Yellow
|
||||
$catalogPathToPub = $scriptPath + "\pub\catalog"
|
||||
Write-Host "catalogPathToPub is $catalogPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $catalogPathToJson
|
||||
dotnet build $catalogPathToJson
|
||||
dotnet publish $catalogPathToJson -o $catalogPathToPub
|
||||
|
||||
#*** Ordering service image ***
|
||||
$orderingPathToJson = $scriptPath + "\src\Services\Ordering\Ordering.API\project.json"
|
||||
Write-Host "orderingPathToJson is $orderingPathToJson" -ForegroundColor Yellow
|
||||
$orderingPathToPub = $scriptPath + "\pub\ordering"
|
||||
Write-Host "orderingPathToPub is $orderingPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $orderingPathToJson
|
||||
dotnet build $orderingPathToJson
|
||||
dotnet publish $orderingPathToJson -o $orderingPathToPub
|
||||
|
||||
#*** Basket service image ***
|
||||
$basketPathToJson = $scriptPath + "\src\Services\Basket\Basket.API\project.json"
|
||||
Write-Host "basketPathToJson is $basketPathToJson" -ForegroundColor Yellow
|
||||
$basketPathToPub = $scriptPath + "\pub\basket"
|
||||
Write-Host "basketPathToPub is $basketPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $basketPathToJson
|
||||
dotnet build $basketPathToJson
|
||||
dotnet publish $basketPathToJson -o $basketPathToPub
|
||||
|
||||
#!/bin/bash
|
||||
# Delete all containers
|
||||
docker rm $(docker ps -a -q) -f
|
||||
# Delete all images
|
||||
docker rmi $(docker images -q)
|
||||
|
||||
#*** build docker images ***
|
||||
docker build -t eshop/web $webPathToPub
|
||||
docker build -t eshop/catalog.api $catalogPathToPub
|
||||
docker build -t eshop/ordering.api $orderingPathToPub
|
||||
docker build -t eshop/basket.api $basketPathToPub
|
||||
docker build -t eshop/identity $identitySvcPathToPub
|
@ -1,11 +1,9 @@
|
||||
|
||||
$scriptPath = Split-Path $script:MyInvocation.MyCommand.Path
|
||||
|
||||
Write-Host "Current script directory is $scriptPath" -ForegroundColor Yellow
|
||||
|
||||
$pubFolderToDelete = $scriptPath + "\pub"
|
||||
remove-item -path $pubFolderToDelete -Force -Recurse -ErrorAction SilentlyContinue
|
||||
#cmd /c "rd /s pub" /q
|
||||
|
||||
# *** WebMVC image ***
|
||||
$webPathToJson = $scriptPath + "\src\Web\WebMVC\project.json"
|
||||
@ -18,17 +16,18 @@ dotnet restore $webPathToJson
|
||||
dotnet build $webPathToJson
|
||||
dotnet publish $webPathToJson -o $webPathToPub
|
||||
|
||||
|
||||
# *** WebSPA image ***
|
||||
$webSPAPathToJson = $scriptPath + "\src\Web\WebSPA\eShopOnContainers.WebSPA\project.json"
|
||||
Write-Host "webSPAPathToJson is $webSPAPathToJson" -ForegroundColor Yellow
|
||||
$webSPAPathToPub = $scriptPath + "\pub\webSPA"
|
||||
#$webSPAPathToNpmBat = $scriptPath + "\src\Web\WebSPA\eShopOnContainers.WebSPA\buildspa.bat"
|
||||
$webSPAPathToNpmBat = $scriptPath + "\src\Web\WebSPA\eShopOnContainers.WebSPA\buildspa.bat"
|
||||
Write-Host "webSPAPathToPub is $webSPAPathToPub" -ForegroundColor Yellow
|
||||
|
||||
Write-Host "Restore Dependencies just in case as it is needed to run dotnet publish" -ForegroundColor Blue
|
||||
dotnet restore $webSPAPathToJson
|
||||
dotnet build $webSPAPathToJson
|
||||
#Start-Process "cmd.exe" "/c " + $webSPAPathToNpmBat
|
||||
# Start-Process "cmd.exe" "/c " + $webSPAPathToNpmBat
|
||||
dotnet publish $webSPAPathToJson -o $webSPAPathToPub
|
||||
|
||||
# *** identitySvc image ***
|
||||
@ -76,6 +75,12 @@ dotnet restore $basketPathToJson
|
||||
dotnet build $basketPathToJson
|
||||
dotnet publish $basketPathToJson -o $basketPathToPub
|
||||
|
||||
#!/bin/bash
|
||||
# Delete all containers
|
||||
docker rm $(docker ps -a -q) -f
|
||||
# Delete all images
|
||||
docker rmi $(docker images -q)
|
||||
|
||||
#*** build docker images ***
|
||||
docker build -t eshop/web $webPathToPub
|
||||
docker build -t eshop/catalog.api $catalogPathToPub
|
||||
|
@ -2,17 +2,18 @@ version: '2'
|
||||
|
||||
services:
|
||||
webmvc:
|
||||
image: eshop/web${TAG}
|
||||
image: eshop/web
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
environment:
|
||||
- CatalogUrl=http://catalog.api
|
||||
- OrderingUrl=http://ordering.api
|
||||
- IdentityUrl=http://identity.service
|
||||
#- IdentityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105.
|
||||
- IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
- BasketUrl=http://basket.api
|
||||
ports:
|
||||
- "5100:80"
|
||||
- "5100:5100"
|
||||
depends_on:
|
||||
- identity.service
|
||||
- basket.api
|
||||
@ -25,7 +26,8 @@ services:
|
||||
environment:
|
||||
- CatalogUrl=http://catalog.api
|
||||
- OrderingUrl=http://ordering.api
|
||||
- IdentityUrl=http://identity.service
|
||||
#- IdentityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105.
|
||||
- IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
- BasketUrl=http://basket.api
|
||||
ports:
|
||||
- "5104:80"
|
||||
@ -33,12 +35,48 @@ services:
|
||||
- basket.api
|
||||
- identity.service
|
||||
|
||||
identity.service:
|
||||
image: eshop/identity
|
||||
environment:
|
||||
- SpaClient=http://localhost:5104
|
||||
- ConnectionString=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
#- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105.
|
||||
- MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
ports:
|
||||
- "5105:5105"
|
||||
depends_on:
|
||||
- identity.data
|
||||
|
||||
identity.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
||||
|
||||
basket.api:
|
||||
image: eshop/basket.api
|
||||
environment:
|
||||
- ConnectionString=basket.data
|
||||
#- identityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105.
|
||||
- identityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "5103:5103"
|
||||
depends_on:
|
||||
- basket.data
|
||||
- identity.service
|
||||
|
||||
basket.data:
|
||||
image: redis
|
||||
|
||||
catalog.api:
|
||||
image: eshop/catalog.api
|
||||
environment:
|
||||
- ConnectionString=Server=catalog.data;Database=CatalogDB;User Id=sa;Password=Pass@word
|
||||
expose:
|
||||
- "80"
|
||||
ports:
|
||||
- "5101:80"
|
||||
depends_on:
|
||||
@ -58,8 +96,6 @@ services:
|
||||
- ConnectionString=Server=ordering.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
ports:
|
||||
- "5102:80"
|
||||
extra_hosts:
|
||||
- "CESARDLBOOKVHD:10.0.75.1"
|
||||
depends_on:
|
||||
- ordering.data
|
||||
|
||||
@ -70,39 +106,3 @@ services:
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5432:1433"
|
||||
|
||||
identity.service:
|
||||
image: eshop/identity
|
||||
environment:
|
||||
- Spa:http://webspa
|
||||
- ConnectionString=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers.WebMVC;User Id=sa;Password=Pass@word
|
||||
expose:
|
||||
- "80"
|
||||
ports:
|
||||
- "5105:80"
|
||||
depends_on:
|
||||
- identity.data
|
||||
|
||||
identity.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
||||
|
||||
basket.api:
|
||||
image: eshop/basket.api
|
||||
environment:
|
||||
- ConnectionString=basket.data
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "5103:80"
|
||||
depends_on:
|
||||
- basket.data
|
||||
- identity.service
|
||||
|
||||
basket.data:
|
||||
image: redis
|
BIN
img/docker_settings.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
img/eshop_cover.png
Normal file
After Width: | Height: | Size: 736 KiB |
@ -1,4 +0,0 @@
|
||||
|
||||
docker push eshop/web
|
||||
docker push eshop/catalog.api
|
||||
docker push eshop/ordering.api
|
@ -17,7 +17,6 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
.UseStartup<Startup>()
|
||||
.UseUrls("http://localhost:5008")
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
|
@ -1,187 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Welcome to ASP.NET Core</title>
|
||||
<style>
|
||||
html {
|
||||
background: #f1f1f1;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #fff;
|
||||
color: #505050;
|
||||
font: 14px 'Segoe UI', tahoma, arial, helvetica, sans-serif;
|
||||
margin: 1%;
|
||||
min-height: 95.5%;
|
||||
border: 1px solid silver;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#header {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
font-size: 44px;
|
||||
font-weight: normal;
|
||||
margin: 0;
|
||||
padding: 10px 30px 10px 30px;
|
||||
}
|
||||
|
||||
#header span {
|
||||
margin: 0;
|
||||
padding: 0 30px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#header p {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
background: #007acc;
|
||||
padding: 0 30px;
|
||||
line-height: 50px;
|
||||
margin-top: 25px;
|
||||
|
||||
}
|
||||
|
||||
#header p a {
|
||||
color: #fff;
|
||||
text-decoration: underline;
|
||||
font-weight: bold;
|
||||
padding-right: 35px;
|
||||
background: no-repeat right bottom url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAWCAMAAAAcqPc3AAAANlBMVEUAAAAAeswfitI9mthXp91us+KCvuaTx+mjz+2x1u+83PLH4vTR5/ba7Pjj8Pns9fv1+v3////wy3dWAAAAAXRSTlMAQObYZgAAAHxJREFUeNp9kVcSwCAIRMHUYoH7XzaxOxJ9P8oyQ1uIqNPwh3s2aLmIM2YtqrLcQIeQEylhuCeUOlhgve5yoBCfWmlnlgkN4H8ykbpaE7gR03AbUHiwoOxUH9Xp+ubd41p1HF3mBPrfC87BHeTdaB3ceeKL9HGpcvX9zu6+DdMWT9KQPvYAAAAASUVORK5CYII=);
|
||||
}
|
||||
|
||||
#main {
|
||||
padding: 5px 30px;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.section {
|
||||
width: 21.7%;
|
||||
float: left;
|
||||
margin: 0 0 0 4%;
|
||||
}
|
||||
|
||||
.section h2 {
|
||||
font-size: 13px;
|
||||
text-transform: uppercase;
|
||||
margin: 0;
|
||||
border-bottom: 1px solid silver;
|
||||
padding-bottom: 12px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.section.first {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.section.first h2 {
|
||||
font-size: 24px;
|
||||
text-transform: none;
|
||||
margin-bottom: 25px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.section.first li {
|
||||
border-top: 1px solid silver;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.section.last {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
li {
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #267cb2;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#footer {
|
||||
clear: both;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
#footer p {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="header">
|
||||
<h1>Welcome to ASP.NET Core</h1>
|
||||
<span>
|
||||
We've made some big updates in this release, so it’s <b>important</b> that you spend
|
||||
a few minutes to learn what’s new.
|
||||
</span>
|
||||
<p>You've created a new ASP.NET Core project. <a href="http://go.microsoft.com/fwlink/?LinkId=518016">Learn what's new</a></p>
|
||||
</div>
|
||||
|
||||
<div id="main">
|
||||
<div class="section first">
|
||||
<h2>This application consists of:</h2>
|
||||
<ul>
|
||||
<li>Sample pages using ASP.NET Core MVC</li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side libraries</li>
|
||||
<li>Theming using <a href="http://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2>How to</h2>
|
||||
<ul>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=699562">Add an appsetting in config and access it in app.</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699318">Add client packages using Bower.</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2>Overview</h2>
|
||||
<ul>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section last">
|
||||
<h2>Run & Deploy</h2>
|
||||
<ul>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li>
|
||||
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<p>We would love to hear your <a href="http://go.microsoft.com/fwlink/?LinkId=518015">feedback</a></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
24
src/Services/Basket/Basket.API/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
# Containerized eShop - Basket Service
|
||||
Sample reference containerized application, cross-platform and microservices architecture.
|
||||
Powered by Microsoft
|
||||
|
||||
#Overview
|
||||
This sample runs a microservices oriented application and a .net core Mvc application that consumes this services. You can find more information about how to set up docker in your machine in the global directory solution.
|
||||
|
||||
#Deploy
|
||||
In the global directory you will find the scripts needed to run and deploy the demo into your local docker infraestructure.
|
||||
|
||||
- <a href='build-image-services-basket.ps1'>build-image-services-basket.ps1</a> <b>Build .net applications and docker images</b>: This power shell script that you will find in the <u>root directory of the solution</u> is the responsible of building .net applications and package in a pub folder and use docker commands to build the images needed to run the previously packaged .net applications.
|
||||
|
||||
- <b>Compose containers in your docker local VM</b>: Finally you have to open your favourite command tool pointing to the <u>root directory of this project</u> where docker-compose.yml file is located and run the command `docker-compose up`
|
||||
|
||||
#Run
|
||||
Once the deploy process of docker-compose finishes you have to be able to access the services in this urls:
|
||||
- Basket service: http://localhost:5103
|
||||
- Identity service: http://localhost:5105
|
||||
- Basket data (Redis): listening in localhost:6379
|
||||
- Identity data (SQL Server): Server=localhost,5433;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
|
||||
|
||||
|
||||
|
@ -68,9 +68,11 @@ namespace Microsoft.eShopOnContainers.Services.Basket.API
|
||||
// Use frameworks
|
||||
app.UseCors("CorsPolicy");
|
||||
|
||||
var identityUrl = Configuration.GetValue(typeof(string), "IdentityUrl");
|
||||
|
||||
app.UseIdentityServerAuthentication(new IdentityServerAuthenticationOptions
|
||||
{
|
||||
Authority = "http://localhost:5000",
|
||||
Authority = identityUrl.ToString(),
|
||||
ScopeName = "basket",
|
||||
RequireHttpsMetadata = false
|
||||
});
|
||||
|
@ -7,6 +7,6 @@
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
},
|
||||
"identityUrl": "http://localhost:5000",
|
||||
"IdentityUrl": "http://localhost:5105",
|
||||
"ConnectionString": "127.0.0.1"
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
basket.api:
|
||||
build:
|
||||
args:
|
||||
source: obj/Docker/empty/
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- .:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
@ -1,9 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
basket.api:
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
@ -2,29 +2,35 @@ version: '2'
|
||||
|
||||
services:
|
||||
basket.api:
|
||||
image: user/basket.api${TAG}
|
||||
image: eshop/basket.api
|
||||
environment:
|
||||
- ConnectionString=basket.data
|
||||
#- identityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105.
|
||||
- identityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "32783:80"
|
||||
- "5103:5103"
|
||||
depends_on:
|
||||
- basket.data
|
||||
- identity.service
|
||||
|
||||
basket.data:
|
||||
image: redis
|
||||
|
||||
identity.service:
|
||||
image: eshop/identity
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
- SpaClient=http://localhost:5104
|
||||
- ConnectionString=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
#- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105.
|
||||
- MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
ports:
|
||||
- "5105:80"
|
||||
- "5105:5105"
|
||||
depends_on:
|
||||
- identity.data
|
||||
|
||||
|
||||
identity.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
|
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
// GET: /<controller>/
|
||||
public IActionResult Index()
|
||||
{
|
||||
return new RedirectResult("~/swagger/ui");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
FROM microsoft/aspnetcore:latest
|
||||
FROM microsoft/aspnetcore:1.0.1
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
ADD . /app
|
||||
COPY . /app
|
||||
ENTRYPOINT dotnet Catalog.API.dll
|
@ -1,44 +1,60 @@
|
||||
namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure
|
||||
{
|
||||
using EntityFrameworkCore;
|
||||
using Extensions.Logging;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class CatalogContextSeed
|
||||
{
|
||||
public static async Task SeedAsync(IApplicationBuilder applicationBuilder)
|
||||
public static async Task SeedAsync(IApplicationBuilder applicationBuilder, ILoggerFactory loggerFactory, int? retry = 0)
|
||||
{
|
||||
var context = (CatalogContext)applicationBuilder
|
||||
.ApplicationServices.GetService(typeof(CatalogContext));
|
||||
|
||||
using (context)
|
||||
int retryForAvaiability = retry.Value;
|
||||
try
|
||||
{
|
||||
context.Database.Migrate();
|
||||
var context = (CatalogContext)applicationBuilder
|
||||
.ApplicationServices.GetService(typeof(CatalogContext));
|
||||
|
||||
if (!context.CatalogBrands.Any())
|
||||
//using (context)
|
||||
//{
|
||||
context.Database.Migrate();
|
||||
|
||||
if (!context.CatalogBrands.Any())
|
||||
{
|
||||
context.CatalogBrands.AddRange(
|
||||
GetPreconfiguredCatalogBrands());
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!context.CatalogTypes.Any())
|
||||
{
|
||||
context.CatalogTypes.AddRange(
|
||||
GetPreconfiguredCatalogTypes());
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!context.CatalogItems.Any())
|
||||
{
|
||||
context.CatalogItems.AddRange(
|
||||
GetPreconfiguredItems());
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
//}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (retryForAvaiability < 10)
|
||||
{
|
||||
context.CatalogBrands.AddRange(
|
||||
GetPreconfiguredCatalogBrands());
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!context.CatalogTypes.Any())
|
||||
{
|
||||
context.CatalogTypes.AddRange(
|
||||
GetPreconfiguredCatalogTypes());
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
if (!context.CatalogItems.Any())
|
||||
{
|
||||
context.CatalogItems.AddRange(
|
||||
GetPreconfiguredItems());
|
||||
|
||||
await context.SaveChangesAsync();
|
||||
retryForAvaiability++;
|
||||
var log = loggerFactory.CreateLogger("catalog seed");
|
||||
log.LogError(ex.Message);
|
||||
await SeedAsync(applicationBuilder, loggerFactory, retryForAvaiability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
21
src/Services/Catalog/Catalog.API/README.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Containerized eShop - Catalog Service
|
||||
Sample reference containerized application, cross-platform and microservices architecture.
|
||||
Powered by Microsoft
|
||||
|
||||
#Overview
|
||||
This sample runs a microservices oriented application and a .net core Mvc application that consumes this services. You can find more information about how to set up docker in your machine in the global directory solution.
|
||||
|
||||
#Deploy
|
||||
In the global directory you will find the scripts needed to run and deploy the demo into your local docker infraestructure.
|
||||
|
||||
- <a href='build-image-services-catalog.ps1'>build-image-services-catalog.ps1</a> <b>Build .net applications and docker images</b>: This power shell script that you will find in the <u>root directory of the solution</u> is the responsible of building .net applications and package in a pub folder and use docker commands to build the images needed to run the previously packaged .net applications.
|
||||
|
||||
- <b>Compose containers in your docker local VM</b>: Finally you have to open your favourite command tool pointing to the <u>root directory of this project</u> where docker-compose.yml file is located and run the command `docker-compose up`
|
||||
|
||||
#Run
|
||||
Once the deploy process of docker-compose finishes you have to be able to access the services in this urls:
|
||||
- Catalog service: http://localhost:5101
|
||||
- Catalog data (SQL Server): Server=tcp:localhost,5434;Database=CatalogDB;User Id=sa;Password=Pass@word
|
||||
|
||||
|
||||
|
@ -8,6 +8,9 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class Startup
|
||||
{
|
||||
@ -45,7 +48,6 @@
|
||||
});
|
||||
|
||||
// Add framework services.
|
||||
|
||||
services.AddSwaggerGen();
|
||||
services.ConfigureSwaggerGen(options =>
|
||||
{
|
||||
@ -68,9 +70,7 @@
|
||||
.AllowCredentials());
|
||||
});
|
||||
|
||||
services.AddMvc(mvcoptions =>
|
||||
{
|
||||
});
|
||||
services.AddMvc();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||
@ -85,18 +85,19 @@
|
||||
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
|
||||
loggerFactory.AddDebug();
|
||||
|
||||
//Seed Data
|
||||
|
||||
CatalogContextSeed.SeedAsync(app)
|
||||
.Wait();
|
||||
|
||||
// Use frameworks
|
||||
app.UseCors("CorsPolicy");
|
||||
|
||||
app.UseMvc();
|
||||
app.UseMvcWithDefaultRoute();
|
||||
|
||||
app.UseSwagger()
|
||||
.UseSwaggerUi();
|
||||
|
||||
//Seed Data
|
||||
CatalogContextSeed.SeedAsync(app, loggerFactory)
|
||||
.Wait();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace eShopOnContainers.Identity.Configuration
|
||||
{
|
||||
public class ClientCallBackUrls
|
||||
{
|
||||
public string Spa { get; set; }
|
||||
}
|
||||
}
|
@ -6,14 +6,6 @@ namespace eShopOnContainers.Identity.Configuration
|
||||
{
|
||||
public class Config
|
||||
{
|
||||
private readonly IOptions<ClientCallBackUrls> _settings;
|
||||
|
||||
public Config(IOptions<ClientCallBackUrls> settings)
|
||||
{
|
||||
_settings = settings;
|
||||
|
||||
}
|
||||
|
||||
// scopes define the resources in your system
|
||||
public static IEnumerable<Scope> GetScopes()
|
||||
{
|
||||
@ -38,7 +30,7 @@ namespace eShopOnContainers.Identity.Configuration
|
||||
}
|
||||
|
||||
// client want to access resources (aka scopes)
|
||||
public static IEnumerable<Client> GetClients()
|
||||
public static IEnumerable<Client> GetClients(Dictionary<string,string> clientsUrl)
|
||||
{
|
||||
return new List<Client>
|
||||
{
|
||||
@ -49,9 +41,9 @@ namespace eShopOnContainers.Identity.Configuration
|
||||
ClientName = "eShop SPA OpenId Client",
|
||||
AllowedGrantTypes = GrantTypes.Implicit,
|
||||
AllowAccessTokensViaBrowser = true,
|
||||
RedirectUris = { "http://localhost:5003/callback.html" },
|
||||
PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
|
||||
AllowedCorsOrigins = { "http://localhost:5003" },
|
||||
RedirectUris = { $"{clientsUrl["Spa"]}/callback.html" },
|
||||
PostLogoutRedirectUris = { $"{clientsUrl["Spa"]}/index.html" },
|
||||
AllowedCorsOrigins = { $"{clientsUrl["Spa"]}" },
|
||||
AllowedScopes =
|
||||
{
|
||||
StandardScopes.OpenId.Name,
|
||||
@ -66,9 +58,9 @@ namespace eShopOnContainers.Identity.Configuration
|
||||
ClientName = "eShop Xamarin OpenId Client",
|
||||
AllowedGrantTypes = GrantTypes.Implicit,
|
||||
AllowAccessTokensViaBrowser = true,
|
||||
RedirectUris = { "http://localhost:5003/callback.html" },
|
||||
PostLogoutRedirectUris = { "http://localhost:5003/index.html" },
|
||||
AllowedCorsOrigins = { "http://localhost:5003" },
|
||||
RedirectUris = { "http://eshopxamarin/callback.html" },
|
||||
PostLogoutRedirectUris = { "http://eshopxamarin/callback.html/index.html" },
|
||||
AllowedCorsOrigins = { "http://eshopxamarin" },
|
||||
AllowedScopes =
|
||||
{
|
||||
StandardScopes.OpenId.Name,
|
||||
@ -85,17 +77,17 @@ namespace eShopOnContainers.Identity.Configuration
|
||||
{
|
||||
new Secret("secret".Sha256())
|
||||
},
|
||||
ClientUri = "http://localhost:2114",
|
||||
ClientUri = $"{clientsUrl["Mvc"]}", // public uri of the client
|
||||
AllowedGrantTypes = GrantTypes.HybridAndClientCredentials,
|
||||
RedirectUris = new List<string>
|
||||
{
|
||||
"http://localhost:2114/signin-oidc"
|
||||
$"{clientsUrl["Mvc"]}/signin-oidc",
|
||||
"http://104.40.62.65:5100/signin-oidc"
|
||||
},
|
||||
PostLogoutRedirectUris = new List<string>
|
||||
{
|
||||
"http://localhost:2114/"
|
||||
$"{clientsUrl["Mvc"]}/"
|
||||
},
|
||||
LogoutUri = "http://localhost:2114/signout-oidc",
|
||||
AllowedScopes = new List<string>
|
||||
{
|
||||
StandardScopes.OpenId.Name,
|
||||
|
@ -202,8 +202,9 @@ namespace IdentityServer4.Quickstart.UI.Controllers
|
||||
// hack: try/catch to handle social providers that throw
|
||||
await HttpContext.Authentication.SignOutAsync(idp, new AuthenticationProperties { RedirectUri = url });
|
||||
}
|
||||
catch(NotSupportedException)
|
||||
catch(Exception ex)
|
||||
{
|
||||
_logger.LogCritical(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,73 +248,6 @@ namespace IdentityServer4.Quickstart.UI.Controllers
|
||||
return new ChallengeResult(provider, props);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Post processing of external authentication
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> ExternalLoginCallback(string returnUrl)
|
||||
{
|
||||
// read external identity from the temporary cookie
|
||||
var info = await HttpContext.Authentication.GetAuthenticateInfoAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
|
||||
//var tempUser = info?.Principal;
|
||||
//if (tempUser == null)
|
||||
//{
|
||||
// throw new Exception("External authentication error");
|
||||
//}
|
||||
|
||||
//// retrieve claims of the external user
|
||||
//var claims = tempUser.Claims.ToList();
|
||||
|
||||
//// try to determine the unique id of the external user - the most common claim type for that are the sub claim and the NameIdentifier
|
||||
//// depending on the external provider, some other claim type might be used
|
||||
//var userIdClaim = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.Subject);
|
||||
//if (userIdClaim == null)
|
||||
//{
|
||||
// userIdClaim = claims.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
|
||||
//}
|
||||
//if (userIdClaim == null)
|
||||
//{
|
||||
// throw new Exception("Unknown userid");
|
||||
//}
|
||||
|
||||
//// remove the user id claim from the claims collection and move to the userId property
|
||||
//// also set the name of the external authentication provider
|
||||
//claims.Remove(userIdClaim);
|
||||
//var provider = info.Properties.Items["scheme"];
|
||||
//var userId = userIdClaim.Value;
|
||||
|
||||
//// check if the external user is already provisioned
|
||||
//var user = _loginService.FindByExternalProvider(provider, userId);
|
||||
//if (user == null)
|
||||
//{
|
||||
// // this sample simply auto-provisions new external user
|
||||
// // another common approach is to start a registrations workflow first
|
||||
// user = _loginService.AutoProvisionUser(provider, userId, claims);
|
||||
//}
|
||||
|
||||
//var additionalClaims = new List<Claim>();
|
||||
|
||||
//// if the external system sent a session id claim, copy it over
|
||||
//var sid = claims.FirstOrDefault(x => x.Type == JwtClaimTypes.SessionId);
|
||||
//if (sid != null)
|
||||
//{
|
||||
// additionalClaims.Add(new Claim(JwtClaimTypes.SessionId, sid.Value));
|
||||
//}
|
||||
|
||||
//// issue authentication cookie for user
|
||||
//await HttpContext.Authentication.SignInAsync(user.Subject, user.Username, provider, additionalClaims.ToArray());
|
||||
|
||||
//// delete temporary cookie used during external authentication
|
||||
//await HttpContext.Authentication.SignOutAsync(IdentityServerConstants.ExternalCookieAuthenticationScheme);
|
||||
|
||||
//// validate return URL and redirect back to authorization endpoint
|
||||
//if (_interaction.IsValidReturnUrl(returnUrl))
|
||||
//{
|
||||
// return Redirect(returnUrl);
|
||||
//}
|
||||
|
||||
return Redirect("~/");
|
||||
}
|
||||
|
||||
// GET: /Account/Register
|
||||
[HttpGet]
|
||||
@ -361,6 +295,10 @@ namespace IdentityServer4.Quickstart.UI.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
if (returnUrl != null) {
|
||||
return Redirect(returnUrl);
|
||||
}
|
||||
|
||||
return RedirectToAction("index", "home");
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,5 @@ FROM microsoft/aspnetcore:1.0.1
|
||||
ENTRYPOINT ["dotnet", "eShopOnContainers.Identity.dll"]
|
||||
ARG source=.
|
||||
WORKDIR /app
|
||||
ENV ASPNETCORE_URLS http://*:80
|
||||
EXPOSE 80
|
||||
COPY $source .
|
||||
ENV ASPNETCORE_URLS http://*:5105
|
||||
COPY $source .
|
||||
|
@ -13,9 +13,9 @@ namespace eShopOnContainers.Identity
|
||||
{
|
||||
var host = new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
//.UseUrls("http://localhost:5000")
|
||||
.UseUrls("http://0.0.0.0:5105")
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
//.UseIISIntegration()
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
|
||||
|
25
src/Services/Identity/eShopOnContainers.Identity/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Containerized eShop - Identity Service
|
||||
Sample reference containerized application, cross-platform and microservices architecture.
|
||||
Powered by Microsoft
|
||||
|
||||
#Overview
|
||||
This sample runs a microservices oriented application and a .net core Mvc application that consumes this services. You can find more information about how to set up docker in your machine in the global directory solution.
|
||||
|
||||
#Considerations
|
||||
This service is a identity provider implemented with identity server 4, to implement this scenario is needed a public authority so to complete this flow in our local docker infrastructure we have to add a entry in our host file (windows) or equivalent in other platforms:
|
||||
|
||||
identity.service 127.0.0.1
|
||||
|
||||
In the root directory of this solution you'll find add-host.ps1 script that does this work for you (requires elevation permission).
|
||||
|
||||
#Deploy
|
||||
In the global directory you will find the scripts needed to run and deploy the demo into your local docker infraestructure.
|
||||
|
||||
- <a href='build-image-services-identity.ps1'>build-image-services-identity.ps1</a> <b>Build .net applications and docker images</b>: This power shell script that you will find in the <u>root directory of the solution</u> is the responsible of building .net applications and package in a pub folder and use docker commands to build the images needed to run the previously packaged .net applications.
|
||||
|
||||
- <b>Compose containers in your docker local VM</b>: Finally you have to open your favourite command tool pointing to the <u>root directory of this project</u> where docker-compose.yml file is located and run the command `docker-compose up`
|
||||
|
||||
#Run
|
||||
Once the deploy process of docker-compose finishes you have to be able to access the services in this urls:
|
||||
- Identity service: http://localhost:5105
|
||||
- Identity data (SQL Server): Server=localhost,5433;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
@ -14,6 +14,7 @@ using eShopOnContainers.Identity.Models;
|
||||
using eShopOnContainers.Identity.Services;
|
||||
using eShopOnContainers.Identity.Configuration;
|
||||
using IdentityServer4.Services;
|
||||
using System.Threading;
|
||||
|
||||
namespace eShopOnContainers.Identity
|
||||
{
|
||||
@ -56,17 +57,18 @@ namespace eShopOnContainers.Identity
|
||||
services.AddTransient<ISmsSender, AuthMessageSender>();
|
||||
services.AddTransient<ILoginService<ApplicationUser>, EFLoginService>();
|
||||
|
||||
//callbacks urls from config:
|
||||
Dictionary<string, string> clientUrls = new Dictionary<string, string>();
|
||||
clientUrls.Add("Mvc", Configuration.GetValue<string>("MvcClient"));
|
||||
clientUrls.Add("Spa", Configuration.GetValue<string>("SpaClient"));
|
||||
|
||||
// Adds IdentityServer
|
||||
services.AddIdentityServer()
|
||||
.AddTemporarySigningCredential()
|
||||
.AddInMemoryScopes(Config.GetScopes())
|
||||
.AddInMemoryClients(Config.GetClients())
|
||||
.AddInMemoryClients(Config.GetClients(clientUrls))
|
||||
.AddAspNetIdentity<ApplicationUser>()
|
||||
.Services.AddTransient<IProfileService, ProfileService>();
|
||||
|
||||
//Configuration Settings:
|
||||
services.AddOptions();
|
||||
services.Configure<ClientCallBackUrls>(Configuration.GetSection("ClientCallBackUrls"));
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
@ -100,17 +102,29 @@ namespace eShopOnContainers.Identity
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
});
|
||||
|
||||
MigrateDb(app);
|
||||
}
|
||||
|
||||
int retries = 0;
|
||||
|
||||
private void MigrateDb(IApplicationBuilder app)
|
||||
{
|
||||
try
|
||||
{
|
||||
var context = (ApplicationDbContext)app
|
||||
.ApplicationServices.GetService(typeof(ApplicationDbContext));
|
||||
|
||||
.ApplicationServices.GetService(typeof(ApplicationDbContext));
|
||||
using (context)
|
||||
{
|
||||
context.Database.Migrate();
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
retries++;
|
||||
if (retries < 2)
|
||||
MigrateDb(app);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
}
|
||||
<div class="brand-header-block">
|
||||
<ul class="container">
|
||||
<li><a asp-area="" asp-controller="Account" asp-action="Register">REGISTER</a></li>
|
||||
<li><a asp-area="" asp-controller="Account" asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]">REGISTER</a></li>
|
||||
<li class="active" style="margin-right: 65px;">LOGIN</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<div class="brand-header-block">
|
||||
<ul class="container">
|
||||
<li class="active">REGISTER</li>
|
||||
<li style="margin-right: 65px;"><a asp-area="" asp-controller="Account" asp-action="Login">LOGIN</a></li>
|
||||
<li style="margin-right: 65px;"><a asp-area="" asp-controller="Account" asp-action="Login" asp-route-returnurl="@ViewData["ReturnUrl"]">LOGIN</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="container register-container">
|
||||
|
@ -1,49 +0,0 @@
|
||||
@*@model eShopOnContainers.Identity.Models.AccountViewModels.LoginViewModel
|
||||
|
||||
<div class="login-page">
|
||||
<div class="page-header">
|
||||
<h1>Login</h1>
|
||||
</div>
|
||||
|
||||
@Html.Partial("_ValidationSummary")
|
||||
|
||||
<div class="row">
|
||||
|
||||
@if (Model.EnableLocalLogin)
|
||||
{
|
||||
<div class="col-sm-6">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Local Login</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<form asp-route="Login">
|
||||
<input type="hidden" asp-for="ReturnUrl" />
|
||||
|
||||
<fieldset>
|
||||
<div class="form-group">
|
||||
<label asp-for="Username"></label>
|
||||
<input class="form-control" placeholder="Username" asp-for="Username" autofocus>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Password"></label>
|
||||
<input type="password" class="form-control" placeholder="Password" asp-for="Password" autocomplete="off">
|
||||
</div>
|
||||
<div class="form-group login-remember">
|
||||
<label asp-for="RememberLogin">
|
||||
<input asp-for="RememberLogin">
|
||||
<strong>Remember My Login</strong>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button class="btn btn-primary">Login</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>*@
|
@ -1,4 +1,4 @@
|
||||
<div class="welcome-page">
|
||||
<div class="welcome-page container">
|
||||
<div class="row page-header">
|
||||
<div class="col-sm-10">
|
||||
<h1>
|
||||
|
@ -3,51 +3,60 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>IdentityServer4</title>
|
||||
<title>eShopOnContainers Identity</title>
|
||||
<link rel="icon" type="image/x-icon" href="~/favicon.ico" />
|
||||
<link rel="shortcut icon" type="image/x-icon" href="~/favicon.ico" />
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/css/bootstrap.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" />
|
||||
<link rel="stylesheet" href="~/css/sitemvc.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a href="~/">
|
||||
<span class="navbar-brand">
|
||||
<img src="~/icon.png" class="icon-banner">
|
||||
IdentityServer4
|
||||
</span>
|
||||
</a>
|
||||
<div class="navbar navbar-inverse navbar-fixed-top es-header">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="navbar-header col-sm-6 col-xs-8">
|
||||
<a href="~/">
|
||||
<div class="navbar-brand"></div>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a asp-action="Register" asp-controller="Account">Register User</a>
|
||||
</div>
|
||||
@if (User.Identity.IsAuthenticated)
|
||||
{
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">@User.Identity.Name <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a asp-action="Logout" asp-controller="Account">Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
<a asp-action="Register" asp-controller="Account">Register User</a>
|
||||
</div>
|
||||
@if (User.Identity.IsAuthenticated)
|
||||
{
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">@User.Identity.Name <b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a asp-action="Logout" asp-controller="Account">Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container body-content">
|
||||
|
||||
<div>
|
||||
@RenderBody()
|
||||
<br /><br />
|
||||
<footer>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<br><div class="brand"></div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<br />
|
||||
<br>
|
||||
<br />
|
||||
<div class="text hidden-xs">© e-ShoponContainers. All right reserved</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="~/lib/jquery/jquery.js"></script>
|
||||
<script src="~/lib/bootstrap/js/bootstrap.js"></script>
|
||||
@RenderSection("scripts", required: false)
|
||||
|
@ -1,11 +1,10 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
//"DefaultConnection": "Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers.WebMVC;User Id=sa;Password=Pass@word"
|
||||
"DefaultConnection": "Server=127.0.0.1,5433;Database=aspnet-Microsoft.eShopOnContainers.WebMVC;User Id=sa;Password=Pass@word"
|
||||
},
|
||||
"ClientsCallBackUrls": {
|
||||
"Spa": "http://localhost:5003"
|
||||
"DefaultConnection": "Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word"
|
||||
//"DefaultConnection": "Server=127.0.0.1,5433;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word"
|
||||
},
|
||||
"MvcClient": "http://localhost:5100",
|
||||
"SpaClient": "http://localhost:5104",
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
|
@ -6,7 +6,6 @@
|
||||
// An array of relative input file paths. Globbing patterns supported
|
||||
"inputFiles": [
|
||||
"wwwroot/css/site.css",
|
||||
"wwwroot/css/sitemvc.css"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -1,18 +1,15 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
identity.service:
|
||||
image: eshop/identity
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
identity.service:
|
||||
image: eshop/identity
|
||||
environment:
|
||||
- ConnectionString=Server=identity.data;Initial Catalog=CatalogData;User Id=sa;Password=Pass@word
|
||||
- Spa=http://localhost/5003
|
||||
expose:
|
||||
- "80"
|
||||
- SpaClient=http://localhost:5104
|
||||
- ConnectionString=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
#- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105.
|
||||
- MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
ports:
|
||||
- "5101:80"
|
||||
- "5105:5105"
|
||||
depends_on:
|
||||
- identity.data
|
||||
|
||||
@ -22,4 +19,4 @@ services:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5434:1433"
|
||||
- "5433:1433"
|
||||
|
@ -97,9 +97,9 @@
|
||||
"prepublish": [
|
||||
"bower install",
|
||||
"dotnet bundle"
|
||||
],
|
||||
"postpublish": [
|
||||
"dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%"
|
||||
]
|
||||
//"postpublish": [
|
||||
// "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%"
|
||||
//]
|
||||
}
|
||||
}
|
||||
|
@ -36,4 +36,869 @@
|
||||
}
|
||||
.page-consent .consent-form .consent-remember {
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Montserrat;
|
||||
font-weight: 400;
|
||||
src: url("/fonts/Montserrat-Regular.eot?") format("eot"),url("/fonts/Montserrat-Regular.woff") format("woff"),url("/fonts/Montserrat-Regular.ttf") format("truetype"),url("/fonts/Montserrat-Regular.svg#Montserrat") format("svg")
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Montserrat;
|
||||
font-weight: 700;
|
||||
src: url("/fonts/Montserrat-Bold.eot?") format("eot"),url("/fonts/Montserrat-Bold.woff") format("woff"),url("/fonts/Montserrat-Bold.ttf") format("truetype"),url("/fonts/Montserrat-Bold.svg#Montserrat") format("svg")
|
||||
}
|
||||
|
||||
body {
|
||||
padding-top: 80px;
|
||||
/*padding-bottom: 20px;*/
|
||||
font-family: Montserrat,sans-serif;
|
||||
min-width:480px;
|
||||
}
|
||||
|
||||
.mt-15 {
|
||||
margin-top:15px;
|
||||
}
|
||||
|
||||
/* Wrapping element */
|
||||
/* Set some basic padding to keep content from hitting the edges */
|
||||
.body-content {
|
||||
padding-left: 15px;
|
||||
padding-right: 15px;
|
||||
}
|
||||
|
||||
/* Set widths on the form inputs since otherwise they're 100% wide */
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
max-width: 280px;
|
||||
}
|
||||
|
||||
.select-filter {
|
||||
background-color: transparent;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
margin-right: 20px;
|
||||
color: white;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 3px;
|
||||
min-width: 140px;
|
||||
border-color: #37c7ca;
|
||||
max-height: 43px;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
.select-filter option {
|
||||
background-color: #00a69c;
|
||||
}
|
||||
|
||||
select::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.select-filter-wrapper {
|
||||
z-index: 0;
|
||||
display:inline-block;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.select-filter-wrapper::before {
|
||||
content: attr(data-name);
|
||||
opacity: 0.5;
|
||||
z-index: 1;
|
||||
text-transform: uppercase;
|
||||
position: absolute;
|
||||
font-size: 10px;
|
||||
margin-top: 15px;
|
||||
margin-left: 21px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.select-filter-arrow {
|
||||
position: absolute;
|
||||
margin-left: 130px;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.btn-brand-small-filter {
|
||||
margin-top: 10px;
|
||||
position: absolute;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
/* Carousel */
|
||||
.carousel-caption p {
|
||||
font-size: 20px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.layout-cart-image {
|
||||
height: 36px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.layout-cart-badge {
|
||||
position: absolute;
|
||||
margin-top: 2px;
|
||||
margin-left: 14px;
|
||||
background-color: #83d01b;
|
||||
padding: 1px;
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* buttons and links extension to use brackets: [ click me ] */
|
||||
.btn-bracketed:hover:before {
|
||||
display: inline-block;
|
||||
content: "[";
|
||||
padding-right: 0.5em;
|
||||
color: chartreuse;
|
||||
}
|
||||
|
||||
.btn-bracketed:hover:after {
|
||||
display: inline-block;
|
||||
content: "]";
|
||||
padding-left: 0.5em;
|
||||
color: chartreuse;
|
||||
}
|
||||
|
||||
.btn-brand {
|
||||
background-color: #83D01B;
|
||||
color: white;
|
||||
padding: 10px 20px 10px 20px;
|
||||
border-radius: 0px;
|
||||
border: none;
|
||||
width: 255px;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
height: 45px;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.btn-brand::before {
|
||||
content: '['
|
||||
}
|
||||
|
||||
.btn-brand::after {
|
||||
content: ']'
|
||||
}
|
||||
|
||||
.btn-brand:hover:before {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.btn-brand:hover:after {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.btn-brand-big {
|
||||
width: 360px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.btn-brand-small {
|
||||
width: 45px;
|
||||
}
|
||||
|
||||
.btn-brand-small::before {
|
||||
content: '';
|
||||
}
|
||||
|
||||
.btn-brand-small::after {
|
||||
content: '';
|
||||
}
|
||||
|
||||
.btn-brand-small:hover:before {
|
||||
content: '';
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.btn-brand-small:hover:after {
|
||||
content: '';
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.btn-brand-dark {
|
||||
background-color: #00a69c;
|
||||
}
|
||||
|
||||
.btn-brand:hover {
|
||||
color: white;
|
||||
background-color: #83D01B;
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.btn-brand-dark:hover {
|
||||
background-color: #00a69c;
|
||||
}
|
||||
|
||||
.btn-cart {
|
||||
float: right;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.btn-catalog-apply {
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
text-transform: uppercase;
|
||||
font-weight: normal!important;
|
||||
text-align: left;
|
||||
margin-bottom: 10px !important;
|
||||
color: #404040;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
border-radius: 0;
|
||||
padding: 10px;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.form-input-small {
|
||||
max-width: 100px!important;
|
||||
}
|
||||
|
||||
.form-select {
|
||||
border-radius: 0;
|
||||
padding: 10px;
|
||||
height: 45px;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
/* Make .svg files in the carousel display properly in older browsers */
|
||||
.carousel-inner .item img[src$=".svg"] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.navbar-inverse {
|
||||
background-color: #FFF;
|
||||
border-color: #FFF;
|
||||
}
|
||||
|
||||
/*.navbar-inverse li {
|
||||
margin-top: 10px;
|
||||
}*/
|
||||
|
||||
.btn-login {
|
||||
border: 1px solid #00A69C;
|
||||
height: 36px!important;
|
||||
margin-right: 10px;
|
||||
margin-top: 10px;
|
||||
background-color: white;
|
||||
color: #00a69c;
|
||||
text-transform:uppercase;
|
||||
max-width: 140px;
|
||||
width: 140px;
|
||||
padding-top:8px!important;
|
||||
}
|
||||
|
||||
.btn-login {
|
||||
font-weight:normal!important;
|
||||
}
|
||||
|
||||
.btn-login::before {
|
||||
content: '[';
|
||||
}
|
||||
|
||||
.btn-login::after {
|
||||
content: ']';
|
||||
}
|
||||
|
||||
.btn-login:hover:before {
|
||||
content: '[ ';
|
||||
}
|
||||
|
||||
.btn-login:hover:after {
|
||||
content: ' ]';
|
||||
}
|
||||
|
||||
.navbar-inverse li a {
|
||||
height: 30px;
|
||||
padding: 5px 20px;
|
||||
color: #00A69C !important;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
margin-top: 20px;
|
||||
background-image: url(../images/brand.PNG);
|
||||
width: 201px;
|
||||
height: 44px;
|
||||
margin-left: 0px !important;
|
||||
}
|
||||
|
||||
.nav > li > a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav > li > a:hover, .nav > li > a:focus {
|
||||
background-color: #00A69C;
|
||||
font-weight: bolder;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.home-banner {
|
||||
width: 100%;
|
||||
margin-right: 0px;
|
||||
margin-left: 0px;
|
||||
background-image: url(../images/main_banner.png);
|
||||
background-size: cover;
|
||||
height: 258px;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.home-banner-text {
|
||||
margin-top: 70px;
|
||||
}
|
||||
|
||||
.home-catalog-container {
|
||||
min-height: 400px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.home-catalog-filter-container {
|
||||
background-color: #00A69C;
|
||||
height:63px;
|
||||
}
|
||||
|
||||
.home-catalog-filter-container li a {
|
||||
padding-top: 5px !important;
|
||||
}
|
||||
|
||||
.home-catalog-filter-brands::before {
|
||||
content: 'BRAND';
|
||||
color: white;
|
||||
font-size: x-small;
|
||||
opacity: 0.5;
|
||||
margin: 10px 0px 0px 15px;
|
||||
}
|
||||
|
||||
.home-catalog-filter-types::before {
|
||||
content: 'TYPES';
|
||||
color: white;
|
||||
font-size: x-small;
|
||||
opacity: 0.5;
|
||||
margin: 10px 0px 0px 15px;
|
||||
}
|
||||
|
||||
.home-catalog-item {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.home-catalog-item-image {
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
/* max-width: 320px; */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.home-catalog-item-image-addCart {
|
||||
background-color: #83D01B;
|
||||
color: white;
|
||||
display: inline-block;
|
||||
height: 43px;
|
||||
padding: 10px 20px 10px 20px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
margin-top: 10px;
|
||||
margin-left: 60px;
|
||||
margin-right: 60px;
|
||||
font-size: 16px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.home-catalog-item-image-addCart:hover {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
.home-catalog-item-image:hover:after {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.home-catalog-item-title {
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.home-catalog-item-price {
|
||||
text-align: center;
|
||||
font-weight: 900;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.home-catalog-item-price::before {
|
||||
content: '$';
|
||||
}
|
||||
|
||||
.home-catalog-noResults {
|
||||
text-align:center;
|
||||
margin-top: 100px;
|
||||
}
|
||||
|
||||
.container .nav .navbar-nav .col-sm-6 ::before {
|
||||
content: 'BRAND';
|
||||
}
|
||||
|
||||
.validation-summary-errors li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
footer {
|
||||
background-color: black;
|
||||
height: 150px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
footer .brand {
|
||||
margin-top: 25px;
|
||||
background-image: url(../images/brand_dark.PNG);
|
||||
max-width: 231px;
|
||||
height: 52px;
|
||||
margin-left: 0px !important;
|
||||
}
|
||||
|
||||
footer .text {
|
||||
text-align: right;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #83D01B;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.text {
|
||||
color: #83D01B;
|
||||
}
|
||||
|
||||
.text:hover {
|
||||
color: #83D01B;
|
||||
}
|
||||
|
||||
form .col-md-4 {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.brand-header-block {
|
||||
background-color: #00A69C;
|
||||
height: 63px;
|
||||
}
|
||||
|
||||
.brand-header-block li {
|
||||
list-style: none;
|
||||
display: inline;
|
||||
opacity: 0.5;
|
||||
margin-top: 25px;
|
||||
margin-left: 10px;
|
||||
/*float: right;*/
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.brand-header-block li a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.brand-header-block li a:hover {
|
||||
text-decoration:none;
|
||||
}
|
||||
|
||||
.brand-header-block .active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.brand-header-block .active::before {
|
||||
content: '[ ';
|
||||
color: greenyellow;
|
||||
}
|
||||
|
||||
.brand-header-block .active::after {
|
||||
content: ' ]';
|
||||
color: greenyellow;
|
||||
}
|
||||
|
||||
.brand-header-back {
|
||||
float: left!important;
|
||||
margin-top: 20px!important;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.account-login-container {
|
||||
min-height: 70vh;
|
||||
text-align: center;
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.account-register-container {
|
||||
min-height: 70vh;
|
||||
text-align: center !important;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.cart-index-container {
|
||||
min-height: 70vh;
|
||||
padding-top: 40px;
|
||||
margin-bottom: 30px;
|
||||
min-width: 992px;
|
||||
}
|
||||
|
||||
.register-container {
|
||||
min-height: 70vh;
|
||||
padding-top: 40px;
|
||||
margin-bottom: 30px;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
.order-create-container {
|
||||
min-height: 70vh;
|
||||
padding-top: 40px;
|
||||
margin-bottom: 30px;
|
||||
padding-left: 30px;
|
||||
min-width: 995px;
|
||||
}
|
||||
|
||||
.cart-product-column {
|
||||
max-width: 120px;
|
||||
text-transform: uppercase;
|
||||
vertical-align: middle!important;
|
||||
}
|
||||
|
||||
.order-create-container .cart-product-column {
|
||||
max-width: 130px;
|
||||
}
|
||||
|
||||
.cart-product-column-name {
|
||||
width: 220px;
|
||||
}
|
||||
|
||||
.cart-subtotal-label {
|
||||
font-size: 12px;
|
||||
color: #404040;
|
||||
margin-top:10px;
|
||||
}
|
||||
|
||||
.cart-subtotal-value {
|
||||
font-size: 20px;
|
||||
color: #00a69c;
|
||||
}
|
||||
|
||||
.cart-total-label {
|
||||
font-size: 14px;
|
||||
color: #404040;
|
||||
margin-top:10px;
|
||||
}
|
||||
|
||||
.cart-total-value {
|
||||
font-size: 28px;
|
||||
color: #00a69c;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.cart-product-image {
|
||||
max-width: 210px;
|
||||
}
|
||||
|
||||
.cart-section-total {
|
||||
margin-bottom: 5px;
|
||||
margin-left: 175px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.cart-product-column input {
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cart-refresh-button {
|
||||
margin-top:0;
|
||||
background-image: url('../images/refresh.svg');
|
||||
color: white;
|
||||
font-size: 8px;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
background-color:transparent;
|
||||
border:none;
|
||||
margin-top: 25px;
|
||||
margin-left:15px;
|
||||
}
|
||||
|
||||
.cart-refresh-button:hover {
|
||||
background-color:transparent;
|
||||
}
|
||||
|
||||
.cart-totals {
|
||||
border-bottom:none!important;
|
||||
}
|
||||
|
||||
.input-validation-error {
|
||||
border: 1px solid #fb0d0d;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: #fb0d0d;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.cart {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.form-horizontal h4 {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.form-horizontal .form-group {
|
||||
margin-right: 0px!important;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
border-color: #83d01b;
|
||||
}
|
||||
|
||||
.form-input-center {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.order-index-container {
|
||||
min-height: 70vh;
|
||||
padding-top: 40px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.order-index-container .table tbody tr {
|
||||
border-bottom:none;
|
||||
}
|
||||
|
||||
.order-index-container .table tbody tr td {
|
||||
border-top:none;
|
||||
padding-top:10px;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.order-index-container .table tbody tr:nth-child(even) {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.order-create-section-title {
|
||||
margin-left: -15px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.order-create-section-items {
|
||||
margin-left: -45px;
|
||||
width: 102%;
|
||||
}
|
||||
|
||||
.order-detail-button {
|
||||
|
||||
}
|
||||
|
||||
.order-detail-button a {
|
||||
color: #83d01b;
|
||||
}
|
||||
|
||||
.order-detail-container {
|
||||
min-height: 70vh;
|
||||
padding-top: 40px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.order-detail-container .table tbody tr:first-child td{
|
||||
border-top:none;
|
||||
}
|
||||
|
||||
.order-detail-container .table tr{
|
||||
border-bottom:none;
|
||||
}
|
||||
|
||||
.order-detail-section {
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.order-detail-container .table {
|
||||
margin-left: -7px;
|
||||
}
|
||||
|
||||
.order-section-total {
|
||||
margin-bottom: 5px;
|
||||
margin-left: 40px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.fr {
|
||||
float:right!important;
|
||||
}
|
||||
|
||||
.down-arrow {
|
||||
background-image: url('../images/arrow-down.png');
|
||||
height: 7px;
|
||||
width: 10px;
|
||||
display: inline-block;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.logout-icon {
|
||||
background-image: url('../images/logout.PNG');
|
||||
display: inline-block;
|
||||
height:19px;
|
||||
width:19px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.myorders-icon {
|
||||
background-image: url('../images/my_orders.PNG');
|
||||
display: inline-block;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.login-user {
|
||||
position: absolute!important;
|
||||
top: 30px;
|
||||
right: 65px;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.login-user-dropdown {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.login-user-dropdown-content {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background-color: #FFFFFF;
|
||||
min-width: 160px;
|
||||
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
|
||||
/*left: 100px;*/
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.login-user-dropdown-content a {
|
||||
color: black;
|
||||
padding: 12px 16px;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
text-align:right;
|
||||
text-transform:uppercase;
|
||||
}
|
||||
|
||||
.login-user:hover .login-user-dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.down-arrow:hover > .login-user-dropdown-content {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.login-user-dropdown-content a:hover {
|
||||
color: #83d01b;
|
||||
}
|
||||
|
||||
.es-header {
|
||||
min-height: 80px!important;
|
||||
}
|
||||
|
||||
.es-pager-bottom {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.es-pager-top {
|
||||
margin-bottom: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.es-pager-top ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.es-pager-bottom ul {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.page-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.next {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.previous {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.is-disabled{
|
||||
cursor: not-allowed;
|
||||
opacity: .5;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.table tr {
|
||||
border-bottom:1px solid #ddd;
|
||||
}
|
||||
|
||||
.table th {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
|
||||
.navbar-nav {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 7.5px;
|
||||
margin-right: -10px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1195px) {
|
||||
.cart-product-column-name {
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide/rearrange for smaller screens */
|
||||
@media screen and (max-width: 767px) {
|
||||
/* Hide captions */
|
||||
.carousel-caption {
|
||||
display: none;
|
||||
}
|
||||
|
||||
footer .text {
|
||||
text-align: left;
|
||||
margin-top: -15px;
|
||||
}
|
||||
|
||||
.cart-product-column-brand {
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 992px) {
|
||||
.form-input {
|
||||
width: 360px;
|
||||
max-width: 360px;
|
||||
}
|
||||
}
|
@ -524,7 +524,7 @@ form .col-md-4 {
|
||||
opacity: 0.5;
|
||||
margin-top: 25px;
|
||||
margin-left: 10px;
|
||||
float: right;
|
||||
/*float: right;*/
|
||||
cursor: pointer;
|
||||
color: white;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1 @@
|
||||
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 32 32" height="32px" id="Слой_1" version="1.1" viewBox="0 0 32 32" width="32px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path clip-rule="evenodd" d="M21.698,15.286l-9.002-8.999 c-0.395-0.394-1.035-0.394-1.431,0c-0.395,0.394-0.395,1.034,0,1.428L19.553,16l-8.287,8.285c-0.395,0.394-0.395,1.034,0,1.429 c0.395,0.394,1.036,0.394,1.431,0l9.002-8.999C22.088,16.325,22.088,15.675,21.698,15.286z" fill="#FFFFFF" fill-rule="evenodd" id="Chevron_Right"/><g/><g/><g/><g/><g/><g/></svg>
|
After Width: | Height: | Size: 693 B |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 429 B |
After Width: | Height: | Size: 713 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 221 B |
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 259.244 259.244" style="enable-background:new 0 0 259.244 259.244;" xml:space="preserve">
|
||||
<g>
|
||||
<path style="fill:#3DB39E;" d="M248.348,129.3h-15.849C232.41,65.277,180.831,13.394,117.202,13.394
|
||||
c-31.841,0-60.661,12.998-81.534,33.996C14.017,68.549,0.25,97.092,0.036,129.3H0l0.018,0.331L0,130.033h0.036
|
||||
c0.393,63.853,51.758,115.816,115.19,115.816c31.841,0,60.661-13.007,81.534-34.049l-25.852-24.931
|
||||
c-14.178,14.303-34.058,23.027-55.682,23.135c-44.401,0.206-79.201-36.49-79.201-80.122c-0.107-22.893,10.092-42.908,25.486-57.595
|
||||
c14.186-14.285,34.058-23.001,55.691-23.108c44.41-0.206,79.201,36.445,79.201,79.997v0.125h-15.661
|
||||
c-9.708,0-13.668,6.499-8.814,14.41l33.799,33.433c7.732,7.732,9.967,7.661,17.646,0l33.799-33.433
|
||||
C262.025,135.781,258.056,129.3,248.348,129.3z"/>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
<g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
// For more information on enabling MVC for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
|
||||
|
||||
namespace Microsoft.eShopOnContainers.Services.Ordering.API.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
// GET: /<controller>/
|
||||
public IActionResult Index()
|
||||
{
|
||||
return new RedirectResult("~/swagger/ui");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,9 +1,4 @@
|
||||
FROM microsoft/aspnetcore:1.0.1
|
||||
# Other .NET images
|
||||
# FROM microsoft/dotnet:1.0.0-preview2-sdk
|
||||
# FROM microsoft/dotnet:1.0.0-core
|
||||
# FROM microsoft/aspnetcore
|
||||
# FROM microsoft/dotnet:1.0.0-preview2-windowsservercore-sdk
|
||||
|
||||
# Entry point through the copied assembly
|
||||
ENTRYPOINT ["dotnet", "Ordering.API.dll"]
|
||||
@ -11,14 +6,3 @@ ARG source=.
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
COPY $source .
|
||||
|
||||
|
||||
#################
|
||||
# Entry point running the SDK --> Requires heavy Docker .NET image, not for production
|
||||
# Restore NuGet packages
|
||||
#RUN ["dotnet", "restore"]
|
||||
# Build the .NET Core app
|
||||
#RUN ["dotnet", "build"]
|
||||
# Entrypoint
|
||||
#ENTRYPOINT ["dotnet", "run"]
|
||||
#################
|
||||
|
26
src/Services/Ordering/Ordering.API/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Containerized eShop - Orders Service
|
||||
Sample reference containerized application, cross-platform and microservices architecture.
|
||||
Powered by Microsoft
|
||||
|
||||
#Overview
|
||||
This sample runs a microservices oriented application and a .net core Mvc application that consumes this services. You can find more information about how to set up docker in your machine in the global directory solution.
|
||||
|
||||
#Deploy
|
||||
In the global directory you will find the scripts needed to run and deploy the demo into your local docker infraestructure.
|
||||
|
||||
- <a href='build-image-services-orders.ps1'>build-image-services-orders.ps1</a> <b>Build .net applications and docker images</b>: This power shell script that you will find in the <u>root directory of the solution</u> is the responsible of building .net applications and package in a pub folder and use docker commands to build the images needed to run the previously packaged .net applications.
|
||||
|
||||
- <b>Compose containers in your docker local VM</b>: Finally you have to open your favourite command tool pointing to the <u>root directory of this project</u> where docker-compose.yml file is located and run the command `docker-compose up`
|
||||
|
||||
#Run
|
||||
Once the deploy process of docker-compose finishes you have to be able to access the services in this urls:
|
||||
- Orders service: http://localhost:5102
|
||||
- Identity service: http://localhost:5105
|
||||
- Orders data (SQL Server): Server=tcp:localhost,5432;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;
|
||||
- Identity data (SQL Server): Server=localhost,5433;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -15,6 +15,8 @@
|
||||
using Ordering.Infrastructure;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public class Startup
|
||||
{
|
||||
@ -41,7 +43,7 @@
|
||||
{
|
||||
// Add framework services.
|
||||
|
||||
services.AddMvc(options=>
|
||||
services.AddMvc(options =>
|
||||
{
|
||||
|
||||
options.Filters.Add(typeof(HttpGlobalExceptionFilter));
|
||||
@ -52,7 +54,7 @@
|
||||
.AddDbContext<OrderingContext>(options =>
|
||||
{
|
||||
options.UseSqlServer(Configuration["ConnectionString"],
|
||||
sqlop=>sqlop.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name));
|
||||
sqlop => sqlop.MigrationsAssembly(typeof(Startup).GetTypeInfo().Assembly.GetName().Name));
|
||||
});
|
||||
|
||||
services.AddSwaggerGen();
|
||||
@ -96,12 +98,13 @@
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
OrderingContextSeed.SeedAsync(app).Wait();
|
||||
|
||||
app.UseMvc();
|
||||
app.UseMvcWithDefaultRoute();
|
||||
|
||||
app.UseSwagger()
|
||||
.UseSwaggerUi();
|
||||
|
||||
OrderingContextSeed.SeedAsync(app).Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
ordering.api:
|
||||
build:
|
||||
args:
|
||||
source: obj/Docker/empty/
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
environment:
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
- DOTNET_USE_POLLING_FILE_WATCHER=1
|
||||
volumes:
|
||||
- .:/app
|
||||
- ~/.nuget/packages:/root/.nuget/packages:ro
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
@ -1,9 +0,0 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
ordering.api:
|
||||
labels:
|
||||
- "com.microsoft.visualstudio.targetoperatingsystem=linux"
|
||||
volumes:
|
||||
- ~/clrdbg:/clrdbg:ro
|
||||
entrypoint: tail -f /dev/null
|
@ -2,21 +2,38 @@ version: '2'
|
||||
|
||||
services:
|
||||
ordering.api:
|
||||
image: eshop/ordering.api${TAG}
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: eshop/ordering.api
|
||||
environment:
|
||||
- ConnectionString=Server=ordering.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
ports:
|
||||
- "81:80"
|
||||
- "5102:80"
|
||||
depends_on:
|
||||
- ordering.data
|
||||
|
||||
ordering.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
- ACCEPT_EULA=Y
|
||||
- SA_PASSWORD=Pass@word
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "1433:1433"
|
||||
- "5432:1433"
|
||||
|
||||
identity.service:
|
||||
image: eshop/identity
|
||||
environment:
|
||||
- SpaClient=http://localhost:5104
|
||||
- ConnectionString=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
#- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105.
|
||||
- MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
ports:
|
||||
- "5105:5105"
|
||||
depends_on:
|
||||
- identity.data
|
||||
|
||||
identity.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
@ -38,6 +38,8 @@ namespace Microsoft.eShopOnContainers.WebMVC.Controllers
|
||||
|
||||
public IActionResult Signout()
|
||||
{
|
||||
HttpContext.Authentication.SignOutAsync("Cookies");
|
||||
HttpContext.Authentication.SignOutAsync("oidc");
|
||||
return new SignOutResult("oidc", new AuthenticationProperties { RedirectUri = "/" });
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,5 @@ FROM microsoft/aspnetcore:1.0.1
|
||||
ENTRYPOINT ["dotnet", "WebMVC.dll"]
|
||||
ARG source=.
|
||||
WORKDIR /app
|
||||
ENV ASPNETCORE_URLS http://*:80
|
||||
EXPOSE 80
|
||||
COPY $source .
|
||||
ENV ASPNETCORE_URLS http://0.0.0.0:5100
|
||||
COPY $source .
|
||||
|
@ -14,7 +14,8 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
var host = new WebHostBuilder()
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
//.UseIISIntegration()
|
||||
.UseUrls("http://0.0.0.0:5100")
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
|
||||
|
31
src/Web/WebMVC/README.md
Normal file
@ -0,0 +1,31 @@
|
||||
# Containerized eShop - Web Mvc
|
||||
Sample reference containerized application, cross-platform and microservices architecture.
|
||||
Powered by Microsoft
|
||||
|
||||
#Overview
|
||||
This sample runs a microservices oriented application and a .net core Mvc application that consumes this services. You can find more information about how to set up docker in your machine in the global directory solution.
|
||||
|
||||
#Deploy
|
||||
In the global directory you will find the scripts needed to run and deploy the demo into your local docker infraestructure.
|
||||
|
||||
- <a href='build-image-web.ps1'>build-image-web.ps1</a> <b>Build .net applications and docker images</b>: This power shell script that you will find in the <u>root directory of the solution</u> is the responsible of building .net applications and package in a pub folder and use docker commands to build the images needed to run the previously packaged .net applications.
|
||||
|
||||
- <b>Compose containers in your docker local VM</b>: Finally you have to open your favourite command tool pointing to the <u>root directory of this project</u> where docker-compose.yml file is located and run the command `docker-compose up`
|
||||
|
||||
#Run
|
||||
Once the deploy process of docker-compose finishes you have to be able to access the services in this urls:
|
||||
- Web: http://localhost:5100
|
||||
- Catalog service: http://localhost:5101
|
||||
- Orders service: http://localhost:5102
|
||||
- Basket service: http://localhost:5103
|
||||
- Identity service: http://localhost:5105
|
||||
- Orders data (SQL Server): Server=tcp:localhost,5432;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;
|
||||
- Catalog data (SQL Server): Server=tcp:localhost,5434;Database=CatalogDB;User Id=sa;Password=Pass@word
|
||||
- Identity data (SQL Server): Server=localhost,5433;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
- Basket data (Redis): listening in localhost:6379
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -9,6 +9,7 @@ using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
{
|
||||
@ -18,9 +19,12 @@ namespace Microsoft.eShopOnContainers.WebMVC.Services
|
||||
private HttpClient _apiClient;
|
||||
private readonly string _remoteServiceBaseUrl;
|
||||
|
||||
public CatalogService(IOptions<AppSettings> settings) {
|
||||
public CatalogService(IOptions<AppSettings> settings, ILoggerFactory loggerFactory) {
|
||||
_settings = settings;
|
||||
_remoteServiceBaseUrl = $"{_settings.Value.CatalogUrl}/api/v1/catalog/";
|
||||
|
||||
var log = loggerFactory.CreateLogger("catalog service");
|
||||
log.LogDebug(settings.Value.CatalogUrl);
|
||||
}
|
||||
|
||||
public async Task<Catalog> GetCatalogItems(int page,int take, int? brand, int? type)
|
||||
|
@ -12,6 +12,8 @@ using Microsoft.eShopOnContainers.WebMVC.Services;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Threading;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.eShopOnContainers.WebMVC
|
||||
{
|
||||
@ -20,17 +22,20 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
public Startup(IHostingEnvironment env)
|
||||
{
|
||||
var builder = new ConfigurationBuilder()
|
||||
.SetBasePath(env.ContentRootPath)
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
||||
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
|
||||
.SetBasePath(env.ContentRootPath)
|
||||
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) // Settings for the application
|
||||
.AddEnvironmentVariables(); // override settings with environment variables set in compose.
|
||||
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
// For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
|
||||
builder.AddUserSecrets();
|
||||
}
|
||||
//if (env.IsDevelopment())
|
||||
//{
|
||||
// // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
|
||||
// builder.AddUserSecrets();
|
||||
//}
|
||||
|
||||
//builder.AddJsonFile("appsettings.override.json");
|
||||
//builder.AddEnvironmentVariables();
|
||||
|
||||
builder.AddEnvironmentVariables();
|
||||
Configuration = builder.Build();
|
||||
}
|
||||
|
||||
@ -40,6 +45,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddMvc();
|
||||
services.Configure<AppSettings>(Configuration);
|
||||
|
||||
// Add application services.
|
||||
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
|
||||
@ -48,8 +54,6 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
services.AddSingleton<IOrderingService, OrderingService>(); //CCE: Once services are integrated, a singleton is not needed we can left transient.
|
||||
services.AddTransient<IBasketService, BasketService>();
|
||||
services.AddTransient<IIdentityParser<ApplicationUser>, IdentityParser>();
|
||||
|
||||
services.Configure<AppSettings>(Configuration);
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
@ -74,16 +78,23 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
|
||||
app.UseCookieAuthentication(new CookieAuthenticationOptions
|
||||
{
|
||||
AuthenticationScheme = "cookies",
|
||||
AuthenticationScheme = "Cookies",
|
||||
AutomaticAuthenticate = true,
|
||||
});
|
||||
|
||||
var identityUrl = Configuration.GetValue(typeof(string), "IdentityUrl");
|
||||
var callBackUrl = Configuration.GetValue(typeof(string), "CallBackUrl");
|
||||
var log = loggerFactory.CreateLogger("identity");
|
||||
|
||||
log.LogDebug(identityUrl.ToString());
|
||||
log.LogDebug(callBackUrl.ToString());
|
||||
|
||||
var oidcOptions = new OpenIdConnectOptions
|
||||
{
|
||||
AuthenticationScheme = "oidc",
|
||||
SignInScheme = "cookies",
|
||||
|
||||
Authority = "http://localhost:5000",
|
||||
SignInScheme = "Cookies",
|
||||
Authority = identityUrl.ToString(),
|
||||
PostLogoutRedirectUri = callBackUrl.ToString(),
|
||||
ClientId = "mvc",
|
||||
ClientSecret = "secret",
|
||||
ResponseType = "code id_token",
|
||||
@ -98,6 +109,7 @@ namespace Microsoft.eShopOnContainers.WebMVC
|
||||
oidcOptions.Scope.Add("orders");
|
||||
oidcOptions.Scope.Add("basket");
|
||||
|
||||
//Wait untill identity service is ready on compose.
|
||||
app.UseOpenIdConnectAuthentication(oidcOptions);
|
||||
|
||||
app.UseMvc(routes =>
|
||||
|
@ -27,9 +27,6 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-header col-sm-6 col-xs-4 text-center">
|
||||
@*@Html.ActionLink("Claims", "Claims", "Account")
|
||||
@Html.ActionLink("Call Api", "Claims", "Account")
|
||||
@Html.ActionLink("Log Out", "Signout", "Account")*@
|
||||
@await Html.PartialAsync("_LoginPartial")
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,7 +4,8 @@
|
||||
|
||||
@inject IIdentityParser<ApplicationUser> UserManager
|
||||
|
||||
@if(Context.User.Identity.IsAuthenticated)
|
||||
@*@if (Context.User.Identity.IsAuthenticated)*@
|
||||
@if (User.FindFirst(x => x.Type == "preferred_username") != null)
|
||||
{
|
||||
<form asp-area="" asp-controller="Account" asp-action="SignOut" method="post" id="logoutForm" class="navbar-right">
|
||||
<div class="nav navbar-nav navbar-right mt-15">
|
||||
|
@ -1,12 +1,9 @@
|
||||
{
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": "Server=127.0.0.1,5433;Database=aspnet-Microsoft.eShopOnContainers.WebMVC;User Id=sa;Password=Pass@word"
|
||||
//"DefaultConnection": "Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers.WebMVC;User Id=sa;Password=Pass@word"
|
||||
},
|
||||
"CatalogUrl": "http://localhost:5101",
|
||||
"OrderingUrl": "http://localhost:5102",
|
||||
"BasketUrl": "http://localhost:5103",
|
||||
"IdentityUrl": "http://localhost:5105",
|
||||
"CallBackUrl": "http://localhost:5100/",
|
||||
"Logging": {
|
||||
"IncludeScopes": false,
|
||||
"LogLevel": {
|
||||
@ -15,4 +12,4 @@
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,18 +9,59 @@ services:
|
||||
environment:
|
||||
- CatalogUrl=http://catalog.api
|
||||
- OrderingUrl=http://ordering.api
|
||||
- IdentityUrl=http://identity.service
|
||||
#- IdentityUrl=http://104.40.62.65:5105
|
||||
- IdentityUrl=http://identity.service:5105 #You need a entry in windows host file.
|
||||
- BasketUrl=http://basket.api
|
||||
- ASPNETCORE_ENVIRONMENT=Development
|
||||
ports:
|
||||
- "5100:80"
|
||||
- "5100:5100"
|
||||
depends_on:
|
||||
- catalog.api
|
||||
- identity.service
|
||||
- basket.api
|
||||
links:
|
||||
- identity.service:localhost # This line should be removed
|
||||
|
||||
identity.service:
|
||||
image: eshop/identity
|
||||
environment:
|
||||
- Spa=http://webspa
|
||||
- ConnectionString=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
- Mvc=http://webmvc
|
||||
ports:
|
||||
- "5105:5105"
|
||||
depends_on:
|
||||
- identity.data
|
||||
|
||||
identity.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
||||
|
||||
basket.api:
|
||||
image: eshop/basket.api
|
||||
environment:
|
||||
- ConnectionString=basket.data
|
||||
#- identityUrl=http://104.40.62.65:5105
|
||||
- identityUrl=http://identity.service:5105
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "5103:80"
|
||||
depends_on:
|
||||
- basket.data
|
||||
- identity.service
|
||||
|
||||
basket.data:
|
||||
image: redis
|
||||
|
||||
catalog.api:
|
||||
image: eshop/catalog.api
|
||||
environment:
|
||||
- ConnectionString=Server=catalog.data;Initial Catalog=CatalogData;User Id=sa;Password=Pass@word
|
||||
- ConnectionString=Server=catalog.data;Database=CatalogDB;User Id=sa;Password=Pass@word
|
||||
expose:
|
||||
- "80"
|
||||
ports:
|
||||
@ -42,44 +83,13 @@ services:
|
||||
- ConnectionString=Server=ordering.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
ports:
|
||||
- "5102:80"
|
||||
extra_hosts:
|
||||
- "CESARDLBOOKVHD:10.0.75.1"
|
||||
depends_on:
|
||||
- ordering.data
|
||||
|
||||
ordering.data:
|
||||
image: eshop/ordering.data.sqlserver.linux
|
||||
ports:
|
||||
- "5432:1433"
|
||||
|
||||
identity.service:
|
||||
image: eshop/identity
|
||||
expose:
|
||||
- "80"
|
||||
ports:
|
||||
- "5105:80"
|
||||
depends_on:
|
||||
- identity.data
|
||||
|
||||
identity.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
||||
|
||||
basket.api:
|
||||
image: eshop/basket.api
|
||||
environment:
|
||||
- ConnectionString=basket.data
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "5103:80"
|
||||
depends_on:
|
||||
- basket.data
|
||||
|
||||
basket.data:
|
||||
image: redis
|
||||
- "5432:1433"
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"userSecretsId": "aspnet-Microsoft.eShopOnContainers.WebMVC-946ae052-8305-4a99-965b-ec8636ddbae3",
|
||||
"userSecretsId": "aspnet-Microsoft.eShopOnContainers-946ae052-8305-4a99-965b-ec8636ddbae3",
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"version": "1.0.0",
|
||||
@ -73,6 +73,7 @@
|
||||
"Views",
|
||||
"Areas/**/Views",
|
||||
"appsettings.json",
|
||||
"appsettings.override.json",
|
||||
"web.config",
|
||||
"Dockerfile",
|
||||
"docker-compose.yml",
|
||||
|
@ -18,7 +18,7 @@ namespace eShopConContainers.WebSPA
|
||||
.UseConfiguration(config)
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
.UseUrls("http://localhost:1250/")
|
||||
//.UseUrls("http://localhost:1250/")
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
"ASPNETCORE_ENVIRONMENT": "Production"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
31
src/Web/WebSPA/eShopOnContainers.WebSPA/README.md
Normal file
@ -0,0 +1,31 @@
|
||||
# Containerized eShop - Web Spa
|
||||
Sample reference containerized application, cross-platform and microservices architecture.
|
||||
Powered by Microsoft
|
||||
|
||||
#Overview
|
||||
This sample runs a microservices oriented application and a .net core Mvc application that consumes this services. You can find more information about how to set up docker in your machine in the global directory solution.
|
||||
|
||||
#Deploy
|
||||
In the global directory you will find the scripts needed to run and deploy the demo into your local docker infraestructure.
|
||||
|
||||
- <a href='build-image-web-spa.ps1'>build-image-web-spa.ps1</a> <b>Build .net applications and docker images</b>: This power shell script that you will find in the <u>root directory of the solution</u> is the responsible of building .net applications and package in a pub folder and use docker commands to build the images needed to run the previously packaged .net applications.
|
||||
|
||||
- <b>Compose containers in your docker local VM</b>: Finally you have to open your favourite command tool pointing to the <u>root directory of this project</u> where docker-compose.yml file is located and run the command `docker-compose up`
|
||||
|
||||
#Run
|
||||
Once the deploy process of docker-compose finishes you have to be able to access the services in this urls:
|
||||
- Web: http://localhost:5104
|
||||
- Catalog service: http://localhost:5101
|
||||
- Orders service: http://localhost:5102
|
||||
- Basket service: http://localhost:5103
|
||||
- Identity service: http://localhost:5105
|
||||
- Orders data (SQL Server): Server=tcp:localhost,5432;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word;
|
||||
- Catalog data (SQL Server): Server=tcp:localhost,5434;Database=CatalogDB;User Id=sa;Password=Pass@word
|
||||
- Identity data (SQL Server): Server=localhost,5433;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
- Basket data (Redis): listening in localhost:6379
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
npm run build:prod
|
@ -1,3 +1,3 @@
|
||||
module.exports = {
|
||||
devtool: 'cheap-module-source-map'
|
||||
//devtool: 'cheap-module-source-map'
|
||||
};
|
||||
|
@ -9,25 +9,64 @@ services:
|
||||
environment:
|
||||
- CatalogUrl=http://catalog.api
|
||||
- OrderingUrl=http://ordering.api
|
||||
#- IdentityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105.
|
||||
- IdentityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
- BasketUrl=http://basket.api
|
||||
ports:
|
||||
- "5104:80"
|
||||
depends_on:
|
||||
- catalog.api
|
||||
- basket.api
|
||||
- identity.service
|
||||
|
||||
identity.service:
|
||||
image: eshop/identity
|
||||
environment:
|
||||
- SpaClient=http://localhost:5104
|
||||
- ConnectionString=Server=identity.data;Database=aspnet-Microsoft.eShopOnContainers;User Id=sa;Password=Pass@word
|
||||
#- MvcClient=http://104.40.62.65:5100 #Remote: VM Needs to have public access at 5105.
|
||||
- MvcClient=http://localhost:5100 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
ports:
|
||||
- "5105:5105"
|
||||
depends_on:
|
||||
- identity.data
|
||||
|
||||
identity.data:
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
||||
|
||||
basket.api:
|
||||
image: eshop/basket.api
|
||||
environment:
|
||||
- ConnectionString=basket.data
|
||||
#- identityUrl=http://104.40.62.65:5105 #Remote: VM Needs to have public access at 5105.
|
||||
- identityUrl=http://identity.service:5105 #Local: You need a entry in windows host file to run identity in local docker.
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "5103:5103"
|
||||
depends_on:
|
||||
- basket.data
|
||||
- identity.service
|
||||
|
||||
basket.data:
|
||||
image: redis
|
||||
|
||||
catalog.api:
|
||||
image: eshop/catalog.api
|
||||
environment:
|
||||
- ConnectionString=Server=catalog.data;Initial Catalog=CatalogData;User Id=sa;Password=Pass@word
|
||||
expose:
|
||||
- "80"
|
||||
- ConnectionString=Server=catalog.data;Database=CatalogDB;User Id=sa;Password=Pass@word
|
||||
ports:
|
||||
- "5101:80"
|
||||
depends_on:
|
||||
- catalog.data
|
||||
|
||||
catalog.data:
|
||||
image: eshop/mssql-server-private-preview
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
@ -40,39 +79,13 @@ services:
|
||||
- ConnectionString=Server=ordering.data;Database=Microsoft.eShopOnContainers.Services.OrderingDb;User Id=sa;Password=Pass@word
|
||||
ports:
|
||||
- "5102:80"
|
||||
# (Go to Production): For secured/final deployment, remove Ports mapping and
|
||||
# leave just the internal expose section
|
||||
# expose:
|
||||
# - "80"
|
||||
extra_hosts:
|
||||
- "CESARDLBOOKVHD:10.0.75.1"
|
||||
depends_on:
|
||||
- ordering.data
|
||||
|
||||
ordering.data:
|
||||
image: eshop/ordering.data.sqlserver.linux
|
||||
ports:
|
||||
- "5432:1433"
|
||||
|
||||
identity.data:
|
||||
image: eshop/mssql-server-private-preview
|
||||
image: microsoft/mssql-server-linux
|
||||
environment:
|
||||
- SA_PASSWORD=Pass@word
|
||||
- ACCEPT_EULA=Y
|
||||
ports:
|
||||
- "5433:1433"
|
||||
|
||||
basket.api:
|
||||
image: eshop/basket.api
|
||||
environment:
|
||||
- ConnectionString=basket.data
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "5103:80"
|
||||
depends_on:
|
||||
- basket.data
|
||||
|
||||
basket.data:
|
||||
image: redis
|
||||
- "5432:1433"
|
||||
|
@ -97,15 +97,16 @@
|
||||
"web.config",
|
||||
"config",
|
||||
"wwwroot",
|
||||
"dockerfile"
|
||||
"dockerfile",
|
||||
"wait-for-it.sh"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
// "prepublish": [
|
||||
// "npm install",
|
||||
// "node node_modules/webpack/bin/webpack.js --config config/webpack.config.vendor.js",
|
||||
// "node node_modules/webpack/bin/webpack.js --config config/webpack.config.js"
|
||||
// ],
|
||||
//"prepublish": [
|
||||
// "npm install",
|
||||
// "node node_modules/webpack/bin/webpack.js --config config/webpack.config.vendor.js",
|
||||
// "node node_modules/webpack/bin/webpack.js --config config/webpack.config.js"
|
||||
//],
|
||||
"postpublish": [
|
||||
"dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%"
|
||||
]
|
||||
|