I have a Visual Studio .Net 8 Solution that contains a WebAPI backend project. It also contains dockerfile. I have also added a docker-compose to orchestrate the project. Outside of this visual studio solution, I also have a MySql Docker container that holds the MySql Database to feed data to the WebAPI project. The MySql container is also started by the docker-compose since I manually added the mysql service to the docker-compose so that they all run in the same network. This database is saved into a docker volume on the docker host. All these, including a Docker Desktop, are running on my Windows 11 machine.
Now, here is my problem: When I manually run the WebAPI project outside of docker and also run the MySql docker container manually, I can connect to the database via the Swagger UI that launches and test out my end points. They all work fine. But If run docker-compose from within the solution, I can see that the MySql container is launched. When it tries to launch the Web API container, it bombs. It fails with an error message saying “Unable to connect to any of the specified MySql hosts”. Under Debug mode, the API project crashes in the program.cs file when it tries to connect to the database using the connection string stored in the appsettings file. I have no clue what is going on. I am posting as many code segments as I can. Someone please help me out with a fix. Ultimately, I want all my containers run via the docker-compose and all my containers be able to communicate with each other.
Do I need to create another Dockerfile for Mysql container? If I do, where would I place the Dockerfile? I don’t have a MySql project in my solution.
Could the reason for not being able to connect to the database container be due to some docker network issue? When I run the API project manually, it is not running in a container and everything works as expected.
Here is my Dockerfile:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 8080
EXPOSE 8081
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["ExpenseTracker.API/ExpenseTracker.API.csproj", "ExpenseTracker.API/"]
COPY ["ExpenseTracker.Data/ExpenseTracker.Data.csproj", "ExpenseTracker.Data/"]
COPY ["ExpenseTracher.CommonTools/ExpenseTracker.CommonTools.csproj", "ExpenseTracher.CommonTools/"]
COPY ["ExpenseTracker.Services/ExpenseTracker.Services.csproj", "ExpenseTracker.Services/"]
COPY ["ExpenseTracker.UserObjects/ExpenseTracker.UserObjects.csproj", "ExpenseTracker.UserObjects/"]
RUN dotnet restore "./ExpenseTracker.API/ExpenseTracker.API.csproj"
COPY . .
WORKDIR "/src/ExpenseTracker.API"
RUN dotnet build "./ExpenseTracker.API.csproj" -c $BUILD_CONFIGURATION -o /app/build
FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./ExpenseTracker.API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
Here is my docker-compose file:
services:
expensetracker.api:
image: ${DOCKER_REGISTRY-}expensetrackerapi
container_name: expensetrackerapi
build:
context: .
dockerfile: ExpenseTracker.API/Dockerfile
depends_on:
- mysql-et
mysql-et:
image: mysql:9.0.0
container_name: mysql-et
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: Valappil@1
MYSQL_DATABASE: ExpenseTracker
volumes:
- mysql-et-db:/var/lib/mysql
volumes:
mysql-et-db:
Here is my connection string defined in appsettings:
//builder.Services.AddDbContext<ExpenseTrackerDbContext>(options => options.UseMySQL(connectionString));
var serverVersion = new MySqlServerVersion(ServerVersion.AutoDetect(connectionString));
//builder.Services.AddDbContext<ExpenseTrackerDbContext>(options =>
// options.UseMySql(connectionString,
// new MySqlServerVersion(ServerVersion.AutoDetect(connectionString))));
builder.Services.AddDbContext<ExpenseTrackerDbContext>(options =>
options.UseMySql(connectionString,
new MySqlServerVersion(serverVersion)));
Babu.