Как поместить проект в Docker container, указать зависимости от других контейнеров, обращаться к сервису другого контейнера?

Есть мой ASP.NET 8 проект (сервер), мое .net 8 консольное приложение (клиент), образ minio (или какой-либо другой образ с docker hub). Нужно, чтобы клиент мог достучаться до сервера, который в докер контейнере, из докера и из хоста. Сервер должен общаться с minio, который тоже в докер контейнере.


Ответы (1 шт):

Автор решения: Lavshyak

Вещи, которые я долго гуглил или выпрашивал у уже "смешариков".

Dockerfile - файл со "скриптом", описывает по шагам, как билдить контейнер (аналог .sh скрипта, .bat, cmakelists.txt). Создается в папке проекта. Создал его Rider'ом (руками не писал), нормально работает. Мне понадобилось трогать там только EXPOSE - указывает порт, который будет открытым (оставил только EXPOSE 7666).

Пример (ASP.NET 8 проект):

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER $APP_UID
WORKDIR /app

EXPOSE 7666

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["MyServer/MyServer.csproj", "MyServer/"]
RUN dotnet restore "MyServer/MyServer.csproj"

COPY . .
WORKDIR "/src/MyServer"
RUN dotnet build "MyServer.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "MyServer.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "MyServer.dll"]

docker-compose.yaml - он нужен для конфигурации запуска контейнера(-ов). Создается в папке решения. Он сам запустит Dockerfile, если нужные контейнеры еще не собраны.

В Rider можно выполнить весь docker-compose.yaml (кнопка пуска около services), либо только какой-то конкретный сервис (запустить контейнер) (кнопка пуска около контейнера).

docker-compose.yaml можно выполнить из консоли, выполнив docker compose up в консоли в директории с этим файлом.

Как я понял, запускать контейнер в первый раз из интерфейса Docker Desktop (функционал ограничен) или запускать его из консоли без docker-compose.yaml (много букав писать) - кринж; ну и всё равно нужна автоматизация запуска и конфигурации.

В коде оставил комментарии, всё должно стать понятно.

#docker-compose.yaml

services: #далее перечисление контейнеров
  minio: #как назовем контейнер
    image: minio/minio:latest #docker image from docker hub
                              #(вроде должно само скачаться, если не скачано)
                              #вместо latest в проде следует использовать
                              #конкретную версию, на которой было протестировано,
                              #а то он упадет когда-нибудь.

    command: server --console-address ":9001" /data/

    ports: #проброс портов.
      - "9050:9070" #с хоста можно отправить запрос в http(s)://localhost:9050,
                    #он придет в 9070 порт внутри контейнера (если EXPOSEd)
      - "9000:9000"
      - "9001:9001"

    environment: #переменные среды)
      MINIO_ROOT_USER: aaa111
      MINIO_ROOT_PASSWORD: bbb222333
    volumes: #внизу файла обьявление томов, тут использование
      - minio-storage:/data #монтирует minio-storage как директорию /data

  myserver: #название контейнера, в котором будет мой сервер
    image: myserver #название образа (не с докер хаба, а локальное.
                    #появится в докере либо после запуска этого файла,
                    #либо докерфайла отдельно)

    ports:
      - "7777:7666"
    build:
      context: . #не знаю, что это. работает, не трогаю.
      dockerfile: MyServer/Dockerfile #путь к докер файлу проекта
                                      #относительно этого docker-compose.yaml,
                                      #Он будет выполнен при выполнении этого файла,
                                      #если сурскод потерял актуальность (не точно)
                                      #или image еще не создан
    depends_on: [minio] #перед запуском этого контейнера (myserver) сначала
                        #скачается/настроится/запустится контейнер minio
    volumes:
      - myserver-storage:/data
    environment:
#
      ASPNETCORE_URLS: "http://+:7666" #в ASP.NET 8 это позволяет задать порт 7666
                                       #как прослушиваемый, вместо дефолтного 8080.
                                       #если вместо http написать https, будет https (не факт, лучше загуглить)
                         #как я понял, launchSettings.json не актуален для докера

  client: #мой "клиент"
    image: client
    build:
      context: .
      dockerfile: Client/Dockerfile
    depends_on: [ myserver ] #перед запуском client должен быть запущен myserver
    environment:
      WEBAPI_URL: http://myserver:7666 #контейнер может стучаться в другой контейнер,
                                       #используя название контейнера
    volumes:
      - trash-storage:/data

volumes: #тома в докере. существуют независимо от контейнеров.
  minio-storage: #после двоеточия ничего можно не писать.
                 #будет создан том {название решения (.net)}_minio-storage
  myserver-storage:

Если в MyServer/Dockerfile не написать EXPOSE 7666, то из другого контейнера нельзя будет достучаться в этот по порту 7666, хост тоже не достучится по порту 7777. если написать EXPOSE 7666, но не написать ports: - "7777:7666", то из других контейнеров все равно можно достучаться в этого контейнер по 7666 порту .

Еще по этой теме:

→ Ссылка