Не удается запустить EntityFramework в Docker-compose с использованием Asp.net API.

Вопрос или проблема

Я пытаюсь запустить API .NET с MySQL в качестве базы данных, используя Entity Framework для настройки базы данных (то есть от API -> миграции MySQL).

API, похоже, работает хорошо, и я думаю, что MySQL тоже работает нормально. Однако, когда я пытаюсь сделать запрос, консоль Docker выдает эту ошибку:

mysql-1  | 2024-10-30T03:02:44.680273Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: готов к подключениям. Версия: '8.0.40'  сокет: '/var/run/mysqld/mysqld.sock'  порт: 3306  MySQL Community Server - GPL.                                                 
api-1    | fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
api-1    |       Не удалось выполнить DbCommand (44ms) [Параметры=[@p0='?' (DbType = Int32), @p1='?' (Size = 4000), @p2='?' (Size = 4000), @p3='?' (Size = 4000)], CommandType="Text", CommandTimeout="30"]                                                            
api-1    |       SET AUTOCOMMIT = 1;
api-1    |       INSERT INTO `User` (`Id`, `Email`, `Name`, `Password`)                                                           
api-1    |       VALUES (@p0, @p1, @p2, @p3); 

Я поделюсь файлами ниже. Дайте знать, если мне нужно поделиться чем-то еще для устранения этой проблемы.

Пробные файлы:

Dockerfile:

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["ApiNetEFMySQL.csproj", "."]
RUN dotnet restore "./ApiNetEFMySQL.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "./ApiNetEFMySQL.csproj" -c $BUILD_CONFIGURATION -o /app/build

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

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

docker-compose (Вы можете увидеть команды, которые я даю Entity Framework.):

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8080:8080"
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - ConnectionStrings__LocalConnection=Server=mysql;Port=3306;Database=testapi;User ID=root;Password=2870FJlw;
    depends_on:
      - mysql
    command: >
      sh -c "until nc -z mysql 3306; do echo 'Ожидание MySQL...'; sleep 2; done; dotnet ef database update; dotnet ApiNetEFMySQL.dll"
    networks:
      - my_network

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 2870FJlw
      MYSQL_DATABASE: testapi
    ports:
      - "3307:3306"
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
      - my_network

volumes:
  mysql_data:

networks:
  my_network:

Строка подключения:

  "ConnectionStrings": {
    "LocalConnection": "Server=mysql;Port=3307;Database=testapi;User ID=root;Password=<mypassword>;"
  }
}

На всякий случай файл Program.cs конфигурации для подключений:

var connection = builder.Configuration.GetConnectionString("LocalConnection") ??
        throw new InvalidOperationException("Строка подключения не найдена.");
builder.Services.AddDbContext<UserContext>(options =>
    options.UseMySql(
        connection,
        ServerVersion.AutoDetect(connection)));

Ответ или решение

Решение проблемы с запуском Entity Framework в Docker-Compose с использованием ASP.NET API и MySQL

Введение

При развертывании ASP.NET API с использованием Entity Framework и MySQL в окружении Docker могут возникнуть различные проблемы, включая ошибки подключения и неверные конфигурации. В этом руководстве мы рассмотрим, как устранить ошибки и корректно настроить ваше приложение для работы с Docker-Compose.

Проблема

В приведенном вами коде мы наблюдаем, что ASP.NET API не удается выполнить команду DbCommand в Entity Framework:

api-1    | fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
api-1    |       Failed executing DbCommand (44ms) [Parameters=[@p0='?' (DbType = Int32), @p1='?' (Size = 4000), @p2='?' (Size = 4000), @p3='?' (Size = 4000)], CommandType="Text", CommandTimeout="30"]                                                            
api-1    |       SET AUTOCOMMIT = 1;
api-1    |       INSERT INTO `User` (`Id`, `Email`, `Name`, `Password`) 
api-1    |       VALUES (@p0, @p1, @p2, @p3); 

Это означает, что API не может успешно вставить запись в таблицу User. Ошибка приложения может быть связана как с конфигурацией подключения, так и с отсутствием необходимых миграций.

Шаги по устранению проблемы

  1. Проверка конфигурации подключения:
    Убедитесь, что строка подключения в appsettings.json и Docker-Compose синхронизированы:

    "ConnectionStrings": {
       "LocalConnection": "Server=mysql;Port=3306;Database=testapi;User ID=root;Password=2870FJlw;"
    }

    В вашем docker-compose.yml вы указали порт 3306, что корректно. Обратите внимание, что в вашей строке подключения вы использовали Port=3307, это может вызывать проблемы.

  2. Изменение порта в строке подключения:
    Если вам нужно использовать порт 3307 (что обычно требуется для доступа из хоста), убедитесь, что вы изменили сервер в строке подключения API до порта 3306, который MySQL использует внутри контейнера:

    "ConnectionStrings": {
       "LocalConnection": "Server=mysql;Port=3306;Database=testapi;User ID=root;Password=2870FJlw;"
    }
  3. Убедитесь в наличии миграций:
    Проверьте, что у вас есть все необходимые миграции. Вы можете создать миграцию, используя команду:

    dotnet ef migrations add InitialCreate

    Затем выполните команду для обновления базы данных:

    dotnet ef database update
  4. Проверка Docker-Compose конфигурации:
    Проверьте секцию command в docker-compose.yml, вы можете разделить команды:

    command: >
     sh -c "until nc -z mysql 3306; do echo 'Waiting for MySQL...'; sleep 2; done; 
     dotnet ef database update; 
     dotnet ApiNetEFMySQL.dll"

    Так вы будете обновлять базу данных перед запуском API.

  5. Проверьте права доступа в MySQL:
    Убедитесь, что пользователь root имеет все необходимые права на создание таблиц и вы можете выполнить команду INSERT. Это можно сделать, если вы подключитесь к MySQL и выполните:

    GRANT ALL PRIVILEGES ON testapi.* TO 'root'@'%';
    FLUSH PRIVILEGES;
  6. Логи и отладка:
    Внимательно просмотрите логи вашего контейнера, чтобы понять причину отказа. Вы можете использовать команду:

    docker-compose logs api

Заключение

Следуя вышеуказанным шагам, вы сможете решить проблему с запуском Entity Framework и конфигурацией вашей .NET API в Docker-Compose с MySQL. Убедитесь, что ваша система настроена корректно и что все компоненты взаимодействуют между собой. Если проблема все еще сохраняется, рассмотрите возможность использования временного контейнера для диагностики.

Оцените материал
Добавить комментарий

Капча загружается...