asp.net core 2.0 - multiple projects solution docker file
Dockerasp.net CoreDocker Problem Overview
[asp.net core 2.0 and docker for linux]
I am completely new to docker and trying to figure out how to use docker in a case where i have a solution with 2 projects. All tutorials i've seen show with single project.
So, if someone could show step by step solution i would really appreciate it.
i have a solution structure like:
Solution.sln
|______WebAPIProject.csproj
|______ClassLibraryProject.csproj
In Visual studio, i've added docker support to solution and got these files:
Under WebAPIProject, it created this Docker file:
FROM microsoft/aspnetcore:2.0
ARG source
WORKDIR /app
EXPOSE 80
COPY ${source:-obj/Docker/publish} .
ENTRYPOINT ["dotnet", "WebAPIProject.dll"]
then, under separate docker-compose 'project' i've got:
docker-compose.ci.build.yml
version: '3'
services:
ci-build:
image: microsoft/aspnetcore-build:1.0-2.0
volumes:
- .:/src
working_dir: /src
command: /bin/bash -c "dotnet restore ./Solution.sln && dotnet publish ./Solution.sln -c Release -o ./obj/Docker/publish"
and docker.compose.yml file
version: '3'
services:
WebAPIProject:
image: WebAPIProject
build:
context: ./WebAPIProject
dockerfile: Dockerfile
I am sure its something trivial with paths but i am just pretty lost with it all so if someone could shed a bit of a light on it?
Docker Solutions
Solution 1 - Docker
I finally found a way how to built solutions with docker.
IMPORTANT: For this to work, you have to put the Dockerfile file into the same location where the solution file is
I've just created a docker file with the following content:
FROM microsoft/aspnetcore:2.0 AS base
WORKDIR /app
EXPOSE 80
FROM microsoft/aspnetcore-build:2.0 AS build
WORKDIR /src
COPY Solution.sln ./
COPY ClassLibraryProject/*.csproj ./ClassLibraryProject/
COPY WebAPIProject/*.csproj ./WebAPIProject/
RUN dotnet restore
COPY . .
WORKDIR /src/ClassLibraryProject
RUN dotnet build -c Release -o /app
WORKDIR /src/WebAPIProject
RUN dotnet build -c Release -o /app
FROM build AS publish
RUN dotnet publish -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "WebAPIProject.dll"]
Note that I think you may have to respect project build dependencies but I don't know really.
Sample call to build:
sudo docker build --no-cache -t webapi:dev .
Sample call to run:
sudo docker run -d=false -p 8080:80 --name webapi webapi:dev
Hope that helps.
Solution 2 - Docker
While I understand that dotnet core isn't specific to Windows and not everyone is going to be using Visual Studio, there's this neat feature that Microsoft has included inside Visual Studio (Tried it in 2017).
- Right click on the Web Project.
- Select Add.
- Then "Docker Support". This will automatically fetch multiple projects into the container.
If you have multiple Web Projects, repeat the step individually for each.
Here's the reference: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/docker/visual-studio-tools-for-docker?view=aspnetcore-2.1#existing-app
If you happen to run with any issues when running the Docker container, try deselecting Hyper-V Services
in "Windows Features" (Search for Windows Features
in Start Menu), selecting again, and then restarting your computer.
Check here.
Solution 3 - Docker
I had the same problem and all other solutions didn't fit my so I worked out my own. I feel that bellow steps are legible, but if you're new to Docker, I explained it line by line in my blog post dedicated to new Docker users (so you could understand precisely what is going on in this Dockerfile).
-
Keep Dockerfile in project directory (which is, in my point of view, better than keeping it next to solution file, because you can have more than one Docker image per solution).
-
Configure Dockerfile as follows:
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build-env
WORKDIR /app
COPY . ./
RUN dotnet publish PROJECT_NAME -c Release -o out
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2
WORKDIR /app
COPY --from=build-env /app/PROJECT_NAME/out .
ENTRYPOINT ["dotnet", "PROJECT_NAME.dll"]
-
Move .dockerignore file to solution directory - that's required, because Docker CLI takes .dockerignore file only from root directory of the build context (as documentation says), but it's also convenient, because you have one, common set of ignore rules for all projects (similar to .gitignore file), which is easier to maintain.
-
Run build command from solution directory, pointing to Dockerfile in project directory, and setting current directory (.) as build context (to have access to all projects):
docker build -f PROJECT_DIRECTORY/Dockerfile -t IMAGE_NAME .
- Run container as usual, for example:
docker run -d -p 8080:80 --name my-app-name IMAGE_NAME
Solution 4 - Docker
This links to an amazing post about how to tackle this issue.
He mentions putting all your code in a src
directory. I didn't so that, and this is the file i came up with: (The key is the for file
part. I'm sure it's not the best dockerfile otherwise; tips are welcome.)
FROM microsoft/dotnet:2.2-aspnetcore-runtime-stretch-slim AS base
WORKDIR /app
EXPOSE 5000
FROM microsoft/dotnet:2.2-sdk-stretch AS build
WORKDIR /src
COPY ./*.sln ./
COPY */*.csproj ./
RUN for file in $(ls *.csproj); do mkdir -p ${file%.*} && mv $file ${file%.*}; done
RUN dotnet restore
COPY . ./
RUN dotnet build -c Release -o /app
FROM build AS publish
RUN dotnet publish -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENV ASPNETCORE_URLS="http://*:5000"
ENTRYPOINT ["dotnet", "PersonalSiteApi.dll"]
Solution 5 - Docker
FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app
RUN mkdir /output
# Copy project and publish
COPY . /app
WORKDIR /app/YourProjectName
RUN dotnet publish --configuration Debug --output /output
# Build runtime image
FROM microsoft/dotnet:aspnetcore-runtime
ENV ASPNETCORE_URLS http://*:5001
WORKDIR /app
COPY --from=build-env /output .
EXPOSE 5001
ENTRYPOINT ["dotnet", "YourProjectName.dll"]
This is a Docker configuration that worked for me. This was an ASP.NET Core 2 WebApi project with many child project references.
Then run it using docker run -d -p 8080:5001 --name some-name yourpojectname
Hope this helpes someone.
Solution 6 - Docker
As of 2022 docker-compose 3.9
After few attempts, I managed to do it this way:
Project hierarchy:
MoulaTracker/
|- MoulaTracker.Core/ # <- PROJECT 1
|- MoulaTracker.Api/ # <- PROJECT 2
|- Dockerfile.Core
|- Dockerfile.Api
|- docker-compose.yml
|- MoulaTracker.sln
The project MoulaTracker.Api
is dependent of MoulaTracker.Core
docker-compose.yml:
version: "3.9"
services:
moula-tracker-core:
build:
context: .
dockerfile: ./Dockerfile.Core
moula-tracker-api:
build:
context: .
dockerfile: ./Dockerfile.Api
Dockerfile.Api:
FROM mcr.microsoft.com/dotnet/core/sdk:3.1.409 AS build-env
# Copy csproj and restore as distinct layers
WORKDIR /MoulaTracker.Api
COPY ./MoulaTracker.Api .
COPY ./MoulaTracker.Core ../MoulaTracker.Core
RUN dotnet restore
RUN dotnet publish -c Release -o out
# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1.0 AS runtime
WORKDIR /MoulaTracker.Api
COPY --from=build-env /MoulaTracker.Api/ ./
ENTRYPOINT ["dotnet", "out/MoulaTracker.Api.dll"]