在 Django 的 Github 操作中设置 postgres

Setup postgres in Github Actions for Django

我目前正在使用 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"

这里是 settings.py

中的相关部分
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgres',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'db',
        'PORT': 5432,
    }
}

当我 运行 使用此设置在 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

当这个 运行s 在 github 操作中时,我得到以下错误:

django.db.utils.OperationalError: could not translate host name "db" to address: Temporary failure in name resolution

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

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

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

你知道是这种情况,因为你的 stepsservices 的缩进级别相同。

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

当到达 run tests 步骤时,我们可以看到 django 实际上正在尝试启动,因为 django.db.utils.OperationalError... 错误 一个 Django 运行时间错误。它显示了 Django 试图与数据库联系和对话。

这意味着settings配置有误。要具体回答这个问题,只需将设置更新为:

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


注意一个非常相似的问题和正在解决的答案 is shown here


如果这不能解决问题

如果这仍然不适合您,很可能 Github 操作 运行ning 的 settings.py 与您正在编辑的不一样。

正如我提到的 here,首先确保您的设置 未被覆盖 并且您的 Github 操作作业正在拉动 正确的分支 您正在编辑 settings.py.

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

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

对此还有一个注意事项,Github 有一个 example simple service using postgres。仔细看看。第二个示例显示了此问题中询问的那个,其中所有步骤都在虚拟机上 运行。

正如@Rob 指出的那样,容器中 settings.py 和 PostgreSQL 运行 之间的配置是错误的。简而言之,容器中的 PostgreSQL 数据库无法访问您的密钥,因此您需要明确提供它们。

settings.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
    }
}

我使用django-environ来存储我的环境变量。 os.getenv 也适用于此。只需将 os.getenv 更改为 env.

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

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

在同一个文件中,以安全的方式使用所有环境变量是可以的。例如,这显示了我的 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

最后,在 Github 存储库机密中,将您的变量定义为:

POSTGRES_HOST --> localhost
POSTGRES_DB --> postgres
POSTGRES_USER --> postgres
POSTGRES_PASSWORD --> postgres
DEBUG --> True
SECRET_KEY --> <Your Django Secret Key>

最后,您将拥有: