I have just started working on docker, so please go easy on me.
I have an .NetCore(.Net 6.0) API. I want to integrate prometheus and grafana with this API.
I have followed a YouTube tutorial and created the required .yml files. However when i try to build my docker-compose file i get the below error
failed to solve with frontend dockerfile.v0: failed to read dockerfile: open /var/lib/docker/tmp/buildkit-mount2783899235/Dockerfile: no such file or directory
ERROR: Service 'web' failed to build : Build failed
Please help me in finding the issue.
Dockerfile
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 7068
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["Src/PaymentService.Api/PaymentService.Api.csproj", "Src/PaymentService.Api/"]
RUN dotnet restore "Src/PaymentService.Api/PaymentService.Api.csproj"
COPY . .
WORKDIR "/src/Src/PaymentService.Api"
RUN dotnet build "PaymentService.Api.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "PaymentService.Api.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "PaymentService.Api.dll"]
prometheus.yml
global:
scrape_interval: 10s
scrape_timeout: 5s
rule_files:
scrape_configs:
- job_name: "Prospera.PaymentService"
static_configs:
- targets: ["host.docker.internal:7068"]
dockerfile-prometheus.yml
FROM quay.io/prometheus:latest
ADD prometheus.yml /etc/prometheus/
docker-compose.yml
version: '3.4'
services:
web:
build: .
ports:
- "7068"
docker-compose.override.yml
version: '3.4'
services:
paymentservice.api:
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ASPNETCORE_URLS=https://+:443;http://+:80
ports:
- "80"
- "443"
- "7068"
volumes:
- ${APPDATA}/Microsoft/UserSecrets:C:\Users\ContainerUser\AppData\Roaming\Microsoft\UserSecrets:ro
- ${APPDATA}/ASP.NET/Https:C:\Users\ContainerUser\AppData\Roaming\ASP.NET\Https:ro
Related
I'm trying to containerize a .NET6 WebApi with a postgrescontainer. I have this Docker file to build the web api image:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["MicroserviceTemplateDDD.csproj", "MicroserviceTemplateDDD/"]
RUN dotnet restore "MicroserviceTemplateDDD/MicroserviceTemplateDDD.csproj"
WORKDIR "/src/MicroserviceTemplateDDD"
COPY . .
RUN dotnet build "MicroserviceTemplateDDD.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "MicroserviceTemplateDDD.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
WORKDIR /app/publish
ENTRYPOINT ["dotnet", "MicroserviceTemplateDDD.dll"]
This runs successfully. But when i run docker-compose up to start the postgre and webapi container i get this error:
microservicetemplateddd_service1 | Process terminated. Couldn't find a valid ICU package installed on the system. Please install libicu using your package manager and try again. Alternatively you can set the configuration flag System.Globalization.Invariant to true if you want to run with no globalization support. Please see https://aka.ms/dotnet-missing-libicu for more information.
My docker compose:
version: "3.7"
services:
api:
image: microservicetemplateddd_service1
container_name: microservicetemplateddd_service1
restart: always
build:
context: .
dockerfile: Dockerfile
environment:
- ConnectionStrings:Context=Server=MicroserviceTemplateDDD_Service1_database;Database=Database;User Id=pa;Password=P4ssW0rd!;
- DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
depends_on:
- database
networks:
- network
ports:
- 8090:80
database:
image: postgres
container_name: microservicetemplateddd_service1_database
restart: always
environment:
- ACCEPT_EULA=Y
- POSTGRES_PASSWORD=P4ssW0rd!
- POSTGRES_USER=pa
networks:
- network
ports:
- 1433:1433
volumes:
- database:/var/opt/mssql
networks:
network:
volumes:
database:
I already tried to use other ms images like alpine and change the place of setting the env.
Per the docs, you should set the environment variable to 1 to disable globalization. Like this
environment:
- ConnectionStrings:Context=Server=MicroserviceTemplateDDD_Service1_database;Database=Database;User Id=pa;Password=P4ssW0rd!;
- DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
Since you always need to set it to run your container, it'll be a good idea to put the configuration into the image. You can put it at the beginning of the dockerfile and remove it from the docker-compose file
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
WORKDIR /app
EXPOSE 80
EXPOSE 443
That way you can't forget to set it and have the error pop up again.
I had a similar issue and got around it by adding this condition in the csproj
<ItemGroup Condition="$([MSBuild]::IsOSPlatform('Windows'))">
<RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="68.2" />
</ItemGroup>
I have a problem / question what should I do when I have docker-compose.yml with several services and want to push this as a project into the repository.
My docker-compose.yml
version: '3.8'
configs:
prometheus_config:
file: ./prometheus.yml
networks:
inner_net:
driver: overlay
services:
app:
build: .
ports:
- 6020:80
container_name: AVM.Core
image: avmtemplate_app
prometheus:
image: quay.io/prometheus/prometheus:latest
ports:
- 9090:9090
configs:
- source: prometheus_config
target: /etc/prometheus/prometheus.yml
depends_on:
- app
container_name: Prometheus
grafana:
image : grafana/grafana
depends_on:
- prometheus
ports:
- 3000:3000
volumes:
- ./grafana/data/:/var/lib/grafana
- ./grafana/provisioning/:/etc/grafana/provisioning/
env_file:
- ./config.monitoring
container_name: Grafana
As you can see, I have three services that depend on each other.
The "grafana" service depends on the "prometheus" service and this depends on the "app" service.
And this is what my "dockerfile" looks like:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
EXPOSE 3000
EXPOSE 9090
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["../AVM.Core/AVM.Core.csproj", "../AVM.Core/"]
COPY ["../AVM.Domain/AVM.Domain.csproj", "../AVM.Domain/"]
COPY ["../AVM.Repository/AVM.Repository.csproj", "../AVM.Repository/"]
COPY ./prometheus.yml /etc/prometheus/prometheus.yml
RUN dotnet restore "../AVM.Core/AVM.Core.csproj"
COPY . .
WORKDIR "/src/AVM.Core"
RUN dotnet build "AVM.Core.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "../AVM.Core/AVM.Core.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app/AVM.Core
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "AVM.Core.dll"]
When I use docker-compose up i get three images and one project which include all this images. I Paste a screenshots that show it.
Maybe some of you know how to push it into the repository so that a person who would like to use my template has to download only a project , and then she just launched the project to make it work? If this is not possible, what else should I do?
Thanks for all your answers
Cheers
We have one API project with DockerFile
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 43001
EXPOSE 43002
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY Api.csproj Api/
RUN dotnet restore Api/Api.csproj
COPY . .
WORKDIR /src/Api
RUN dotnet build Api.csproj --no-restore -c Release -o /app
FROM build AS publish
WORKDIR /src/Api
RUN dotnet publish Api.csproj --no-restore --no-self-contained -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Api.dll"]
And with docker-compose
version: '3.5'
services:
Api:
image: Api
restart: always
environment:
- ASPNETCORE_URLS=https://+:443;http://+:80
- ASPNETCORE_ENVIRONMENT=Production
build:
context: .
dockerfile: Api/Dockerfile
ports:
- "43001:80"
- "43002:443"
This project pushed to private docker registry.
And we have second Prod project that should use and connect to Api project.
docker-compose Prod project:
version: '3.5'
services:
Prod:
image: Prod
restart: always
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_URLS=http://+:80
build:
context: .
dockerfile: Prod/Dockerfile
depends_on:
- Api
networks:
- proxy-net
expose:
- "80"
Api:
image: {RegistryAddress}/Api
restart: always
networks:
- proxy-net
ports:
- "43002:443"
networks:
proxy-net:
external:
name: proxy-net
Issue - When I am connecting from Prod to Api I am getting Connection refused. Perhaps something with ports settings, but I tried a lot of changes and it didn`t help. I thought Api ports settings should be enough, but looks like we need to set something in Prod also.
I am trying to use docker-compose with my project.
Having issue with .Net 5 API project.
It works properly with ISS Express and Docker but when I run project with docker-compose api project is not working as expected.
As expeced when running docker-compose it should run API project and launch swagger api page instead it’s displaying different erros when exposed ports are accessed via browser. Please find attached snaps below.
Docker container image
browser run1
browser run2
browser run3
As you can see for each url it's displaying different error message in browser.
Following solutions to resolve issues but none worked.
1. Expose ports using below in docker file
ports:
- 51850:80
Docker expose ports
2. Try with debug environment
ARG BUILD_CONFIGURATION=Debug
ENV ASPNETCORE_ENVIRONMENT=Development
ENV DOTNET_USE_POLLING_FILE_WATCHER=true
ENV ASPNETCORE_URLS=http://+:80
stackoverlow suggestion - set environment to debug
3. Tried using VSCode docker-compose and Visual Studio docker-compose
Regenerated docker-compose file with help of Visual Studio and VS Code.
4. Tried setting up specific ports on Launchsettings.json
Tried settings specif ports with docker in launsettings.json
and exporting from docker, docker compose
Docker
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 44370
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["TAPI/TAPI.csproj", "TAPI/"]
RUN dotnet restore "TAPI/TAPI.csproj"
COPY . .
WORKDIR "/src/TAPI"
RUN dotnet build "TAPI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "TAPI.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TAPI.dll"]
docker-compose
version: '3.4'
services:
todoworker:
image: tworker
build:
context: .
dockerfile: TWorker/Dockerfile
todoapi:
image: tapi
build:
context: .
dockerfile: TAPI/Dockerfile
ports:
- 80
- 443
- 44370
tangular:
image: tangular
build:
context: .
dockerfile: TAngular/Dockerfile
ports:
- 4200:4200
5. Tried with deleting all containers
Tried deleting all containers, images and recreating all after restarting docker desktop (using docker on windows system)
As suggested in following article Docker for clean build of an image
docker system prune
Docker desktop image
Even deleting images and containers from docker and recreating images some time it displayes image created time from past hours.
Date: 20-May-2021:
I have created another small Sample with two Web APIs. Tested on my local Laptop. Please get that to your local box and execute. Please let me know if you need any further assistance.
GitHub URL: https://github.com/vishipayyallore/mini-projects-2021/tree/master/Projects/CollegeDockerDemo
College.WebAPI Docker File
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["Source/College.WebAPI/College.WebAPI.csproj", "Source/College.WebAPI/"]
RUN dotnet restore "Source/College.WebAPI/College.WebAPI.csproj"
COPY . .
WORKDIR "/src/Source/College.WebAPI"
RUN dotnet build "College.WebAPI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "College.WebAPI.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "College.WebAPI.dll"]
ToDo.WebAPI Docker File
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["Source/ToDo.WebAPI/ToDo.WebAPI.csproj", "Source/ToDo.WebAPI/"]
RUN dotnet restore "Source/ToDo.WebAPI/ToDo.WebAPI.csproj"
COPY . .
WORKDIR "/src/Source/ToDo.WebAPI"
RUN dotnet build "ToDo.WebAPI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ToDo.WebAPI.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ToDo.WebAPI.dll"]
docker-compose.yml File
version: '3.4'
services:
college.webapi:
image: ${DOCKER_REGISTRY-}collegewebapi
build:
context: .
dockerfile: Source/College.WebAPI/Dockerfile
todo.webapi:
image: ${DOCKER_REGISTRY-}todowebapi
build:
context: .
dockerfile: Source/ToDo.WebAPI/Dockerfile
docker-compose.override.yml File
version: '3.4'
services:
college.webapi:
environment:
- ASPNETCORE_ENVIRONMENT=Development
ports:
- "8000:80"
volumes:
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
todo.webapi:
environment:
- ASPNETCORE_ENVIRONMENT=Development
ports:
- "8001:80"
volumes:
- ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
- ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
I was asked to create a .net solution with a web api and a console program, then have this available with a docker-compose command that includes the full environment. The web api is using mongodb and easynetq. The console program references the web api project and also uses easynetq. I know Visual Studio can provide me a dockerfile for each project. How do I proceed after this? Do I combine the 2 dockerfiles into 1 at the solution level? Or can I continue with the 2 dockerfiles?
Dockerfile for console program
FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app
COPY . ./
RUN dotnet restore "./ConsoleProgram.csproj"
RUN dotnet publish "ConsoleProgram.csproj" -c Release -o out
FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "ConsoleProgram.dll"]
Dockerfile for webapi is identical as above, only names are changed
Docker compose at solution level
version: '3'
services:
mongo:
image: mongo
restart: always
ports:
- 27017:27017
webapi:
build: ./webapi
restart: always
ports:
- 5000:80
environment:
MongoDB__Host: mongo
depends_on:
- mongo
console:
build: ./console
restart: always
depends_on:
- webapi
After doing a docker compose on this I get the following errors:
Skipping project "C:\WebApi\WebApi.csproj" because it was not found.
The referenced project '..\WebApi\WebApi.csproj' does not exist.
Service 'console' failed to build: The command 'cmd /S /C dotnet
publish "Console.csproj" -c Release -o out' returned a non-zero code:
1
You are on the right way. You should have Dockerfile for each projects (in root of the project folder), then one file docker-compose.yaml and many docker-compose.override.yaml if you need.
There are some gaps in Dockerfile.
1.Don't copy COPY . ./ all files in ConsoleProgram image, first just copy csproj
COPY console/ConsoleProgram.csproj console/
2.After copy csproj file run dotnet restore to improve image building time
RUN dotnet restore console/ConsoleProgram.csproj
3.Then copy all other files and run dotnet publish (or build) with flag --no-restore
COPY console/ console/
RUN dotnet publish console/ConsoleProgram.csproj --no-restore -c Release -o /out
Here are some example how Dockerfile should look
FROM microsoft/dotnet:2.2-sdk AS publish
WORKDIR /src
COPY console/ConsoleProgram.csproj console/
RUN dotnet restore console/ConsoleProgram.csproj
COPY console/ console/
RUN dotnet publish console/ConsoleProgram.csproj --no-restore -c Release -o /app
FROM microsoft/dotnet:2.2-aspnetcore-runtime AS runtime
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "ConsoleProgram.dll"]
Something similar should be for WebAPI. Now look at your docker-compose.yaml. You should specify build context and image name
webapi:
image: 'webapi'
build:
context: .
dockerfile: ./webapi/Dockerfile
restart: always
ports:
- 5000:80
environment:
MongoDB__Host: mongo
depends_on:
- mongo
console:
image: 'console'
build:
context: .
dockerfile: ./console/Dockerfile
restart: always
depends_on:
- webapi
As I doesn't know your project structure you need to be careful with all paths to project in this answer