1
votes

I'm trying to containerize my .net core 3.1 service into linux Docker container. This service works with a SQL Server database, so I have a docker-compose as follows:

version: "3.5"

services:
    back:
        build: 
            context: ../../
            dockerfile: local_deploy/back/docker
        container_name: api
        restart: always
        environment:
          - ASPNETCORE_ENVIRONMENT=Development
        depends_on:
          - db-server
        ports:
          - "7000:80"
        networks:
          - localdev

    db-server:
        image: microsoft/mssql-server-linux:2017-latest
        container_name: db-server
        environment:
          - ACCEPT_EULA=Y
          - MSSQL_SA_PASSWORD=1234
          - MSSQL_TCP_PORT=1433
        ports:
          - "1400:1433"
        networks:
          - localdev

networks:
  localdev:
    name: localdev

To run this docker-compose I have a up.bat file into local_deploy/back directory inside the root folder of the solution:

@echo off

echo Starting build
rd ..\..\out /s /Q
dotnet restore ../../MySimpleService.sln -s http://nexus.tools.example.com/nuget-v2/ -s https://nexus.eas.example.com/repository/nuget-hosted/
dotnet publish ../../MySimpleService.sln -c Release --force -o ../../out - /property:Version=1.0.0 /p:ASPNETCORE_ENVIRONMENT=Development

echo Starting containers
docker-compose up --build -d

And, finally, here is a docker file:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
COPY out ./
ENTRYPOINT ["dotnet", "MySimpleService.dll"]

All these three files are into local_deploy/back directory.

When I run up command in cmd, container is successfully built.

The problem is that the service also uses NATS as a message broker so it is down inside of a container because it can't establish connection with NATS.

To install and use NATS on my local machine I have to install a msi file prepared by our team. After installing this msi on my machine, I can run MySimpleService successfully locally.

So, my guess, to run this service into container I should also install this msi into container. I tried to edit my docker file:

FROM mcr.microsoft.com/dotnet/core/aspnet:3.1

SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]

COPY out ./

RUN (New-Object System.Net.WebClient).DownloadFile('https://nexus.eas.example.com/repository/mars-nats-streaming-business/NatsStreaming_2.1.4-alpha386.msi', 'c:\tools\NatsStreaming_2.1.4-alpha386.msi') ;\
    Start-Process 'msiexec' -ArgumentList '/i c:\tools\NatsStreaming_2.1.4-alpha386.msi /quiet /qn /norestart /log c:\tools\installNatsStreaming.log'; \
    Start-Sleep -s 30 ;\
    Remove-Item c:\tools\*.msi -force

ENTRYPOINT ["dotnet", "MySimpleService.dll"]

But I get an error:

Service 'back' failed to build : OCI runtime create failed:
container_linux.go:370: starting container process caused: exec:
"powershell": executable file not found in $PATH: unknown

Now my guess is that I should install a powershell into container.

Any help would be highly appreciated.

1
You are trying to install contents designed for Windows (.msi file) into a container. You will need a Windows container for this. You can't install it into a Linux container. It's not just powershell, but paths like c:\tools and the command msiexec don't work in Linux. I dont think you can run Windows containers on Linux at all. - omajid
NATS seems to be available for Linux as well. Can you install that Linux binary instead of the msi? Also, it sounds like you are trying to run two things in a container: the NATS broker and your .NET application. That's not a good design: just like your db server runs in a separate container, so should the message broker. - omajid
@omajid, yeah, I had a thought that .msi file could be installed only in Windows container. And you confirmed my thought. Thanks for your proposals, I will try them. - Dmitry Stepanov
A continuation of this story goes on this post - Dmitry Stepanov

1 Answers

0
votes

I would say that your guess (Now my guess is that I should install a powershell into container.) is correct, yes :)

I had a similar problem and opted to replace the PowerShell command by a shell command, which ensures compatibility.

However, if you cannot replace your PowerShell command by a suitable shell, then, you may use the PowerShell in Docker, following the documentation.