What's up guys, Eze here. Again, those who follow me on Twitter (if you are not a follower you better do it now @skielo) already know I've been working on an app to show you how to create an Angular 2 app using a, ASP.NET Core 1.1 Web API with a MongoDB database and using all those components in different Docker containers. Today I want to show you how easy is to get up and running an Angular 2 app and connect it to ASP.NET Core 1.1 Web API to retrieve data from a MongoDB database. Sounds amazing, right? Well this will be the first out of a series of posts where we are going to find out more about those tools
The Front-End Skeleton
First, we need to build the front-end and the backend for our app. As I already told you, the front-end will be an Angular 2 app. To create it we are going to use the Angular CLI tool. There is nothing new here, and you can follow the steps I already wrote here. The only difference is this time we are creating a server.js file which will be our entry point in the Docker container.
The Backend Skeleton
Well, the backend will be an ASP.NET Core 1.1 Web API. This API will receive a request from the front-end, get/put data to the database, and provide a response. To create this application, we will use the Yeoman generator. So let's first install all the required dependencies by running the following command:
npm install -g yo firstname.lastname@example.org generator-docker. This will install the latest version of the Yeoman tool, plus the latest generator for ASP.NET projects and a Docker generator. The last one is not completely necessary, but it's good to have it.
Creating the Code
Once we have all the required tools by executing this command, ASP.NET Yeoman will create a small web API project. In order to test if our project has been created correctly, we need to navigate to the project folder and execute this command:
dotnet restore and then dotnet run. When the server has started, we can browse this URL, http://localhost:5000/api/values, to test our web API.
In order to create a data layer to access MongoDB from our Web API project, I'm using MongoDBDriver for C#. Basically, I'm using the repository pattern; if you want to know more about that please follow this link. Something which is important to highlight is that within the connection string I'm using as a server name/IP address, the name mongodb appears after the Docker image. I will go into more details later.
Then, I created a new web API controller to handle the request from our Angular 2 app.
Well, we are almost ready to go. In order to complete our system, we need to get the right version of Docker according with our operating system. Please follow this link to get it. Also, it's important to know that we will require the docker-toolbox; you can find it here. This toolbox will create the Docker machine in our computer and using this console we will interact with our Docker application.
After running this command, yo docker, and selecting .NET Core as a project, we need to follow some bootstrapping scripts to create the docker files in our project. Regardless of the structure used by this tool in my project, I've created a folder called .docker where I place the created dockerfile. This is a recommendation by @DanWahlin.
Exploring the Dockerfile
In the dockerfile, we will find the instructions to build and run our images with Docker. In the example below, we instruct Docker to base our image in one from the docker hub: microsoft/dotnet:latest. But, what does that mean? Well, that means that we are going to use the official docker image created by Microsoft to run a .NET app. Then we select which port will be available within our container and which is the entry point for this image.
FROM microsoft/dotnet:latest WORKDIR /app COPY bin/Debug/netcoreapp1.1/publish /app ENV ASPNETCORE_URLS http://*:80 EXPOSE 80 ENTRYPOINT ["dotnet", "WebAPIApplication.dll"]
Exploring the Docker-Compose File
This is the file we are going to use to build our images. In this file, we specify all the characteristics of our images. We also define the container_name (otherwise docker will pick a funky name on runtime for us), the image we want to use, the internal and external port for the container, and, something which is really cool, the network. This network specification will allow us to talk between one container and another. As you can see in the code below, I'm using mongodb as the container_name for the database, just like I did in the connection string of our web API.
version: '2' services: webapiapplication: container_name: webapiapplication image: webapiapplication build: context: . dockerfile: .docker/Dockerfile ports: - "80:80" networks: - webapi-network node: container_name: nodeapp image: nodeapp build: context: . dockerfile: .docker/Dockerfile environment: - NODE_ENV=development ports: - "3000:3000" networks: - webapi-network mongodb: container_name: mongodb image: mongo networks: - webapi-network networks: webapi-network: driver: bridge
Start the Engine
Now, we have our applications ready, we've configured the containers, and it's time to start our system. The first step is to build and publish our .NET Core app. By running the commands (
dotnet build and
dotnet publish) we will do that. Then we need open the Docker Toolbox terminal. This will initialize our Docker machine.
If you are running Docker in Windows, you probably are using hyper-v. If this is the case, you might have to edit the start.sh file for your docker-toolbox in order to use hyperv as a driver and a virtual switch.
docker-machine create --driver hyperv --hyperv-virtual-switch "My Internal Switch"
Once the toolbox terminal is done, we need to navigate to our project folder and run the command
docker-compose build. This will build our images, and, after that, by running
docker-compose up -d, Docker is going to start up all our images and keep it running in daemon mode. And that's it, our applications will all work together. Because the images are running in daemon mode, we can check the logs by executing
docker-compose logs. There is another useful command,
docker ps -a, which will show us all the instances of our images.
If you want to see the full code working together, I have a working example here. Be aware that this is only an example, it is not meant to be used in a production environment because, as you can see, the database doesn't have any security at all. If you want more details, please follow the official documentation.
If you found this post useful please don't forget to press the like button and share it. If you are confused, don't hesitate to ask a question and, as always, thank you for reading.