使用Postgres使用Docker进行Entity Framework核心更新的最佳方法

问题描述 投票:0回答:1

背景

我正在构建一个API,使用dotnet核心和EF核心将用户信息保存在Postgres DB中。

我认为这不会对以下问题产生任何影响,但出于背景说明的目的,我还将IdentityServer4和Npgsql包用于Postgres访问。

在本地,一切工作都很好,我可以根据需要更新自己的架构,这都反映了数据库中的正确性。现在,我想使用这些容器来帮助新的团队成员快速建立。

问题

当我尝试直接从dotnet API容器更新架构时,会发生问题。这是我的dockerfiles:

仅使用dockerfile的首次尝试

API Dockerfile:

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine AS build-env

WORKDIR /app

# Explicitly ask for path to be added
ENV PATH="${PATH}:/root/.dotnet/tools"

RUN dotnet tool install --global dotnet-ef --version 3.1.3

# Copy csproj and restore as distinct layers
COPY *.csproj /app
RUN dotnet restore api.csproj

COPY . /app
RUN dotnet publish api.csproj -c Release -o out

# Run updates
RUN dotnet ef database update -c HelloApiDbContext
RUN dotnet ef database update -c ConfigurationDbContext

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1
COPY --from=build-env /app/out .

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

Postgres Dockerfile:

FROM postgres:12-alpine AS build-env
WORKDIR /app

ENV POSTGRES_USER docker
ENV POSTGRES_PASSWORD docker
ENV POSTGRES_DB docker

# Expose the PostgreSQL port
EXPOSE 5432

# Add VOLUMEs to allow backup of config, logs and databases
VOLUME  ["/etc/postgresql", "/var/log/postgresql", "/var/lib/postgresql"]

# Set the default command to run when starting the container
CMD ["postgres"]

也是我的默认配置连接字符串如下:

"DefaultConnection": "Server=localhost;Database=docker;Port=32778;User id=docker;Password=docker"

但是它总是会导致:

Build started...
Build succeeded.
Npgsql.NpgsqlException (0x80004005): Exception while connecting
 ---> System.Net.Internals.SocketExceptionFactory+ExtendedSocketException (99): Address not available [::1]:32778
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
   at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
   at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
   at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnection.<>c__DisplayClass32_0.<<Open>g__OpenLong|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---

我已经尝试了几件事。

注意

如果我使用本地EF从程序包管理器或Powershell运行更新,则可以正常工作。

第二次尝试撰写

我了解到问题是来自尚未解决的Docker容器内部DNS。我用其他方法将两者链接起来,其中最有前途的是this post之后的shell脚本,如下所示:

#!/bin/bash

set -e
run_cmd="dotnet run --server.urls http://*:80"

until dotnet ef database update -c HelloApiDbContext; do
>&2 echo "SQL Server is starting up"
sleep 1
done

>&2 echo "SQL Server is up - executing command"
exec $run_cmd

还有一个docker-compose文件:

version: '3.4'

networks: 
  api-dev:
    driver: "bridge"

services: 
  logic-api:
    image: project/api:latest
    depends_on: 
     - "usersdb"
    build:
      context: ./api/
      dockerfile: dockerfile
    ports: 
        - "5000:80"
    networks: 
      - api-dev

  usersdb:
    image: usersdb:latest
    build:
      context: ./users-db/
      dockerfile: dockerfile
    ports: 
      - "32778:5432"
    volumes: 
      - db_volume:/var/lib/postgresql/data
    environment: 
      POSGRES_USER: "docker"
      POSTGRES_PASSWORD : "docker"
      POSGRES_DB: "docker"
    networks: 
      - api-dev
volumes: 
  db_volume:

并更改了API dockerfile的入口点,以确保Postgres数据库已通过DBeaver启动

Dbeaver showing docker up

在像这样启动更新命令之前:

EXPOSE 80/tcp
RUN chmod +x ./entrypoint.sh
CMD /bin/bash ./entrypoint.sh

我也将默认连接更改为

"DefaultConnection": "Server=usersdb;Database=docker;Port=32778;User id=docker;Password=docker"

所有尝试均失败,我一直遇到此连接问题。

问题

我读过几篇文章说,使用SQL脚本而不是EF自动迁移,更容易管理产品中的SQL迁移。我是否应该放弃从一个容器更新到另一个容器的想法?

尽管可能,我想完全使用EF。有没有一种方法可以使此连接干净地工作?

提前感谢您的时间。

postgresql docker .net-core entity-framework-core npgsql
1个回答
1
投票

请更新您的连接字符串。

将端口号改回5432

新连接字符串:

"DefaultConnection": "Server=usersdb;Database=docker;Port=5432;User id=docker;Password=docker"

正当理由:

API-DEV是专用网络。

使用docker技巧时,您将了解您所连接的网络。

您的示例中有两个网络:

  • 您的主机/本地计算机
  • 第二API-DEV

API Dev将继续使用Postgres的默认端口5432。希望这会有所帮助。

进一步的想法

我已经在多个地方读过/听说过docker并不是一个不错的选择。根据我的有限知识,我建议您使用本机安装的postgress

Docker-compose也有一些限制。 Kubernetes和YAML文件解决了比docker-compose更好的创建基础架构的方式。还要考虑那些。

© www.soinside.com 2019 - 2024. All rights reserved.