-
Notifications
You must be signed in to change notification settings - Fork 10.3k
04. Setting eShopOnContainer solution up in a Mac, VS for Mac or with CLI environment (dotnet CLI, Docker CLI and VS Code)
Install Docker for Mac. The stable channel is fine.
The SQL Server image for Docker requires more memory to run. You will need to update your Docker settings to allocate at least 4 GB of memory:
Depending on how many apps you are running in your Mac you might need to assign more memory to Docker in the Mac. Usually, 4GB should suffice, but we got feedback from devs who needed to assign up to 8GB of ram to Docker in the Mac.
If your projects are placed within the /Users folder, you don't need to configure anything additional, as that is a pre-shared folder. However, if you place your projects under a different path, like /MyRootProjects, then you'd need to add that shared folder to Docker's configuration, here:
Since December 2017, eShopOnContainers supports Docker Multi-stage, therefore, the steps in order to compile the .NET apps/projects before creating the Docker images can now be performed with a single command based on "docker-compose build" or "docker build".
The quickest path to get eShopOnContainers running on your Mac is by using VS for Mac which will install most of the pre-requisites you need.
- Docker for Mac. (You should already have this installed)
- Visual Studio for Mac.
When installing Docker for Mac, you can select between multiple workloads or platforms.
Make sure you select the .NET Core platform:
Before completing the VS for Mac installation, it will demand you to install XCode, that is needed for multiple dependencies.
If you install Android as a target platform, Java will also be installed as a dependency for building mobile apps for Android.
For running just the Docker containers and web apps, you'd just need the .NET Core platform.
But if you want to try the eShopOnContainers mobile app, that requires Xamarin and therefore, the iOS and Android platforms, too. Those mobile platforms are optional for this Uncyclo walkthrough, though.
Open a bash shell and run the following command:
$ mkdir MyGitRepos
$ cd MyGitRepos
$ git clone https://github.com/dotnet-architecture/eShopOnContainers.git
$ cd eShopOnContainers
With that, you'll have the code at /Users/yourUser/MyGitRepos/eShopOnContainers folder.
Run Visual Studio for Mac and open the solution eShopOnContainers-ServicesAndWebApps.sln
.
If you just want to run the containers/microservices and web apps, do NOT open the other solutions, like eShopOnContainers.sln
as those solutions will also open the Xamarin projects and that might slow you down when testing due to additional dependencies in VS.
After opening the eShopOnContainers-ServicesAndWebApps.sln
solution for the first time, it is recommended to wait for a few minutes as VS will be restoring many NuGet packages and the solution won't be able to compile or run until it gets all the nuGet packages dependencies, in the first place (this time is only needed the first time you open the solution. Next times it is a lot faster).
This is VS for Mac with the eShopOnContainers-ServicesAndWebApps.sln
solution.
Make sure that the by default start-up project is the Docker project named docker-compose
.
Hit Ctrl+F5 or press the "play" button in VS for Mac.
IMPORTANT: The first time you run eShopOnContainers, it will take longer than the next time you launch it. Under the covers, Docker is pulling quite a few "heavy" images from Docker Hub (the public image registry), like the SQL Server image, Redis image, RabbitMQ image and the base ASP.NET Core images. That pull/download process will take a few minutes. Then, VS will launch the application custom containers plus the infrastructure containers (SQL, Redis, RabbitMQ and MongoDB), populate sample data in the databases and finally run the microservices and web apps on custom containers.
Note that you will see normal/controlled Http exceptions caused by our retries with exponential backoff, as the web apps have to wait until the microservices are ready for the first time which need first to run SQL sentences populating sample data, etc.
Once the solution is up and running, you should be able to see it in the browser at:
If you open a bash window, you can type docker images
and see the pulled/downloaded images plus the custom images created by VS for Mac:
And by typing docker ps
you can see the containers running in Docker. The infrastructure containers like SQL, Redis, RabbitMQ plus the custom containers running Web API microservices and the web apps.
IMPORTANT: In order to have the full app working, like being able to login with a user and add items to the basket and create orders, or being able to consume the services from a remote Xamarin or web SPA, you need to configure additional steps for the app, like the IP to be used by the Identity Service because it needs to be redirected, etc. - Check the additional configuration at the end of this post.
Option B: Use a CLI environment (dotnet CLI, Docker CLI with the bash shell) and VS Code as plain editor
- Docker for Mac. You should already have this.
- A Git client. The git-scm site maintains a great list of clients.
- (OPTIONAL) NPM installed with Node.js. The stable channel is fine as well.
- (OPTIONAL) Bower ($ sudo npm install -g bower) needed by the MVC web app.
- .NET Core and SDK. Install the SDK and runtime.
Local installation of NPM/Node, Bower and .NET Core SDK are not required when using Docker Multi-Stage
The SDKs and dependencies like NPM, Bower and even .NET Core SDK are optional because when building through Docker Multi-Stage it will be using the dependencies available within the ASP.NET Core build image, not the installed software on the local machine/PC. However, if you will be developing .NET apps in the Mac or customizing eShopOnContainers, it is recommended to install all the dependencies locally, as well.
Compile the application's projects and build the Docker images with a single command thanks to Docker Multi-Stage
The recommended approach is to build the .NET application/microservices bits and Docker images with a single command based on Docker Multi-Stage by simply running the following commands within the solution's root folder:
Move to the root folder of the solution:
cd YourPath\eShopOnContainers\
Then, run the following docker command:
docker-compose build
The first time you run this command it'll take some more additional time as it needs to pull/download the aspnet-build image with the SDKs, so it'll take its time.
It should take a few minutes to compile all the .NET Core projects plus the SPA application (Angular/TypeScript/JavaScript) which has additional processes and dependencies using NPM.
- When the
docker-compose build
command finishes, you can check out with Docker CLI the images created by typing in the PowerShell console the command:
docker images
Those Docker images you see are the ones you have available in your local image repository in your machine. You might have additional images, but at least, you should see the the custom images starting with the prefix "eshop" which is the name of the image repo. The rest of the images that are not starting with "eshop" will probably be official base-images like the microsoft/aspnetcore or the SQL Server for Linux images, etc.
With a single command you can deploy the whole solution into your local Docker host by just executing the following:
docker-compose up

Note that the first time you try to run the application (with docker run or docker-compose) it detects that it needs a few related infrastructure images, like the SQL Server image, Redis image, RabbitMQ image, etc. so it will pull or download those base images from the Internet, from the public repo at the Docker registry named DOCKER HUB, by pulling the "microsoft/mssql-server-linux" which is the base image for the SQL Server for Linux on containers, and the "library/redis" which is the base Redis image, and so on. Therefore, the first time you run "docker-compose up" it might take a few minutes pulling those images before it spins up your custom containers.
Finally, you can see how the scripts waits after deploying all the containers:

- The next time you run "docker-compose up" again, because you already have all the base images downloaded and registered in your local repo and your custom images built and ready to go, it'll be much faster since it just needs to deploy the containers, like the following screenshot:

- Check out the containers running in your Docker host: Once docker-compose up finishes, you will have the original PowerShell window busy and showing the execution's output in a "wait state", so in order to ask to Docker about "how it went" and see what containers are running, you need to open a second PowerShell window and type "docker ps" so you'll see all the running containers, as shown in the following screenshot.
Option B.1 is the recommended way to build your binaries before creating the Docker images as you'd be using the same Linux build-container with the SDKs that you can also use for your CI/CD pipelines in your DevOps system (that is VSTS, TFS, Jenkins, etc.). However, take into account the note below if you have that issue.
IMPORTANT NOTE (as of Oct. 2017):
This is the simplest way to do it from the CLI, and with the latest tests using the Docker build-container image with SDKs, microsoft/aspnetcore-build:2.0.2 we're not getting this issue, any more.
But if you get the following error when compiling from the Linux build-container:
MSBUILD : error MSB4017: The build stopped unexpectedly because of an unexpected logger failure.
ci-build_1 | Microsoft.Build.Exceptions.InternalLoggerException: The build stopped unexpectedly because of an unexpected logger failure. ---> System.IO.IOException: The process cannot access the file because it is being used by another process.
That is a bug in .NET CLI when running "dotnet publish" within a container.
If you get this issue, until the fix is released by the dotnet CLI team in the next version of the .NET CLI, in the meantime, follow the OPTION B.2 explained below, which is building the app's .NET binaries in the local Mac, instead of from a Linux build-container.
Open a bash shell and run the following four commands:
$ git clone https://github.com/dotnet-architecture/eShopOnContainers.git
$ cd eShopOnContainers
$ docker-compose -f docker-compose.ci.build.yml up
$ docker-compose up
The first two commands clone the git repository onto your machine, and changes the current directory to the root directory of the project.
The third command, docker-compose -f docker-compose.ci.build.yml up
creates a Docker container based on an image used for Continuous Integration (CI) builds. That image has all the required SDKs and tools loaded on it. These include .NET Core, the .NET Core CLI and SDK, npm, and required npm packages. Once the container starts, it will mount your source directory as a shared drive, then build and publish all the projects that make up the eShopOnContainers application.
The final command docker-compose up
pulls all the base Docker images needed, creates the images for each microservice, then launches each container that makes up the application.
Once the containers have launched, open a browser and navigate to http://localhost:5100
to visit the MVC application:
img/eShopOnContainersHomePage.png
You can also try the SPA style application by navigating to http://localhost:5104
. Here are where all the
services can be reached:
- MVC web app: `http://localhost:5100`
- SPA web app: `http://localhost:5105`
- Health Status web app: `http://localhost:5107`
- Catalog Microservice API: `http://localhost:5101`
- Ordering Microservice API: `http://localhost:5102`
- Basket Microservice API: `http://localhost:5103`
- Identity Microservice API: `http://localhost:5105`
- Payment API: `http://localhost:5108`
- Marketing API: `http://localhost:5110`
- Locations API: `http://localhost:5109`
To add items to the shopping cart or check out, you'll need to login to the site. The credentials for a demo user are:
- User: [email protected]
- Password: Pass@word1
The quick instructions above build all the projects that make up eShopOnContainers in a Docker Linux "build-container". That's the preferred way to build the application. It's easier to make sure all the prerequisites are installed, every developer uses the same version of all the tools, and you have a consistent experience from any build.
This section (B.1.1) is just a further explanation of that method.
As mentioned, the recommended approach is to build the .NET bits and Docker images by using an special build container from the CLI or your CI/CD pipeline. What you run and test locally is built using the same process as your CI/CD pipleine. The verions of all tools are the same, the same version of all SDKs are used, and so on. This ensures consistency across all builds.

The build container to use is based on the image: microsoft/aspnetcore-build
ASP.NET Core
build image which includes the .NET SDK, NPM and many other Web and ASP.NET dependencies
(Gulp, Bower, NPM, etc.) to build your services and web apps.
Contrast the four commands you ran above, along with the minimal prerequisites, with the list of prerequisites and tools needed to build locally on your machine.
You can build the application using your local Mac machine. You'll need the following prerequisites installed, in addition to those listed above for building using the CI container.
- Install [.NET Core and SDK](http://dot.net)*
- Install [Node LTS](http://nodejs.org)* - Just needed in order to use NPM.
- Bower ($ sudo npm install -g bower) needed by the MVC web app.
Install .NET Core 2.0 SDK or later, for Mac as shown in the image:
In order to be able to build the JavaScript dependencies from command line by using NPM you need to install npm globally.
NPM is bundled with NODE.JS. Installing NPM and NODE is pretty straightforward by using the installer package available at https://nodejs.org/en/
Install NodeJS 6.11.5 LTS or latest Long Term Service version
You can see the installed NPM version with the command npm -v, as shown below.
In bash, run the following command:
$ sudo npm install -g bower
As shown in the following screenshot:
You could generate the binaries manually, with 'dotnet publish', but for your convenience, we've included a bash script that runs all the 'dotnet publish' commands on your local Mac and generates the bits in the right folders expected by Docker and Visual Studio, if you use VS with the same solution, eventually.
Using the bash windows, navigate to your eShopOnContainers directory, and cd into the cli-mac directory. Then, run the build script:
$ ./build-bits.sh
This script runs a dotnet restore, build, and publish for each project using the dotnet
CLI tool.
In addition, it runs the client build commands using npm to build the SPA application
assets. Finally, it will remove old docker containers and images.
After you've finished the build, you can create the Docker images defined at the docker-compose.yml file within the solution's root directory, by using docker-compose build
:
First, move to the solution's root directory with cd ..
Check that you are in the folder where the docker-compose.yml files are, and finally run the following command:
$ docker-compose build
If you now run $ docker images
you'll see the eShopOnContainers images are now ready to be used by Docker.
To run the containers, you use docker-compose up
again:
$ docker-compose up
You could also go ahead and directly run docker-compose up
and it will first build the Docker images like when you run docker-compose build
, though.
Ignore the warnings about environment variables for Azure, as tyhat is only needed if you were using infrastructure services in Azure (SQL Database, Redis as a service, Azure Service Bus, etc.) which is the "next step" when using eShopOncontainers.
The first time you run docker-compose up
, it will pull the necessary docker images from Docker hub. That will take some time. Once the base Docker images have been pulled, the application will start and you can test it out using the browser and the addresses shown above.
For testing the MVC web app, run http://localhost:5100
in any browser, so you'll see the MVC app running like in the following screenshot:
You can also try/test the SPA (Single Page Application), which is based on Angular, by running this URL in a browser: http://localhost:5104
Configuring the app for Authentication and access from remote client apps (Remote access through the network)
If you don't configure these further settings, you should get the following error when trying to login in the MVC web app.
That is because the by default IP used to redirect to the Identity service/app used by the application (based on IdentityServer4) is the IP 10.0.75.1. That IP is always set up when installing Docker for Windows in a Windows 10 machine. It is also used by Windows Server 2016 when using Windows Containers.
eShopOnContainers uses that IP as the "by default choice" so anyone testing the app don't need to configure further settings. However, that IP is not used by "Docker for Mac", so you need to change the config.
If you were to access the Docker containers from remote machines or mobile phones, like when using the Xamarin app or the web apps in remote PCs, then you would also need to change that IP and use a real IP from the network adapter.
As explained here by Docker, the Mac has a changing IP address (or none if you have no network access). From June 2017 onwards our recommendation is to connect to the special Mac-only DNS name docker.for.mac.localhost which will resolve to the internal IP address used by the host.
In the docker-compose.override.yml
file, replace the IdentityUrl environment variable (or any place where the IP 10.0.75.1 is used) with:
IdentityUrl=http://docker.for.mac.localhost:5105
You could also set your real IP at the Mac's network adapter. But that would be a worse solution as it'll depend on the network you are connecting your Mac development machine..
Therefoire, the WebMVC service definition at the docker-compose.override.yml
should finally be configured as shown bellow:
webmvc:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=http://0.0.0.0:80
- CatalogUrl=http://catalog.api
- OrderingUrl=http://ordering.api
- BasketUrl=http://basket.api
- LocationsUrl=http://locations.api
- IdentityUrl=http://docker.for.mac.localhost:5105
- MarketingUrl=http://marketing.api
- CatalogUrlHC=http://catalog.api/hc
- OrderingUrlHC=http://ordering.api/hc
- IdentityUrlHC=http://identity.api/hc
- BasketUrlHC=http://basket.api/hc
- MarketingUrlHC=http://marketing.api/hc
- PaymentUrlHC=http://payment.api/hc
- UseCustomizationData=True
- ApplicationInsights__InstrumentationKey=${INSTRUMENTATION_KEY}
- OrchestratorType=${ORCHESTRATOR_TYPE}
- UseLoadTest=${USE_LOADTEST:-False}
ports:
- "5100:80"
If you re-deploy with docker-compose up
, now the login page should work properly, as in the screenshot below.
NOTE: For some reason, if using SAFARI browser, it cannot reach docker.for.mac.localhost but using Chrome in Mac, it works with no issues. Since the usage of docker.for.mac.localhost is just for development purposes, just use Chrome for tests.
If using the services from remote apps, like the a phone with the Xamarin mobile app in the same Wifi network, or the web apps accessing remotely to the Docker Host, you need to change a few by-default URLs.
eShopOnContainers app uses the .env file to set certain by-default environment variables used by the multiple docker-compose.override you can have.
Therefore, the following change must be done in the .env file at the root of the eShopOnContainers folder. If you don't see the .env file, run the following command and re-start the Finder:
$ defaults write com.apple.finder AppleShowAllFiles TRUE
$ killall Finder
Then, edit the .env file (with VS code, for instance) and change the ESHOP_EXTERNAL_DNS_NAME_OR_IP variable, and instead of using "localhost" as value, set a real IP or a real DNS name:
`
ESHOP_EXTERNAL_DNS_NAME_OR_IP=192.168.0.25
`
or
ESHOP_EXTERNAL_DNS_NAME_OR_IP=myserver.mydomain.com
This is something you'll want to do if deploying to a real Docker Host, like in a VM in Azure, where you can use a DNS name for that.
We'd appreciate to your feedback, improvements and ideas. You can create new issues at the issues section, do pull requests and/or send emails to [email protected]
[QUESTION] Answer +1 if the solution is working for you on the Mac: https://github.com/dotnet/eShopOnContainers/issues/107
- System requirements
- Development setup
- Databases & containers
- Architecture
- Application
- Code
- Logging and Monitoring
- Tests