Friday, December 30, 2016

Docker-Compose’ing an ASP.NET Core app that uses PostgreSQL database in Linux containers on Windows 10

Docker Compose is a tool for defining and running multi-container applications. In this post I will show you how you can create two containers. One will host a PostgreSQL database and the other will host an ASP.NET Core website. Docker Compose will build a virtual network that allows both containers to communicate with each other.

PostgreSQL is an open source relational database management system ( DBMS ) developed by a worldwide team of volunteers. PostgreSQL is not controlled by any corporation or other private entity and the source code is available free of charge.

The pre-requisites needed to proceed are:
  1. Windows 10 Professional or Enterprise (Anniversary Edition)
  2. Hyper-V enabled on the host Windows 10 operating system
  3. Yeoman command line interface
  4. .NET Core 1.0 is installed on your computer
You can get more information on installing the Yeoman command line interface at http://yeoman.io/codelab/setup.html.

Scaffolding an ASP.NET Core SQLite application with Yeoman


1) Open a command-line window in Windows 10.

2) In a suitable working directory on your hard-drive, create a folder named dev with the following command:
mkdir dev

3) Go into the newly created directory with:
cd dev

4) In the dev folder, create a file named global.json with the following content:
{
  "sdk": {
    "version": "1.0.0-preview2-003131"
  }
}
Note that for this example, we will be using ASP.NET Core version 1.0, as specified in the global.json file.

5) You will now use the Yeoman scaffolding tool to create an ASP.NET Core 1.0 application that uses the SQLite database. Type the following inside the dev folder:

yo aspnet

The following menu will display:

image_thumb1

6) Hit the down-arrow on your keyboard until you get to “Web Application” then hit ENTER.



7) Hit ENTER again to select Bootstrap.

image_thumb3image

8) When asked for an application name, type-in AspnetPostgres then hit ENTER. The application will get created for you. This is what it should look like when it is done:

image

9) Note these suggested instructions:
cd "AspnetPostgres"
dotnet restore
dotnet build
dotnet ef database update
dotnet run
Execute the above five instructions in sequence. Eventually, your command-line windows will be running the Kestrel web server listening on port 5000:

image

10) View the web application by pointing your browser to http://localhost:5000. This is what the web application, running on your host computer,  looks like:

image

Stop the web application by hitting CTRL + C on your keyboard and close your browser.
We are now ready to modify this application so that it uses PostgreSQL instead of SQLite.

Changing app so that it uses PostgreSQL instead of SQLite

We need to make only four changes to our current application so that it works with PostgreSQL instead of SQLite.
  1. Update the connection string in file appsettings.json
  2. Replace a SQLite dependency in file project.jsone with a PostgresSQL dependency
  3. In the Startup.cs file, specify that the app is using PostGresSQL and not SQLite.
  4. Also in Startup.cs, we will instruct the app to implement automatic database migration

1) The Connection String

Open appsettings.json in a text editor and make the following changes:

Replace:
"DefaultConnection": "Data Source=AspnetPostgres.db"
With:
"DefaultConnection": "User ID=docker;Password=docker;Host=db;Port=5432;Database=InstituteDB;Pooling=true;"
The appsettings.json file will eventually look like this:
{
  "ConnectionStrings": {
    "DefaultConnection": "User ID=docker;Password=docker;Host=db;Port=5432;Database=InstituteDB;Pooling=true;"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

2) PostgresSQL dependency

Open project.json in a text editor and make the following changes:

Replace:
"Microsoft.EntityFrameworkCore.Sqlite": "1.0.1",
"Microsoft.EntityFrameworkCore.Sqlite.Design": {
  "version": "1.0.0",
  "type": "build"
},
With:
"Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.0",

Restore

Before we touch any C# code, it is wise to restore dependencies. While in a command-prompt inside the AspnetPostgres directory, run the following command:

dotnet restore

3) Startup.cs file - use PostGresSQL instead of SQLite

Open Startup.cs in a text editor. Find the ConfigureServices() method and make the following changes:

Replace:
services.AddDbContext<ApplicationDbContext>(options =>
  options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
With:
services.AddDbContext<ApplicationDbContext>(options =>
  options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection")));

4) Startup.cs file – automatic database migration

Also, in the Startup.cs file find the Configure() method. We will use dependency injection to get an instance of the database ApplicationDbContext context class. To do this, add an additional argument to the Configure() method so that its signature looks like this:
public void Configure(
  IApplicationBuilder app,
  IHostingEnvironment env,
  ILoggerFactory loggerFactory,
ApplicationDbContext context)
At the bottom end of the Configure() method, add this line of code:

context.Database.Migrate();

Build

Build your application in a terminal window with the following command:

dotnet build

Dockerfile & Docker-Compose

We will deploy two containers. One with the PostgresSQL database and the other with our ASP.NET 1.0 Core application.

Linux containers will be used in this exercise. Therefore, right-click on the Docker (whale) icon in your system tray and make sure it displays:

image_thumb13

If it does not show the above message then you should switch to the Linux container.
Dockerfile
Create a text file in the AspnetPostgres folder named Dockerfile.linux and add to it the following content:
FROM microsoft/aspnetcore-build:1.0.3-projectjson
ENTRYPOINT ["dotnet", "run"]
ENV ASPNETCORE_ENVIRONMENT=Development
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet build
EXPOSE 80
I will explain what each command in Dockerfile.linux does.

FROM microsoft/aspnetcore-build:1.0.3-projectjson We will be using the official Microsoft docker container named microsoft/aspnetcore-build:1.0.3-projectjson as our starting image. This is a suitable container because it already has the .NET Core sdk + npm + bower. Also, it is based on .NET Core version 1.0, which is compatible to our web app.
ENTRYPOINT ["dotnet", "run"] The web application will be started by executing the “dotnet run” command which starts the web server.
ENV ASPNETCORE_ENVIRONMENT=Development We are setting the ASPNETCORE_ENVIRONMENT environment variable so that we can see detailed error messages. In production, you will change this to Production.
WORKDIR /app A directory named /app is created in the Linux container to host our source code.
COPY . . Our source code is copied from the YoAspnet folder on our Windows 10 computer to the /app folder in the Linux container.
RUN dotnet restore This command executes “dotnet restore” in the /app folder in the Linux container.
RUN build This command will build the application
EXPOSE 80 Port 80 is the port number that will be exposed by the container.

docker-compose.yml
Create a text file in the AspnetPostgres folder named docker-compose.yml and add to it the following content:
version: '2'
services:
  db:
    image: postgres
    environment:
      - POSTGRES_USER=docker
      - POSTGRES_PASSWORD=docker
  app:
    links:
      - db
    depends_on:
      - db
    ports:
      - 88:80
    build:
      context: .
      dockerfile: Dockerfile.linux
The above docker-compose.yml file describes two containers:

Container db will host the PostgresSQL database server. This container is built using the postgres image, which will be downloaded from http://hub.docker.com. A user named docker will be created also with password docker.

Container app will host our ASP.NET Core 1.0 application. This container is dependent on container db. The internal container port 80 will be exposed to the host as port 88. The context of the build process will be the current directory and the build process is defined in the Dockerfile.linux file, which we already scripted.

Executing docker-compose.yml

In a command-prompt, execute the following command in order to run docker-compose.yml:

docker-compose up

The instructions in the docker-compose.yml file will take about two minutes to complete. When it is done, you will see that the Kestrel web server is listening on port 80:

image

Open another instance of a terminal window and execute the following command to find out how many containers are running:
docker ps

There are two containers running. One is named aspnetpostgres_app_1 and the other is named aspnetpostgres_db_1.

image

Find out what virtual networks were created by executing the following command:

docker network ls

This reveals that a network named aspnetpostgres_default was created which both containers use to communicate with one-another:

image

Let us also find out where the data is being saved. Type the following command:

docker volume ls

This shows that a volume was created by PostGresSQL for the data:

image

This database volume will not be deleted automatically when the container is stopped or removed.

Now for the moment you have been waiting for: Point your browser to http://localhost:88. You should see our website being served from the ASP.NET Core 1.0 container:

image

Click on Register in the top-right corner and enter a user email and password:

image

After clicking on the Register button, you should see that the new user was indeed created:

image

Cleanup

Stop the terminal window that you used for docker-compose by hitting CTRL + C on the keyboard.
Type the following command to tear down all the containers and networks that were created by docker-compose.yml:

docker-compose down

At this stage, the database volume will still exist. To delete the database volume, type the following command:
docker volume prune

References:

https://docs.docker.com/compose/overview/

Thursday, December 29, 2016

ASP.NET Core 1.0 SQLite app in Windows Docker container on Windows 10 with yeoman

In a previous post, I showed how you can scaffold an ASP.NET Core 1.0 app that uses SQLite and deploy it into a Linux Docker container on Windows 10. In this post I will show you how to do the same thing, but instead in a Windows container rather than a Linux container.
If you are new to Docker on Windows 10, you can refer to a previous post that will help you install and configure it.
The pre-requisites needed to proceed are:
  1. Windows 10 Anniversary edition or later
  2. Hyper-V enabled on the host Windows 10 Anniversary operating system
  3. Yeoman command line interface
  4. .NET Core 1.0 is installed on your computer
You can get more information on installing the Yeoman command line interface at http://yeoman.io/codelab/setup.html.

Scaffolding an ASP.NET Core SQLite application with Yeoman


1) Open a command-line window in Windows 10.

2) In a suitable working directory on your hard-drive, create a folder named dev with the following command:
mkdir dev

3) Go into the newly created directory with:

cd dev

4) In the dev folder, create a file named global.json with the following content:
{
  "sdk": {
    "version": "1.0.0-preview2-003131"
  }
}
Note that for this example, we will be using ASP.NET Core version 1.0, as specified in the global.json file.

5) You will now use the Yeoman scaffolding tool to create an ASP.NET Core 1.0 application that uses SQLite as its database. Type the following inside the dev folder:

yo aspnet

The following menu will display:

image_thumb1

6) Hit the down-arrow on your keyboard until you get to “Web Application” then hit ENTER.

image_thumb3

7) Hit ENTER again to select Bootstrap.

image

8) When asked for an application name, type-in YoAspnetWin then hit ENTER. The application will get created for you. This is what it should look like when it is done:

image

9) Note these suggested instructions:
cd "YoAspnetWin"
dotnet restore
dotnet build
dotnet ef database update
dotnet run
Execute the above five instructions in sequence. Eventually, your command-line windows will be running the Kestrel web server listening on port 5000:

image

10) View the web application by pointing your browser to http://localhost:5000. This is what the web application, running on your host computer,  looks like:

image

Stop the web application by hitting CTRL + C on your keyboard.

We are now ready to deploy this SQLite database driven application into a Windows Docker container.

Writing code to create the database

We will be publishing a release version of our application and then deploy it into a Windows docker container. One of the instructions that we executed in the command line (dotnet ef database update) is intended to apply migrations and create the database. This cannot be done in production once our app is published. Instead, we will have to execute code in our application that creates the database according to our connection string.

The connection string is specified in appsettings.json file and its content is:
{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=YoAspnetWin.db"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}
Open the Startup.cs file in a text editor and find the Configure() method. We will use dependency injection to get an instance of the database ApplicationDbContext context class. To do this, add an additional argument to the Configure() method so that its signature looks like this:
public void Configure(
  IApplicationBuilder app,
  IHostingEnvironment env,
  ILoggerFactory loggerFactory,
  ApplicationDbContext context)
At the bottom end of the Configure() method, add this line of code:

context.Database.EnsureCreated();

EnsureCreated() is new EF core method which ensures that the database for the context exists. If it exists, no action is taken. If it does not exist then the database and all its schema are created and also it ensures it is compatible with the model for the context.

Eventually, the Configure() method will look like this:
public void Configure(
  IApplicationBuilder app,
  IHostingEnvironment env,
  ILoggerFactory loggerFactory,
  ApplicationDbContext context)       
{
  loggerFactory.AddConsole(Configuration.GetSection("Logging"));
  loggerFactory.AddDebug();

  if (env.IsDevelopment()) {
      app.UseDeveloperExceptionPage();
      app.UseDatabaseErrorPage();
      app.UseBrowserLink();
  } else {
      app.UseExceptionHandler("/Home/Error");
  }

  app.UseStaticFiles();
  app.UseIdentity();
  app.UseMvc(routes =>
  {
      routes.MapRoute(
          name: "default",
          template: "{controller=Home}/{action=Index}/{id?}");
  });
 
  context.Database.EnsureCreated();
}
Save your file then execute this statement from the command-line to ensure that your app compiles OK.
dotnet build

Deploying web app into Windows Docker container

We will be deploying our web app into a Windows container. Therefore, right-click on the Docker (whale) icon in your system tray and make sure it displays:

image

If it does not show the above message then you should switch to the Windows container.
We will next publish our application into a directory named out. Therefore, run the following instruction inside of a command-line window in the YoAspnetWin folder:

dotnet publish -c Release -o out

Have a peek at the files in the out folder. You will notice that it contains all the compiled files that make up the release version of our application:
image

Create a text file in the YoAspnetWin folder named Dockerfile.nano and add to it the following content:
FROM microsoft/dotnet:1.0-sdk-projectjson-nanoserver
ENTRYPOINT ["dotnet", "YoAspnetWin.dll"]
WORKDIR /app
ENV ASPNETCORE_URLS
http://+:82
EXPOSE 82
COPY out .
I will explain what each command in Dockerfile.nano does.

FROM microsoft/dotnet:1.0-sdk-projectjson-nanoserver We will be using the official Microsoft docker container named microsoft/dotnet:1.0-sdk-projectjson-nanoserver as our starting image. This is a suitable container because it already has the small Windows Nano server. It also has the .NET Core version 1.0 runtime, which is compatible to our web app. Note that it does not contain the .NET Core SDK, so we cannot run commands like dotnet restore, dotnet build, etc… in the container.
ENTRYPOINT ["dotnet", "YoAspnetWin.dll"] The web application will be started by executing the “dotnet YoAspnetWin.dll”. The name of the DLL file is dictated by the name of the containing folder during execution of the “dotnet publish” step, which we did previously.
WORKDIR /app A directory named /app is created in the Windows container to host our published app.
ENV ASPNETCORE_URLS http://+:82 The environment variable ASPNETCORE_URLS is set so that the listening Kestrel web server port in the container is 82.
EXPOSE 82 Port 82 is the port number that will be exposed by the container.
COPY out . The contents of the out folder is copied into the /app working directory in the container.

Inside a command-prompt in the YoAspnetWin folder, execute the following to build an image named dotnetweb/nano that contains our web app:

docker build -t dotnetweb/nano -f Dockerfile.nano .

This will download the microsoft/dotnet:1.0-sdk-projectjson-nanoserver container from http://hub.docker.com and subsequently build our new image. When it is done, you can type the following command to see all the images you have:

docker images

image

You will find at least these two images.
  1. dotnetweb/nano is the docker image we just built
  2. microsoft/dotnet:1.0-sdk-projectjson-nanoserver is the base image we used
To make a container from the image and run it, type the following command:

docker run -d -p 88:82 dotnetweb/nano

Run the following command to determine which containers are running:

docker ps

It should show the following running images:

image

You would think that we can access the web site using http://localhost:88. If you try that your browser will report back that the site can’t be reached. This is because there is a bug with Windows containers running under Windows 10 that does not allow that. The alternative, is to access the web server directly inside the container, which is being exposed on port 82. But, what is the IP address of the container? This is where the “docker inspect” command comes to the rescue. Grab the first two or three characters of the container-id. Looking as the previous screen-capture, the container-id is c1d. Therefore, then run the following command with your container-id:

docker inspect c1d

image

Grab the container’s IP address and try http://{container-ip-address}:82. In my case, this is http://172.29.131.95:82.

image

Yep. It works.

We must ensure that our database is indeed working. In order to do that, click on Register in the top-right corner of the web app and enter a user email and password:

image

After clicking on the Register button, you should see that the new user is successfully created:

image

Cleanup

To stop the container you can simply use the first two or three character of the container-id as follows:

docker stop c1d

To see which containers are still available, type:

docker ps -a

To delete the container completely, identify the first two to three character of the container-id then use the “docker rm” command similar to the following:

docker rm c1d

I you run “docker ps –a” again you will determine that the container is gone.
Find out what images you have by typing  the following command:

docker images

You can delete the image by id or by name, as follows:

docker rmi ce3
                    OR                           docker rmi dotnetweb/nano

After you remove the image you can again type “docker images” to prove that the image is indeed deleted.

Tuesday, December 27, 2016

ASP.NET Core 1.0 SQLite app in Linux Docker container on Windows 10 with yeoman

The Windows 10 anniversary edition has build-in support for Docker. In this tutorial I will show you how to scaffold and deploy a SQLite database driven ASP.NET core app and deploy it into a Linux Docker container. If you are new to Docker on Windows 10, you can refer to a previous post that will help you install and configure it.

The pre-requisites needed to proceed are:
  1. Windows 10 Anniversary edition or later
  2. Hyper-V enabled on the host Windows 10 Anniversary operating system
  3. Yeoman command line interface
  4. .NET Core 1.0 is installed on your computer
You can get more information on installing the Yeoman command line interface at http://yeoman.io/codelab/setup.html.

Scaffolding an ASP.NET Core SQLite application with Yeoman

1) Open a command-line window in Windows 10.

2) In a suitable working directory on your hard-drive, create a folder named dev with the following command:
mkdir dev

3) Go into the newly created directory with:
cd dev

4) In the dev folder, create a file named global.json with the following content:
{
  "sdk": {
    "version": "1.0.0-preview2-003131"
  }
}
Note that for this example, we will be using ASP.NET Core version 1.0, as specified in the global.json file.

5) You will now use the Yeoman scaffolding tool to create an ASP.NET Core 1.0 application that uses SQLite as its database. Type the following inside the dev folder:

yo aspnet

The following menu will display:

image

6) Hit the down-arrow on your keyboard until you get to “Web Application” then hit ENTER.

image

7) Hit ENTER again to select Bootstrap.

image

8) When asked for an application name, type-in YoAspnet then hit ENTER. The application will get created for you. This is what it should look like when it is done:

image

9) Note these suggested instructions:
cd "YoAspnet"
dotnet restore
dotnet build
dotnet ef database update
dotnet run
Execute the above five instructions in sequence. Eventually, your command-line windows will be running the Kestrel web server on port 5000:

image

10) View the web application by pointing your browser to http://localhost:5000. This is what the web application, running on your host computer,  looks like:

image

We are now ready to deploy this SQLite database driven application into a Linux Docker container.

Deploying web app into Linux Docker container

Stop the web application by hitting CTRL + C on your keyboard.

Delete the bin and obj folders as we do not need to copy these folders into the container.

We will be deploying our web app into a Linux container. Therefore, right-click on the Docker (whale) icon in your system tray and make sure it displays:

image

If it does not show the above message then you should switch to the Linux container.

Create a text file in the YoAspnet folder named Dockerfile.linux and add to it the following content:
FROM microsoft/aspnetcore-build:1.0.3-projectjson
ENTRYPOINT ["dotnet", "run"]
ENV ASPNETCORE_ENVIRONMENT=Development
WORKDIR /app
COPY . .
RUN dotnet restore
RUN dotnet ef database update
EXPOSE 80
I will explain what each command in Dockerfile.linux does.

FROM microsoft/aspnetcore-build:1.0.3-projectjson We will be using the official Microsoft docker container named microsoft/aspnetcore-build:1.0.3-projectjson as our starting image. This is a suitable container because it already has the .NET Core sdk + npm + bower. Also, it is based on .NET Core version 1.0, which is compatible to our web app.
ENTRYPOINT ["dotnet", "run"] The web application will be started by executing the “dotnet run” command which starts the web server.
ENV ASPNETCORE_ENVIRONMENT=Development We are setting the ASPNETCORE_ENVIRONMENT environment variable so that we can see detailed error messages. In production, you will change this to Production.
WORKDIR /app A directory named /app is created in the Linux container to host our source code.
COPY . . Our source code is copied from the YoAspnet folder on our Windows 10 computer to the /app folder in the Linux container.
RUN dotnet restore This command executes “dotnet restore” in the /app folder in the Linux container.
RUN dotnet ef database update This command executes “dotnet ef database update” in the /app folder in the Linux container.
EXPOSE 80 Port 80 is the port number that will be exposed by the container.

Inside a command-prompt in the YoAspnet folder, execute the following to build an image named dotnetweb/linux that contains our web app:

docker build -t dotnetweb/linux -f Dockerfile.linux .

This will download the microsoft/aspnetcore-build:1.0.3-projectjson container from http://hub.docker.com and subsequently build our new image. When it is done, you can type the following command to see all the images you have:

docker images

image

As you can see, there are two images.
  1. dotnetweb/linux is the docker image we just built
  2. microsoft/aspnetcore-build:1.0.3-projectjson is the base image we used
To make a container from the image and run it, type the following command:

docker run -d -p 5000:80 dotnetweb/linux

As you can see, the container’s port 80 is exposed to the host as port 5000.
If you now point your browser to http://localhost:5000/, you will see the web application served by our Linux container.

image

We need to ensure that our database is indeed working. In order to do that, click on Register in the top-right corner of the web app and enter a user email and password:

image

After clicking on the Register button, you should see that the new user was indeed created:

image

Cleanup

Let us stop the container and clean up the image.

To see which containers are running, type the following:

docker ps

Take note of the container-id. In my case it is ee92b47148e1. To stop the container you can simply use the first two or three character of the container-id as follows:

docker stop ee9

To see which containers are still available, type:

docker ps -a

To delete the container completely, identify the first two to three character of the container-id then use the “docker rm” command similar to the following:

docker rm ee9

I you run “docker ps –a” again you will determine that the container is gone.
Find out what images you have by typing  the following command:

docker images

You can delete the image by id or by name, as follows:

docker rmi 5cc
                     OR                           docker rmi dotnetweb/linux

After you remove the image you can again type “docker images” to prove that the image is indeed deleted.

Friday, December 23, 2016

Docker-izing SQL Server Express in a Windows Container

In this post, I will show you how to install the SQL Server Express database server inside of a Windows Docker container. In order to proceed with this tutorial, it is assumed that you have the following pre-requisites:
In this walkthrough, I am using Windows Containers on Windows 10 (Anniversary Edition).

Installing SQL Server Express Docker Container

Right-click on the whale docker icon in the tray and make sure it is in Windows Container mode. This is the case if it displays “Switch to Linux containers…” as shown below:

image


Open a command prompt and enter the following command:

docker run -d -p 1433:1433 --env sa_password=Sql!Expre55 --env ACCEPT_EULA=Y microsoft/mssql-server-windows-express

The switches used with the above docker command are explained below:

-p maps the container port number 1433 to the host computer’s port number. Needless to say, port 1433 is default for SQL Server
-d instructs docker to run in detached mode in the background
--env allows you to pass an environment variables into the container. We have two environment variables – namely: sa_password and ACCEPT_EULA. The password entered above is Sql!Expre55. Feel free to change the password to whatever you want. Just make sure that the password complies to the Microsoft SQL Server Strong Password Requirements. Failure to do so will result in “Invalid Password” errors when you attempt to login.

The container that we are downloading from Docker Hub is named microsoft/mssql-server-windows-express and is substantial in size. Be patient as it may take some time to download.
You will know that it is completed when you are returned to the terminal prompt. At this point, you can access and use the database server in three ways:
  1. You can use sqlcmd in windows authentication mode inside the container
  2. You can use sqlcmd in SQL Server authentication mode inside the container
  3. You can access the Docker-zed SQL Server database externally. We will use SQL Server Management Studio (SSMS) to access the database externally.

Using sqlcmd in windows authentication mode inside the container


Before we can access the database, we need to determine the container_id. This is done by typing the following docker command:
docker ps

This displays information about the running container:

CONTAINER ID        IMAGE                                    COMMAND                  CREATED             STATUS              PORTS                    NAMES
a66847266360        microsoft/mssql-server-windows-express   "cmd /S /C 'powers..."   8 minutes ago       Up 8 minutes        0.0.0.0:1433->1433/tcp   jolly_shaw


It suffices to grab the first three characters of the container_id. In the above example, this is a66. The next step is enter a sqlcmd prompt inside the container using windows authentication. This is done with the following docker command that uses the correct container_id:

docker exec -it a66 sqlcmd

The –i switch is for interactive and –t is for pseudo-TTY.

You will see a window that looks like this:

image







Enter the following pair of commands to display existing databases:
EXEC sp_databases
go
The output will look like this:

image

Type exit to close the sqlcmd terminal window.

Using sqlcmd in SQL Server authentication mode inside the container

Using the same container_id as before, type in the following docker command to get into a sqlcmd prompt:
docker exec -it a66 sqlcmd -S. –Usa

The –S switch points to the current server name and –U is for username.
When prompted for the password, enter the password that you entered when the container was first created. In the above example it is Sql!Expre55.

image

You will see a very similar prompt as in the previous example when Windows authentication was used.

Using SQL Server Management Studio to access the database externally

We will need the IP address of our SQL Server Docker container if we are to access it externally. You can obtain the IP address by using the “docker inspect” command with the appropriate container_id. In my case, I entered the following command:

docker inspect a66

This displays configuration data regarding the SQL Server Express container:

image

Grab the IP address from the Networks >> nat section as shown above. In my case, the container’s IP address is 172.27.237.190.

image

If all is well, you will be connected to the database.

image

Cleanup

To stop the container, you can enter the following docker command with the appropriate container_id:
docker rm -f a66

If you want to permanently delete the SQL Server Express image then you must determine the image_id first with this command:
docker images

Once you determine the image_id, the following docker command will permanently delete the image from your computer:
docker rmi d5c

References:
https://hub.docker.com/r/microsoft/mssql-server-windows-express/

Wednesday, December 21, 2016

Deploying ASP.NET Core 1.0 web app to a Linux Docker container on Windows 10

The Windows 10 anniversary edition has build-in support for Docker. In this tutorial I will show you how to:
  • install Docker on Windows 10 Anniversary edition
  • build an ASP.NET Core 1.0 web application using Visual Studio 2015
  • deploy ASP.NET Core 1.0 web application into a Linux Docker container image
  • run the ASP.NET Core 1.0 that resides in a Linux Docker container image from the Windows 10 host operating system
  • clean up our containers and images
The pre-requisites needed to proceed are:
  1. Windows 10 Anniversary edition or later
  2. Hyper-V enabled on the host Windows 10 Anniversary operating system
  3. Visual Studio 2015 with the latest updates
  4. .NET Core 1.0 is installed on your computer

Enabling Hyper-V virtualization

Let us start by enabling Hyper-V virtualization on your Windows 10 computer.

Control Panel >> Programs >> Turn Windows features on or off

image

image

Enable both Hyper-V & Containers then click OK. The computer may need to be restarted.

Download and install Docker for Windows

Go to https://docs.docker.com/docker-for-windows/.

image

At the time of writing, click on “Get Doclker for Windows (beta)”. This downloads a file named InstallDocker.msi. Run this file in order to install “Docker for Windows”. Once it is done you should see the whale icon in your system tray.

image

If you right-click on the whale icon, you will see the following options:

image

Click on Settings…

image

Click on “Shared Drives”.

image

Enable sharing of the C drive and any other drive that you may be using for the working directory when developing your ASP.NET Core 1.0 Web Application with Visual Studio 2015. When you are done, click on Apply then close the “Shared Drives” dialog.

Build your ASP.NET Core 1.0 web application in Visual Studio 2015

I am using Visual Studio 2015 to build an ASP.NET Core 1.0 application. Note that you can also use Visual Studio Code instead.

Start Visual Studio 2015 then follow these steps to create a vanilla ASP.NET Core 1.0 web application:

File >> New >> Project
Templates >> Visual C# >> Web

image

Select “ASP.NET Core Web Application (.NET Core)”, enter a decent web application name (like WebApp4Docker) then click on OK.

image

Select the “Web Application” template, make sure authentication is “No Authentication” to keep it as simple as possible. Also make sure “Host in the cloud” is unchecked then click on OK.
Wait a while while dependencies are restored then hit “Ctrl + F5” on the keyboard to run the application. This what your default browser should look like:

image

Close your browser.

Open the project.json file in Visual Studio. The first “dependencies” JSON block suggests that our application is running ASP.NET Core 1.0.1:

image

Deploy ASP.NET Core 1.0 application to Docker

Here’s a cheat sheet for some important Docker commands:

where docker show where docker is installed on your computer
docker info detailed information about your docker instance
docker version client and server versions of docker
docker ps docker processes
docker run hello-world download, install and run the hello-world container
docker stop 992 stop the docker container that starts with id = 992
docker ps -a display all containers
docker start 992 start container that starts with id = 992
docker images list downloaded images
docker rmi e43 delete image that starts with id = e43
docker run -d -p 85:80 asplinux run docker container named asplinux in detached mode (-d) with host port 85 mapped to container port 80
docker logs 992 show logs in container with id=992
docker history e43 show history of image with id = e43
docker cp . 992:/usr/html copy files in the current folder to /usr/html in container with id = 992
docker commit 992 star:101 product an image named star:101 from container with id = 992
docker volume ls list created volumes
docker network ls list networks
docker-compose up build service described in file named docker-compose.yml
docker-compose exec db bash start shell inside db service created by docker-compose

Create a text file named Dockerfile in the web project location. In my case this location is src/WebApp4Docker. Make sure that file Dockerfile has no extension.

image

Add the following content into Dockerfile:
FROM microsoft/aspnetcore:1.0.1
ENTRYPOINT ["dotnet", "WebApp4Docker.dll"]
ARG source=.
WORKDIR /app
EXPOSE 80
COPY $source .
This is what the above instructions mean:

Line 1 download and install a container named microsoft/aspnetcore:1.0.1 from http://dockerhub.com
Line 2 Execute command “dotnet WebApp4Docker.dll” to start the web application
Line 3 Declare a variable named source with value ‘.’
Line 4 The working directory in the Linux container is /app
Line 5 Port 80 is exposed in the Linux container
Line 6 Copy current directory on the host computer to /app in the Linux container

Open a command line in the web application folder (in my case src/WebApp4Docker) and execute the following:
dotnet publish

Copy Dockerfile from src/WebApp4Docker to src\WebApp4Docker\bin\Debug\netcoreapp1.0\publish.
Execute the following command to build an image that contains our web application in a Linux container:
docker build bin\Debug\netcoreapp1.0\publish -t asplinux

Run the image named asplinux that was just created in the background where port 80 in the container is mapped to port 8001 on the host computer:
docker run -d -p 8001:80 asplinux

To see which container is running in the background, type the following in the command line:
docker ps

You will see output similar to the following:

image

Now we should see the fruit of our hard work by experiencing our container deployed web application in a browser on the host. Open your favorite browser on your computer and go to http://localhost:8001. You should see the following:

image

Cleaning up

Let us stop the container and clean up the image.

To see which containers are running, type the following:

docker ps

Take note of the container id. In my case it is ee92b47148e1. To stop the container you can simply use the first three character of the id as follows:

docker stop ee9

you can also stop the container by referencing is name, like: docker stop asplinux
To see which containers are still available, type:

docker ps –a

To delete the container completely, identify the first three character of the id then use the “docker rm” command similar to the following:

docker rm ee9

I you run “docker ps –a” again you will determine that the container is gone.
Now let us see if the image named asplinux is still available. To find out, type the following command:

docker images

You can delete the image by id or by name, as follows:

docker rmi f60                     OR                           docker rmi asplinux

After you remove the image you can again type “docker images” to prove that our asplinux image is deleted.

In my next post I will discuss using a windows nano-server instead of Linux.

References:

http://www.hanselman.com/blog/ExploringASPNETCoreWithDockerInBothLinuxAndWindowsContainers.aspx