【问题标题】:docker-compose working correctly in powershell but not in visual studiodocker-compose 在 PowerShell 中正常工作,但在 Visual Studio 中不能正常工作
【发布时间】:2020-04-01 16:01:59
【问题描述】:

我在一个容器中有一个反向代理 (nginx),在另一个容器中有一个 .net core api。在 powershell 中运行 docker-compose builddocker-compose up 时,这将按预期工作。 api 只能通过反向代理访问(http://localhost:80)。

我已经使用 Visual Studio 设置了 docker-compose,当在具有相同 dockerfile、docker-compose.yml、docker-compose.override.yml 的 Visual Studio 中运行时,这不起作用。我没有收到错误,两个容器都启动了。但是当尝试通过反向代理访问 api 时,我在反向代理的 docker 日志中出现以下错误

2020/04/01 15:49:30 [error] 6#6: *8 connect() failed (111: Connection refused) while 
connecting to upstream, client: 172.20.0.1, server: , request: "GET /api/health HTTP/1.1", 
upstream: "http://172.20.0.2:5000/api/health", host: "localhost"
172.20.0.1 - - [01/Apr/2020:15:49:30 +0000] "GET /api/health HTTP/1.1" 502 559 "-" 
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) 
Chrome/80.0.3987.149 Safari/537.36"

这是我的文件夹结构:

  • ....
  • RestApi(项目文件夹文件夹)
    • Dockerfile
  • docker-compose.yml
  • docker-compose.override.yml
  • 反向代理(文件夹)
    • Dockerfile
    • nginx.conf
  • ...

这些是我使用的文件:

.net core api 的 Dockerfile:

FROM mcr.microsoft.com/dotnet/core/aspnet:2.1-stretch-slim AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/core/sdk:2.1-stretch AS build
WORKDIR /src
COPY ["RestApi/RestApi.csproj", "RestApi/"]
COPY ["Services/Services.csproj", "Services/"]
COPY ["DataServices/DataServices.csproj", "DataServices/"]
COPY ["Entities/Entities.csproj", "Entities/"]
RUN dotnet restore "RestApi/RestApi.csproj"
COPY . .
WORKDIR "/src/RestApi"
RUN dotnet build "RestApi.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "RestApi.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .

ENV ASPNETCORE_URLS http://+:5000
EXPOSE 5000

ENTRYPOINT ["dotnet", "RestApi.dll"]

用于反向代理的 Dockerfile:

FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf

ngingx conf 文件反向代理:

worker_processes 4;

events { worker_connections 1024; }

http {
    sendfile on;

    upstream app_servers {
        server restapi:5000;
    }

    server {
        listen 80;

        location / {
            proxy_pass         http://app_servers;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_set_header   X-Real-IP $remote_addr;
            proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header   X-Forwarded-Host $server_name;
        }
    }
}

docker-compose.yml:

version: '3.7'
services:
  restapi:
    build:
      context: .
      dockerfile: RestApi/Dockerfile
    container_name: restapi
    image: restapi:latest
    expose:
      - "5000"
  reverseproxy:
    build:
      context: ./ReverseProxy
      dockerfile: Dockerfile
    container_name: reverseproxy
    image: reverseproxy:latest
    ports:
      - "80:80"
    links :
      - restapi

docker-compose.override.yml:

version: '3.7'

services:
  restapi:
    volumes:
      - ${USERPROFILE}/.aws:/root/.aws
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - AWS_REGION=eu-west-3
      - AWS_PROFILE=default

这就是 Visual Studio 在运行时对文件所做的:

services:
  restapi:
    build:
      context: D:\Repositories\dank\dank\api\RestApi
      dockerfile: RestApi/Dockerfile
      labels:
        com.microsoft.created-by: visual-studio
        com.microsoft.visual-studio.project-name: RestApi
      target: base
    container_name: restapi
    entrypoint: tail -f /dev/null
    environment:
      ASPNETCORE_ENVIRONMENT: Development
      AWS_PROFILE: default
      AWS_REGION: eu-west-3
      DOTNET_USE_POLLING_FILE_WATCHER: '1'
      NUGET_FALLBACK_PACKAGES: ''
    expose:
    - '5000'
    image: restapi:dev
    labels:
      com.microsoft.visualstudio.debuggee.arguments: ' --additionalProbingPath /root/.nuget/packages  "bin/Debug/netcoreapp2.1/RestApi.dll"'
      com.microsoft.visualstudio.debuggee.killprogram: /bin/sh -c "if PID=$$(pidof
        dotnet); then kill $$PID; fi"
      com.microsoft.visualstudio.debuggee.program: dotnet
      com.microsoft.visualstudio.debuggee.workingdirectory: /app
    tty: true
    volumes:
    - D:\Repositories\dank\dank\api\RestApi\RestApi:/app:rw
    - C:\Users\Gebruiker\vsdbg\vs2017u5:/remote_debugger:rw
    - C:\Users\Gebruiker\AppData\Roaming\ASP.NET\Https:/root/.aspnet/https:ro
    - C:\Users\Gebruiker\.aws:/root/.aws:rw
    - C:\Users\Gebruiker\AppData\Roaming\Microsoft\UserSecrets:/root/.microsoft/usersecrets:ro
    - C:\Users\Gebruiker\.nuget\packages:/root/.nuget/packages:ro
    - D:\Repositories\dank\dank\api\RestApi:/src:rw
  reverseproxy:
    build:
      context: D:\Repositories\dank\dank\api\RestApi\ReverseProxy
      dockerfile: Dockerfile
    container_name: reverseproxy
    image: reverseproxy:latest
    links:
    - restapi
    ports:
    - published: 80
      target: 80
version: '3.7'

【问题讨论】:

    标签: visual-studio asp.net-core nginx docker-compose


    【解决方案1】:

    阅读官方文档时:https://docs.microsoft.com/en-us/visualstudio/containers/container-build?view=vs-2019#debugging

    我看到他们把暴露的端口放在 dockerfile 的顶部。这样做时,它可以在 Visual Studio 中工作,并且端口 5000 被我的 api 容器正确公开,并且可以通过反向代理访问。

    这是我当前的 dockerfile 更改:

    FROM mcr.microsoft.com/dotnet/core/aspnet:2.1-stretch-slim AS base
    WORKDIR /app
    
    ENV ASPNETCORE_URLS http://+:5000
    EXPOSE 5000
    
    FROM mcr.microsoft.com/dotnet/core/sdk:2.1-stretch AS build
    WORKDIR /src
    COPY ["RestApi/RestApi.csproj", "RestApi/"]
    COPY ["Services/Services.csproj", "Services/"]
    COPY ["DataServices/DataServices.csproj", "DataServices/"]
    COPY ["Entities/Entities.csproj", "Entities/"]
    RUN dotnet restore "RestApi/RestApi.csproj"
    COPY . .
    WORKDIR "/src/RestApi"
    RUN dotnet build "RestApi.csproj" -c Release -o /app/build
    
    FROM build AS publish
    RUN dotnet publish "RestApi.csproj" -c Release -o /app/publish
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    
    ENTRYPOINT ["dotnet", "RestApi.dll"]
    

    这行得通的原因是(来自文档):

    在调试配置中构建时,Visual Studio 会进行多项优化,以帮助提高容器化项目的构建过程的性能。容器化应用程序的构建过程并不像简单地按照 Dockerfile 中列出的步骤那么简单。在容器中构建比在本地机器上构建要慢得多。因此,当您在 Debug 配置中构建时,Visual Studio 实际上会在本地计算机上构建您的项目,然后使用卷挂载将输出文件夹共享给容器。启用此优化的构建称为快速模式构建。

    在快速模式下,Visual Studio 调用 docker build 时带有一个参数,告诉 Docker 只构建基础阶段。 Visual Studio 处理其余过程,而不考虑 Dockerfile 的内容。因此,当您修改 Dockerfile 时,例如自定义容器环境或安装额外的依赖项,您应该将修改放在第一阶段。放置在 Dockerfile 的构建、发布或最终阶段中的任何自定义步骤都不会执行。

    【讨论】:

      猜你喜欢
      • 2022-06-29
      • 1970-01-01
      • 2011-06-17
      • 2013-06-29
      • 2021-06-28
      • 1970-01-01
      • 2022-06-13
      • 1970-01-01
      • 2017-12-12
      相关资源
      最近更新 更多