Как создать работающий контейнер Docker с .NET 6.0?

Мне уже удалось создать рабочий контейнер с помощью Node и React. Сейчас я пытаюсь создать контейнер докеров для работы с простым исполняемым файлом С#, который будет прослушивать порт 8000 и отправлять обратно «hello world». Это работает, если я запускаю его локально, посетив http://localhost:8000/ Вот код:

using System;
using System.Net;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        string url = "http://localhost:8000/";
        HttpListener listener = new HttpListener();
        listener.Prefixes.Add(url);
        listener.Start();

        Console.WriteLine("Listening on {0}", url);

        while (true)
        {
            HttpListenerContext context = listener.GetContext();
            HttpListenerRequest request = context.Request;
            HttpListenerResponse response = context.Response;

            Console.WriteLine("{0} {1}", request.HttpMethod, request.Url);

            byte[] buffer = Encoding.UTF8.GetBytes("Hello, World!");
            response.ContentLength64 = buffer.Length;
            response.OutputStream.Write(buffer, 0, buffer.Length);
            response.OutputStream.Close();
        }
    }
}

Я построил программу и переместил ее в папку на рабочем столе:

Как видите, я создал Dockerfile со следующим содержимым:

FROM mcr.microsoft.com/dotnet/runtime:6.0      

WORKDIR /HelloWorld

COPY . .

EXPOSE 8000

CMD ["/HelloWorld/DockerTest.exe"]

Затем я построил изображение, используя:

docker build -t imagename:tagname .

А затем запустите контейнер, используя:

docker run --name containername -p 8000:8000 imagename:tagname

Контейнер немедленно завершает работу с кодом выхода 1, поэтому возникает ошибка, и он не создает журналы. Я думаю, что могу ошибаться, используя неправильный образ для среды выполнения .NET. (правильно ли mcr.microsoft.com/dotnet/runtime:6.0?) или забыл что-то еще в Dockerfile. Если у вас есть какие-либо вопросы, я буду рад дать вам более подробную информацию

Образ в Linux (если я правильно помню) в cmd использует dotnet HelloWorld.dll

Camadas 11.05.2023 11:42

Файл Docker просто копирует содержимое папки в образ, а не создает ваш проект. Вы спрашиваете, что создает шаблон проекта веб-API, если включить поддержку Docker. Сам код состоит из 4 строк в .NET 6 с использованием минимальных API. Попробуйте создать проект Minimal API либо в Visual Studio, либо в командной строке и установите параметр Docker Support.

Panagiotis Kanavos 11.05.2023 11:43

Да, докер использует Ubuntu, даже если я на Windows. Вы имеете в виду DockerTest.dll? Хорошо, я попытаюсь. Это должно быть до, после или вместо «/HelloWorld/DockerTest.exe»?

David 11.05.2023 11:44

Panagiotis проект уже построен и работает. Если я запускаю файл локально, я могу без проблем получить привет, мир из браузера. Контейнеризирует это, что вызывает у меня проблемы

David 11.05.2023 11:46

Вы должны фактически создать проект в самом файле Docker, а затем скопировать вывод в целевой образ. И VS, и VS Code добавят файлы Dockerfile, которые делают это с помощью команды. Взгляните, например, на быстрый старт ASP.NET Core в контейнере. Показанный здесь Dockerfile сначала компилирует проект в образ на основе SDK, а затем копирует выходные данные в образ на основе среды выполнения.

Panagiotis Kanavos 11.05.2023 11:46
is already built and working не совсем так. Если вы не попытаетесь запустить файл внутри папки bin\Release\net6.0\publish, вы копируете исходный код в образ, а не двоичные файлы. Попробуйте следовать инструкциям, прежде чем настраивать их, чтобы увидеть, как все работает на самом деле.
Panagiotis Kanavos 11.05.2023 11:49

@PanagiotisKanavos OP заявил, что файлы были вручную скопированы из выходной папки сборки в корневую (хотя это сомнительное решение, но оно должно работать с правильным используемым изображением / командой).

Guru Stron 11.05.2023 11:50

Панайотис построен. Я переместил файлы из bin\Release\net6.0\publish в папку на рабочем столе.

David 11.05.2023 11:50

Если вы строите на Windows, вы в любом случае получаете двоичные файлы Windows, которые не могут работать в контейнере Linux. Вот почему вам нужно собрать приложение в Dockerfile. В .NET 7 была добавлена ​​публикация напрямую в образы Docker , а это значит, что вы можете избавиться от Dockerfile и создать образ Docker через dotnet publish. Это показано в руководстве Публикация как контейнер.

Panagiotis Kanavos 11.05.2023 11:55

@GuruStron, если OP явно не опубликован для Linux, двоичные файлы будут неправильными. Здесь много пропущенных ручных шагов, много вещей, которые могли пойти не так.

Panagiotis Kanavos 11.05.2023 11:56

Да, я согласен с Панайотисом. Я новичок в этом, и я пытался перевести то, что я только что узнал, используя его для узла (узнал, следуя учебнику).

David 11.05.2023 11:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
11
123
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

mcr.microsoft.com/dotnet/runtime:6.0 — это контейнер Linux на основе Debian 11 — проверьте информацию на докер-хабе:

6.0.16-bulseye-slim-amd64, 6.0-bulseye-slim-amd64, 6.0.16-bulseye-slim, 6.0-bulseye-slim, 6.0.16, 6.0 Dockerfile Debian 11 03.05.2023

Поэтому он не может запускать .exe файлы, созданные для Windows.

Вам нужно либо переключиться на контейнер Windows, либо изменить команду на допустимую для Debian, например:

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

Также вы можете попробовать использовать инструменты VS, чтобы добавить поддержку Docker . Это должно создать многоэтапную сборку Docker-файла, который будет обрабатывать как сборку, так и создание результирующего образа.

P.S.

  • Также я бы рекомендовал создать проект ASP.NET Core (например, используя Минимальные API для простоты) вместо HttpListener напрямую.
  • localhost в "http://localhost:8000/" будет означать, что он будет принимать запросы только от локального хоста, который в случае докеризованного приложения будет самим контейнером - см. этот ответ для деталей и решений.

Спасибо Гуру. Можете ли вы объяснить мне пару вещей? ENTRYPOINT нужно поставить вместо CMD в Dockerfile? Предположим, я предпочитаю включить контейнер Windows, где и как его легко найти? Я получил этот контейнер через эту страницу: mcr.microsoft.com/product/dotnet/runtime/about Насколько мне известно, это официальный контейнер. Попытка найти такие слова, как Net6 и тому подобное, на Docker Hub дала мне только неофициальные источники. Спасибо!

David 11.05.2023 11:57

@ Дэвид, почему бы тебе не начать с руководств и кратких руководств, которые все это объясняют? Я разместил ссылки на документацию в комментариях, которые действительно показывают правильные файлы Dockerfile. Даже как можно свести все это к одному dotnet publish --os linux --arch x64 /t:PublishContainer -c Release в .NET 7

Panagiotis Kanavos 11.05.2023 11:58

@David, да, его следует использовать вместо CMD, посмотрите ссылку о добавлении поддержки Docker. Вы никогда не использовали образы докеров Windows TBH, в узле докеров перечислены Nano Server и Windows Server Core, вы можете попробовать один из них (некоторые документы).

Guru Stron 11.05.2023 12:00

Я сделаю это, Панайотис. Спасибо. Я просто воспользовался возможностью, чтобы спросить реального человека, который, возможно, мог бы добавить что-то еще, основываясь на своем опыте.

David 11.05.2023 12:00

@David просто создайте приложение ASP.NET Core с включенной поддержкой Docker. Он должен справиться с большинством проблем за вас.

Guru Stron 11.05.2023 12:01

@GuruStron Спасибо, но как мне найти эти изображения, если панель поиска выдает мне много несвязанных вещей? есть ли какая-то страница на DockerHub, где они перечислены? Извините, если вопрос глупый

David 11.05.2023 12:02

@David, они перечислены на странице, которая является первой ссылкой в ​​моем ответе.

Guru Stron 11.05.2023 12:03

@GuruStron Я имел в виду, как мне найти что-то еще, не спрашивая вас каждый раз :) Например, как мне перейти к Explore-> .NET Runtime из Explore. Если я наберу .NET Runtime в строке поиска, перед этим появится много вещей, таких как консул и моно.

David 11.05.2023 12:06

@David лично я использовал Google =)

Guru Stron 11.05.2023 12:08

О, хорошо xD Сделаю то же самое! Большое спасибо! Я пытался использовать ENTRYPOINT ["dotnet", "DockerTest.dll"], и теперь он фактически начинает говорить, что прослушивает порт 8000. Но когда я посещаю его на локальном хосте, я не получаю от него никакого ответа. Это улучшение.

David 11.05.2023 12:11

@David, посмотри этот ответ. Localhost будет локальным хостом контейнеров.

Guru Stron 11.05.2023 12:21

Еще раз спасибо. После обеда я перейду к уроку, который предоставил Панайотис. :) Теперь все работает!

David 11.05.2023 12:29

Другие вопросы по теме