使用 PostgreSQL 的两个 DDEV 项目之间的奇怪干扰

Weird interference between two DDEV projects using PostgreSQL

我正在处理两个使用 PostgreSQL(基于 procedure described here)的 Drupal(7 和 9)项目。当它们同时 运行ning 时我注意到错误:Drupal 7 会抱怨 variable table 不存在,而 Drupal 9 会断开我的连接或显示某种 WSOD。奇怪的是,它们可以 随机 正常工作或在页面重新加载时再次崩溃。但是,当我关闭一个时它会变得非常好。

所有这些让我想起了我配置 PostgreSQL 的方式的一些问题。你能帮我找出我的设置中可能有什么问题吗?

这是我对 Drupal 9 的配置。docker-compose.postgres.yaml:

version: '3.6'
services:
  postgres:
    container_name: ddev-${DDEV_SITENAME}-postgres
    image: postgres:13.4
    ports:
      - 32784:5432
    environment:
      - POSTGRES_PASSWORD=<REDACTED>
      - POSTGRES_USER=<REDACTED>
      - POSTGRES_DB=<REDACTED>
    volumes:
      - type: "volume"
        source: postgres
        target: "/var/lib/postgresql/data"
        volume:
          nocopy: true
      - type: "bind"
        source: "."
        target: "/mnt/ddev_config"
      - ddev-global-cache:/mnt/ddev-global-cache
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: $DDEV_APPROOT
  web:
    links:
      - postgres:postgres

volumes:
  postgres:

和settings.ddev.php:

<?php                                                      
                                                           
/**                                                                                                                    
 * @file                                                   
 * Manually managed.                                       
 */                                                        

$host = "postgres";                                        
$port = 5432;                                              

// If DDEV_PHP_VERSION is not set but IS_DDEV_PROJECT *is*, it means we're running (drush) on the host,
// so use the host-side bind port on docker IP
if (empty(getenv('DDEV_PHP_VERSION') && getenv('IS_DDEV_PROJECT') == 'true')) {
  $host = "127.0.0.1";                                     
  $port = -1;                                              
}                                                          

$databases['default']['default'] = array(
  'database' => "<REDACTED>",                                      
  'username' => "<REDACTED>",                                      
  'password' => "<REDACTED>",                                      
  'host' => $host,                                         
  'driver' => "pgsql",                                     
  'port' => $port,                                         
  'prefix' => "",                                          
);                                                         

(省略哈希和配置设置。)

现在,对于 Drupal 7。docker-compose.postgres.yaml:

version: '3.6'
services:
  postgres:
    container_name: ddev-${DDEV_SITENAME}-postgres
    image: mdillon/postgis:11
    ports:
      - 32785:5432
    environment:
      - POSTGRES_PASSWORD=<REDACTED>
      - POSTGRES_USER=<REDACTED>
      - POSTGRES_DB=<REDACTED>
    volumes:
      - type: "volume"
        source: postgres
        target: "/var/lib/postgresql/data"
        volume:
          nocopy: true
      - type: "bind"
        source: "."
        target: "/mnt/ddev_config"
      - ddev-global-cache:/mnt/ddev-global-cache
    labels:
      com.ddev.site-name: ${DDEV_SITENAME}
      com.ddev.approot: $DDEV_APPROOT
  web:
    links:
      - postgres:postgres

volumes:
  postgres:

settings.ddev.php:

<?php

/**
 * @file
 * Manually managed.
 */

$host = "postgres";
$port = 5432;

// If DDEV_PHP_VERSION is not set but IS_DDEV_PROJECT *is*, it means we're
// running (drush) on the host, so use the host-side bind port on docker IP.
if (empty(getenv('DDEV_PHP_VERSION') && getenv('IS_DDEV_PROJECT') == 'true')) {
  $host = "127.0.0.1";
  $port = 32784;
}

$databases['default']['default'] = [
  'database' => "<REDACTED>",
  'username' => "<REDACTED>",
  'password' => "<REDACTED>",
  'host' => $host,
  'driver' => "pgsql",
  'port' => $port,
  'prefix' => "",
];

我能够检查 postgres 实际上是不同 FQDN 和不同 IP 的别名(不是很懂 Docker Compose,抱歉)。

我的系统上有两个不同的卷(虽然我不能保证它们被正确使用):

$ docker volume ls | grep postgres     
local     ddev-mgis_postgres
local     ddev-mgisv5_postgres

当我从 Drupal 7 项目 运行 drush sqlc 时,我看到 Drupal 9 tables 直到关闭另一个项目。真是一场噩梦!

我最担心的是这两个项目可能共享资源,并且可能在某个时间点在同一个地方写入。

我需要能够同时 运行 这两个项目,因为其中一个需要迁移到另一个。

DDEV v1.19+更新

  1. Postgres 现在可以使用带有 DDEV 的盒子,因此不需要额外的 service/container。
  2. 您不再需要为容器使用显式名称,因为 DDEV 中的网络现在更加复杂。

--------- 下面是原始答案---------

您正在使用 $host = "postgres";,请使用 postgres 容器的显式名称,ddev-<project>-postgres

主机名 postgres 在 docker 网络中是不明确的,当您 运行 多个项目都有名为“postgres”的服务时。所以你得到了你看到的行为。

对 ddev-contrib 配方的 PR 将不胜感激;自从大约一年前发现问题以来,这已经在许多 ddev-contrib 食谱中进行了更新,但显然不是这个。