Мне уже удалось создать рабочий контейнер с помощью 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. Если у вас есть какие-либо вопросы, я буду рад дать вам более подробную информацию
Файл Docker просто копирует содержимое папки в образ, а не создает ваш проект. Вы спрашиваете, что создает шаблон проекта веб-API, если включить поддержку Docker. Сам код состоит из 4 строк в .NET 6 с использованием минимальных API. Попробуйте создать проект Minimal API либо в Visual Studio, либо в командной строке и установите параметр Docker Support.
Да, докер использует Ubuntu, даже если я на Windows. Вы имеете в виду DockerTest.dll? Хорошо, я попытаюсь. Это должно быть до, после или вместо «/HelloWorld/DockerTest.exe»?
Panagiotis проект уже построен и работает. Если я запускаю файл локально, я могу без проблем получить привет, мир из браузера. Контейнеризирует это, что вызывает у меня проблемы
Вы должны фактически создать проект в самом файле Docker, а затем скопировать вывод в целевой образ. И VS, и VS Code добавят файлы Dockerfile, которые делают это с помощью команды. Взгляните, например, на быстрый старт ASP.NET Core в контейнере. Показанный здесь Dockerfile сначала компилирует проект в образ на основе SDK, а затем копирует выходные данные в образ на основе среды выполнения.
is already built and working не совсем так. Если вы не попытаетесь запустить файл внутри папки bin\Release\net6.0\publish, вы копируете исходный код в образ, а не двоичные файлы. Попробуйте следовать инструкциям, прежде чем настраивать их, чтобы увидеть, как все работает на самом деле.
@PanagiotisKanavos OP заявил, что файлы были вручную скопированы из выходной папки сборки в корневую (хотя это сомнительное решение, но оно должно работать с правильным используемым изображением / командой).
Панайотис построен. Я переместил файлы из bin\Release\net6.0\publish в папку на рабочем столе.
Если вы строите на Windows, вы в любом случае получаете двоичные файлы Windows, которые не могут работать в контейнере Linux. Вот почему вам нужно собрать приложение в Dockerfile. В .NET 7 была добавлена публикация напрямую в образы Docker , а это значит, что вы можете избавиться от Dockerfile и создать образ Docker через dotnet publish. Это показано в руководстве Публикация как контейнер.
@GuruStron, если OP явно не опубликован для Linux, двоичные файлы будут неправильными. Здесь много пропущенных ручных шагов, много вещей, которые могли пойти не так.
Да, я согласен с Панайотисом. Я новичок в этом, и я пытался перевести то, что я только что узнал, используя его для узла (узнал, следуя учебнику).





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.
HttpListener напрямую.localhost в "http://localhost:8000/" будет означать, что он будет принимать запросы только от локального хоста, который в случае докеризованного приложения будет самим контейнером - см. этот ответ для деталей и решений.Спасибо Гуру. Можете ли вы объяснить мне пару вещей? ENTRYPOINT нужно поставить вместо CMD в Dockerfile? Предположим, я предпочитаю включить контейнер Windows, где и как его легко найти? Я получил этот контейнер через эту страницу: mcr.microsoft.com/product/dotnet/runtime/about Насколько мне известно, это официальный контейнер. Попытка найти такие слова, как Net6 и тому подобное, на Docker Hub дала мне только неофициальные источники. Спасибо!
@ Дэвид, почему бы тебе не начать с руководств и кратких руководств, которые все это объясняют? Я разместил ссылки на документацию в комментариях, которые действительно показывают правильные файлы Dockerfile. Даже как можно свести все это к одному dotnet publish --os linux --arch x64 /t:PublishContainer -c Release в .NET 7
@David, да, его следует использовать вместо CMD, посмотрите ссылку о добавлении поддержки Docker. Вы никогда не использовали образы докеров Windows TBH, в узле докеров перечислены Nano Server и Windows Server Core, вы можете попробовать один из них (некоторые документы).
Я сделаю это, Панайотис. Спасибо. Я просто воспользовался возможностью, чтобы спросить реального человека, который, возможно, мог бы добавить что-то еще, основываясь на своем опыте.
@David просто создайте приложение ASP.NET Core с включенной поддержкой Docker. Он должен справиться с большинством проблем за вас.
@GuruStron Спасибо, но как мне найти эти изображения, если панель поиска выдает мне много несвязанных вещей? есть ли какая-то страница на DockerHub, где они перечислены? Извините, если вопрос глупый
@David, они перечислены на странице, которая является первой ссылкой в моем ответе.
@GuruStron Я имел в виду, как мне найти что-то еще, не спрашивая вас каждый раз :) Например, как мне перейти к Explore-> .NET Runtime из Explore. Если я наберу .NET Runtime в строке поиска, перед этим появится много вещей, таких как консул и моно.
@David лично я использовал Google =)
О, хорошо xD Сделаю то же самое! Большое спасибо! Я пытался использовать ENTRYPOINT ["dotnet", "DockerTest.dll"], и теперь он фактически начинает говорить, что прослушивает порт 8000. Но когда я посещаю его на локальном хосте, я не получаю от него никакого ответа. Это улучшение.
@David, посмотри этот ответ. Localhost будет локальным хостом контейнеров.
Еще раз спасибо. После обеда я перейду к уроку, который предоставил Панайотис. :) Теперь все работает!
Образ в Linux (если я правильно помню) в cmd использует dotnet HelloWorld.dll