在 Github Actions 中为 Django 设置 postgres

pat*_*ick 4 django django-testing django-postgresql github-actions

我目前正在 Django 上开发一个网站。在我的计算机上,我在带有 postgres 数据库的 Docker 上运行它。这是我拥有的 docker-compose 文件:

version: '3'

services:
    db:
        image: postgres
        environment:
            - POSTGRES_DB=postgres
            - POSTGRES_USER=postgres
            - POSTGRES_PASSWORD=postgres


    web:
        build: .
        volumes:
            - .:/usr/src/app
        ports:
            - "8000:8000"
Run Code Online (Sandbox Code Playgroud)

这是 settings.py 中的相关部分

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'db',
        'PORT': 5432,
    }
}
Run Code Online (Sandbox Code Playgroud)

当我使用此设置在 docker 容器中运行我的测试时,它可以找到并运行测试。但是,在 github 操作中,它不起作用。这是我的工作流文件:

name: Django CI

on: push


jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      max-parallel: 4
      matrix:
        python-version: [3.7, 3.8]

    services:
      db:
        image: postgres
        env:
          POSTGRES_DB: postgres
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        ports:
          - 5432:5432

    steps:
    - uses: actions/checkout@v2
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v1
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install Dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -r requirements.txt
    - name: Run Tests
      run: |
        python manage.py test
Run Code Online (Sandbox Code Playgroud)

当它在 github 操作中运行时,我收到以下错误:

django.db.utils.OperationalError: could not translate host name "db" to address: Temporary failure in name resolution
Run Code Online (Sandbox Code Playgroud)

有人可以帮我解决这个问题,如果您需要更多代码,请告诉我。

Rob*_*Rob 6

这不起作用的原因是设置HOST设置为db.

当您使用只有服务的 Github 操作时,这称为“在虚拟机上运行所有步骤”或 VM。

您知道这是这种情况,因为您steps的缩进级别与services.

在这种情况下,您不要将服务的容器名称(在本例中db)指定为主机。相反,services如问题中所示运行的服务实际上localhost是在执行步骤的同一位置上运行的。

到了run tests步骤,我们可以看到django其实是在尝试启动,因为这个django.db.utils.OperationalError...错误Django运行时错误。它显示了 Django 试图与数据库联系并与之交谈。

这意味着设置配置错误。要专门回答这个问题,只需将设置更新为:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'localhost',
        'PORT': 5432,
    }
}


Run Code Online (Sandbox Code Playgroud)

请注意这里显示了一个非常相似的问题和解决方案。


如果这不能解决它

如果这仍然不适合您,很可能 Github Actions 正在运行的 settings.py 与您正在编辑的不同。

正如我在这里提到的,首先确保您的设置没有被覆盖,并且您的 Github Actions 作业正在拉取您正在编辑的正确分支settings.py

这可能特别困难,因为等待 Github Actions 构建的延迟会导致您正在执行的操作与结果之间存在某种脱节。

您可能认为您正在处理相关代码/推送到正确的位置/设置正确的环境变量,而不是。而且您可能没有检测到它,因为很容易分心等待查看您的修复是否有效。:)

关于这一点的另一个注意事项,Github 有一个 使用 postgres 的简单服务示例。仔细看看。第二个示例显示了此问题中的问题,其中所有步骤都在虚拟机上运行。


小智 5

settings.py正如@Rob指出的正确点,容器中运行的 PostgreSQL之间的配置是错误的。简而言之,容器中的 PostgreSQL 数据库不会访问您的密钥,因此您需要显式地提供它们。

设置.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': env('POSTGRES_DB'),
        'USER': env('POSTGRES_USER'),
        'PASSWORD': env('POSTGRES_PASSWORD'),
        'HOST': env('POSTGRES_HOST'),
        'PORT': 5432
    }
}
Run Code Online (Sandbox Code Playgroud)

我用来django-environ存储我的环境变量。os.getenv也在这里工作。只需更改os.getenvenv.

在扩展名为 的工作流程文件中.ymlservices部分应如下所示:

services:
  postgres:
    image: postgres:12.5
    env:
      POSTGRES_DB: postgres
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
    ports:
      - 5432:5432
      # needed because the postgres container does not provide a healthcheck
    options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
Run Code Online (Sandbox Code Playgroud)

在同一个文件中,可以安全地使用所有环境变量。例如,这显示了我的Django Testing工作流程:

- name: Django Testing
  env:
    DEBUG: ${{ secrets.DEBUG }}
    SECRET_KEY: ${{ secrets.SECRET_KEY }}
    POSTGRES_HOST: ${{ secrets.POSTGRES_HOST }}
    POSTGRES_DB: ${{ secrets.POSTGRES_DB }}
    POSTGRES_USER: ${{ secrets.POSTGRES_USER }}
    POSTGRES_PASSWORD: ${{ secrets.POSTGRES_PASSWORD }}
  run: |
    python manage.py test
Run Code Online (Sandbox Code Playgroud)

最后,在 Github 存储库 Secrets 中,将变量定义为:

POSTGRES_HOST --> localhost
POSTGRES_DB --> postgres
POSTGRES_USER --> postgres
POSTGRES_PASSWORD --> postgres
DEBUG --> True
SECRET_KEY --> <Your Django Secret Key>
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

最后,您将拥有: 在此输入图像描述