How can one dockerize a Terminal Gui application to run on Linux - c#

I have created a terminal app in C# .NET 6 using Terminal Gui. I have dockerized it
but for some reason every time i run the container it keeps exiting with 139, after looking at the logs it initially mentioned that it was missing libncursew.so.5/6 then i added apk add ncurses but after that now I'm getting that same 139 exit code but no additional detail in the logs.
Has anyone dockerized a Terminal.Gui app?
Thanks in advance

From you question I assumed that you are trying to dockerize Terminal.Gui on an alpine based container (you've mentioned an apk package manager).
Here is an example of dockerizing Terminal.Gui template app on an alpine linux image:
Create a template terminal gui app:
dotnet new --install Terminal.Gui.templates
dotnet new tui -n myproj
cd myproj
dotnet run
Publish it, so we'll be able to use it in a container:
dotnet publish -c Release -r linux-musl-x64 --self-contained
-r stands for run runtime, this is important since we'll be publishing our binaries on another OS, just to keep things working. This is a must for alpine linux, otherwise it won't work.
--self-contained means that we won't need to install dotnet framework on a machine where app will run
Create a dockerfile:
FROM alpine:latest
RUN apk add --no-cache ncurses musl-dev gcc icu bash
WORKDIR /app
COPY ./bin/Release/net6.0/linux-musl-x64/publish/ /app
CMD bash -c /app/myproj
ncurses, musl-dev, gcc, icu and bash are requirements of terminal.gui lib, I found it out via trial and error. Probably part of this is an overkill and you won't need to install full packages, just a little subset of libraries that come with those packages.
published app copied under /app folder in a container.
Build an image:
docker build -t tuiapp .
Create and run container:
docker run --tty --interactive --env TERM tuiapp
--tty this is a terminal gui app, have to instruct docker to assigne a pseudo tty
--interactive otherwise controls won't work
--env TERM have to pass TERM variable of a shell that invokes docker run. If your environment doesn't have TERM env variable set (like in windows terminal for example) you can set it explicitly, like this: ```--env TERM=xterm-256color``, tested it on windows terminal as well.
It should work, tested it on a ubuntu wsl, with tmux and without + tested it on a windows terminal from cmd.

Related

What is the difference between running a docker dotnet console app through Visual Studio and Docker Run?

Apologies if this is a dumb question, I am relatively new to Docker and this may simply be a misunderstanding on my part.
I have a dotnet 6 console app that is being deployed to Docker. When I run this via the Visual Studio Docker launch setting, it works fine, I can see the logs in Docker. However, if I go to the image in Docker Desktop, and launch it using the Run option, I don't see any logs, and as far as I can tell, the app does not actually run at all.
So what is the difference between the two ways of launching the container? Apart from that one works and one doesn't?!
I have tried supplying some of the same environment variable arguments that Visual Studio puts in it's own Docker Run command, but it doesn't seem to work.
Thanks!
Update: here is the dockerfile that I can reproduce the problem on - it's just the default one that VS generates when you Add Docker Support:
FROM mcr.microsoft.com/dotnet/runtime:6.0 AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["ConsoleApp1/ConsoleApp1.csproj", "ConsoleApp1/"]
RUN dotnet restore "ConsoleApp1/ConsoleApp1.csproj"
COPY . .
WORKDIR "/src/ConsoleApp1"
RUN dotnet build "ConsoleApp1.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ConsoleApp1.csproj" -c Release -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ConsoleApp1.dll"]
The app itself is just the boiler plate that gets created when you ask VS to add a new console app.
If I run through Visual Studio, it does indeed print "Hello, World!" - however, if I use the Run option against the Image in Docker Desktop, or I use Docker Run, the container spins up but there's nothing in the logs.
This happens on 2 different computers.
You've provided very little information about your project, so it's hard to say what is wrong. In general, running a console app in a container is very similar to running it outside the container.
If you take the following Dockerfile that creates a new console app and builds it
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
RUN dotnet new console -o . --name myapp
RUN dotnet publish -o /app
FROM mcr.microsoft.com/dotnet/runtime:6.0
WORKDIR /app
COPY --from=build /app .
CMD ["dotnet", "myapp.dll"]
you can then build and run it using
docker build -t test .
docker run --rm test
and it'll print out "Hello, World!" as it should.

Deploy Blazor Application to Google App Engine

I am trying to deploy a Blazor Server side application to the Google Cloud App Engine.
I have the base project that build when you select the Blazor Server App with docker enable for Linux, and put the following app.yaml in the project folder:
runtime: custom
env: flex
I then opened my gcloud console to this directory and did an app deploy, however this failed on step 7 in the boilerplate dockerfile. I noticed that the dockerfile had all of the project relevant files in a nested directory of the project name, so I removed the first folder from each of the docker commands:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["CallAssistant.csproj", "."]
RUN dotnet restore "CallAssistant.csproj"
COPY . .
RUN dotnet build "CallAssistant.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "CallAssistant.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "CallAssistant.dll"]
After this, I ran another gcloud app deploy and the deployment process completed, and on the google cloud console I was able to see the service running. However, when I tried to access the server I got a 502 Bad Gateway error on the home page, and subsequently in each of the nav pages nested in the app.
Does anyone know how to deploy a Blazor app to google app engine utilizing the docker image?
I figured this out. (It throws some weird errors occasionally though on the initial blazor project template)
If you copy the publish folder in the docker /app/ after publishing the project, then deploy using the app.yaml and dockerfile form the project directory, you can gcloud app deploy and it will work.
Here's my docker file:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
EXPOSE 8080
#------------------------------------------------------------------------------
# Copy publishing artifacts.
#------------------------------------------------------------------------------
WORKDIR /app
COPY bin/Release/net6.0/publish/ /app/
ENV ASPNETCORE_URLS=http://0.0.0.0:8080
#------------------------------------------------------------------------------
# Run application in Kestrel.
#------------------------------------------------------------------------------
ENTRYPOINT ["dotnet", "CallAssistant.dll"]

Execute compiled .NetCore console in docker

I wrote this small .net core app that backup and transfer mysql database from a server to a dockerized app. However, when I put it in docker and try to run it nothing happens. If there is an error in the app it should console.writeline the error message but nothing.
FROM mysql:5.7.34
COPY ./dbmover /tmp/dbmover
WORKDIR /tmp/dbmover
EXPOSE 3306
As you already figured out my released .net core app is contained in the dbmover folder and copied on the docker container.
Now if I connect to the container shell and execute the app I get no output of it. I run ./myapp.exe
There are my release settings for my app.
Note that this application is not meant to be dockerized it is just a tool to help build the container.
What am I doing wrong ?
SO I didn't noticed at first but I was publishing with visual studio instead of the command line tool. Once it is done publishing it is ginving you the path of the publish. What I ddin't notive is that it was the parent folder of the publishing folder which was linux-x64 folder. Once I took the linux-x64 subfolder instead of the main one it started working.

How to run an ASP.NET Core Web Application on Dockers container directly without using Visual Studio

I am trying to run an asp.net core web application from Dockers container without using Visual Studio but it is not running. I am following the steps listed in this tutorial on Microsoft site.
I have successfully done everything which are:
Creating Image.
Creating and running container with the ASP.NET Core Application.
The Dockers desktop shows that the image and container are both running.
The image (testn) screenshot:
The container (myapp) screenshot:
Now when I open the app url in the browser which is "http://localhost:8080/. I get "This page isn’t working" message. See below image:
My Dockerfile code is:
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy everything else and build
COPY . ./
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/sdk:5.0-buster-slim AS build
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "Testn.dll"]
I am using Lixus container in Dockers Desktop. My laptop OS is Windows 10 Home.
What I am missing?
Your 8080 port is just exposed, but not published dear.
You should publish your port when you are going to run the container from image like this:
docker run -d -p 8080:8080 testn:latest

Copy file from linux to windows share with C# (.NET core)

I'm using .NET core for an application running on a Linux machine (a docker container, to be exact)
How can I copy a binary file from there to a windows network share (including username & password)?
All solutions I've found were windows specific, but nothing related to Linux.
How about by using CIFS from Samba to mount the share. Once you've installed cifs-utils, you could try something like:
mkdir ~/localMountPoint
mount -t cifs //server/share ~/localMountPoint -o user=myname,pass=mypassword
There's a more in depth tutorial here: https://www.howtogeek.com/176471/how-to-share-files-between-windows-and-linux/
apt-get update && apt-get install smbclient -y
smbclient //IPADDRESS/shared -c 'put myfile.txt' -U mydomain/username%password -m SMB2
Using P/Invoke

Categories

Resources