Is there an example of a project that has the 3 project structure with service model and service interface and a docker file?
I am new to docker and need to build an image from the .net core angular spa project.
I am not sure of best approach. Should there be one container for the front end and one for the API? Or all in one? How will that scale?
Here are our docs around DockerFile's we're using:
Which is what we're using to deploy most of our .NET Core Apps, look for projects which contain a
DockerFile in the hope page.
We also have DockerFile for our .NET Core Web Apps.
But using Docker is irrelevant to ServiceStack which is just another .NET Core project so you'd better be served by reading the available .NET Core docs for Docker:
The project structure is irrelevant, you'd just be building the host project and deploying/copying the results in the Docker container. You don't make the decision of how many host projects you have when you Dockerize your App, it's based on whether you've split your solution into multiple host projects in which case each host project would be a separate Docker container and deployment unit.
I looked through your repos but didn't see any dockerfile for a project used the 3 projects approach.
I'm posting what I came up with in-case anyone else finds this post:
FROM microsoft/dotnet:sdk AS build-env
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
&& apt-get install -y gnupg nodejs
# Copy csproj and restore as distinct layers
COPY ./ProjectName/ProjectName.csproj ./ProjectName/ProjectName.csproj
COPY ./ProjectName/package.json ./ProjectName/package.json
COPY ./ProjectName/npm-shrinkwrap.json ./ProjectName/npm-shrinkwrap.json
COPY ./ProjectName.ServiceInterface/ProjectName.ServiceInterface.csproj ./ProjectName.ServiceInterface/ProjectName.ServiceInterface.csproj
COPY ./ProjectName.ServiceModel/ProjectName.ServiceModel.csproj ./ProjectName.ServiceModel/ProjectName.ServiceModel.csproj
RUN dotnet restore ./ProjectName/ProjectName.csproj
RUN dotnet restore ./ProjectName.ServiceInterface/ProjectName.ServiceInterface.csproj
RUN dotnet restore ./ProjectName.ServiceModel/ProjectName.ServiceModel.csproj
RUN cd ProjectName && npm i && cd ..
# Copy everything else and build
COPY ./ProjectName ./ProjectName
COPY ./ProjectName.ServiceInterface/ ./ProjectName.ServiceInterface
COPY ./ProjectName.ServiceModel/ ./ProjectName.ServiceModel
RUN cd ProjectName && npx ng build --prod && cd ..
RUN dotnet publish ./ProjectName/ProjectName.csproj -c Release -o out
# Build runtime image
COPY --from=build-env /app/ProjectName/out .
ENTRYPOINT ["dotnet", "ProjectName.dll"]
One little gotcha is that this must be in root of solution as docker build process doesn't have access to parent directories.
The issue I found was image takes long time to build so I build dependencies with just the dependency files first so it caches them unless dependency files changes.
Slowest part is probably the npm modules downloading and angular cli building. I think it makes sense maybe to have this in it's own image but then I think serverside rendering would be impossible. I am still researching the best way to arrange containers.
It uses the sdk image to build project and then uses that output in the production image.
If anyone has any suggestions or improvements please share.
Not sure why you're copying the projects individually, you just need to copy the sources folder, run publish on the host project and copy the published output to a new ASP.NET Runtime Docker Image. If you run
npm run publish (assuming you're using one of our SPA templates) before creating the Docker image it will generate a production npm client build so you can avoid doing it within the DockerFile.
Here are our DockerFile's for multi-project solutions:
e.g. DockerFile for redis-geo
FROM microsoft/aspnetcore-build:2.0 AS build-env
COPY src /app
RUN dotnet restore --configfile ../NuGet.Config
RUN dotnet publish -c Release -o out
# Build runtime image
COPY --from=build-env /app/RedisGeo/out .
ENV ASPNETCORE_URLS http://*:5000
ENTRYPOINT ["dotnet", "RedisGeo.dll"]
I did it that way so dependencies get cached, I am not exactly sure how the CI build scripts will work, haven't got to that stage yet so just guessing atm. If it lets me run publish on a post commit hook and then build image from that then it will be better to do like you say. I thought it might need everything to happen in the docker build so I did it that way, I'll edit it when I get to that stage. Thanks for the links, all the examples I saw were copying proj file first for dependency reason so I was expecting a docker file referencing all proj files which is what threw me when looking at repo.