Docker部署.NET 6 API连接MariaDB报未配置连接字符串错误
问题根因
报错System.InvalidOperationException: "A relational store has been configured without specifying either the DbConnection or connection string to use."由三处配置错误共同触发:
- DbContext配置冲突+读取配置路径错误:你在Program.cs中已经通过
AddDbContext使用Pomelo的UseMySql方法配置了MariaDB连接,但又在MariaDbContext的OnConfiguring方法中调用了Oracle官方驱动的UseMySQL方法重复配置,同时读取连接串的路径写错——连接串存放在ConnectionStrings节点下,直接用_config["MariaDbConnectionString"]读取到的值为null,相当于给UseMySQL传入了空连接串,直接触发报错。另外你写的DbContext构造函数没有接收DI容器传入的DbContextOptions参数,Program.cs里配置的连接参数根本没有被DbContext使用。 - Dockerfile路径配置错误:文件复制、restore、build的路径不匹配,会导致发布后的运行目录中缺失appsettings.json配置文件,运行时读不到任何连接字符串配置。
- Docker Compose服务启动顺序不合理:
depends_on默认只保证容器启动顺序,不等待MariaDB服务完成初始化,数据库还没就绪时后端就发起连接,也会触发连接相关错误。
修复步骤
1. 修正DbContext代码
删除重复错误的OnConfiguring配置,修改构造函数接收DI传入的配置项,不要在DbContext内部重复读取配置做连接设置:
public class MariaDbContext : DbContext { public MariaDbContext(DbContextOptions<MariaDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); } }
注意:Pomelo.EntityFrameworkCore.MySql的UseMySql和Oracle官方驱动的UseMySQL属于不同的EF Core提供器,二者不能混用,否则会出现提供器冲突。
2. 修正Dockerfile路径配置
调整文件复制、还原、构建的路径,确保配置文件能被正确复制到发布目录:
FROM mcr.microsoft.com/dotnet/aspnet:6.0-focal AS base WORKDIR /app EXPOSE 80 EXPOSE 443 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["src/Family-Chronicles-Server.csproj", "src/"] RUN dotnet restore "src/Family-Chronicles-Server.csproj" COPY . . WORKDIR "/src/src" RUN dotnet build "Family-Chronicles-Server.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "Family-Chronicles-Server.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "Family-Chronicles-Server.dll"]
同时确认项目中appsettings.json和appsettings.Development.json的文件属性设置为「如果较新则复制」,保证配置文件会被输出到发布目录。
3. 修复Docker Compose服务就绪判断
给MariaDB添加健康检查,配置后端服务等待数据库完全就绪后再启动,修改docker-compose.yml对应部分:
services: mariadb: image: mariadb:10.7 restart: always ports: - "3307:3306" environment: - MYSQL_ROOT_HOST=% - MYSQL_ROOT_PASSWORD=family-chronicles-maria-root - MYSQL_DATABASE=family-chronicles - MYSQL_USER=family-chronicles - MYSQL_PASSWORD=family-chronicles-maria volumes: - mariadb_data:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-pfamily-chronicles-maria-root"] interval: 5s timeout: 5s retries: 10 # phpmyadmin、mongodb、mongo-express服务配置保持原有内容不变 family-chronicles-backend: build: context: . dockerfile: src/Dockerfile depends_on: mariadb: condition: service_healthy mongodb: condition: service_started
也可以选择在连接字符串中追加Connect Timeout=30;参数,让EF Core自动重试等待数据库就绪,替代健康检查配置。
修改完成后先执行docker-compose down -v清理旧的容器和数据卷,再执行docker-compose up --build重新构建启动服务,报错即可解决。
内容的提问来源于stack exchange,提问作者JosunLP
相关产品推荐
相关产品推荐

