无法使用 PHP PDO 和 Docker 连接到 Postgres 数据库

Can't connect to Postgres database using PHP PDO and Docker

我是 运行 一个基于三个图像构建的 Docker 应用程序:php:7.4-fpmnginx:stable-alpinepostgres:alpine

我之前尝试使用图像 php:7.4-fpm-alpine,但显然它没有随 Postgres PDO 驱动程序一起提供,这导致了 could not find driver 错误。 This post 对此进行了详细说明,以及如何修复它。我按照 post 中的步骤进行操作,包括为我的 PHP FPM 服务创建 Dockerfile(尽管我没有创建 PHP CLI 服务),这修复了我的驱动程序问题。但是,当我尝试使用 PDO 连接到我的 PSQL 数据库时出现以下错误:

SQLSTATE[08006] [7] could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 6432?

我知道我的数据库是 运行(在端口 6432 上),因为我可以从我的终端和 Positco 访问它,并且在我的 Docker 应用程序创建后创建了表。我还尝试连接到端口 5432 上的数据库(我的 Postgres 桌面应用程序通过该端口 运行),但这也不起作用。我也尝试重新启动我的 Postgres 容器,但这没有帮助。

这是我的 PHP:

class Database {

    private $connection;

    private static $options = array(
        PDO::ATTR_EMULATE_PREPARES => FALSE, 
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
    );

    public function __construct() {
        try {
            $dsn = 'pgsql:host=localhost;port=6432;dbname=db_my_test_app';
            $username = 'root';
            $password = 'secret';
            $connection = new PDO($dsn, $username, $password, self::$options);
            $this->connection = $connection;
            return $connection;      
        } catch (PDOException $e) {
            exit($e->getMessage());
        }
    }
}

$database = new Database();

...和我的 docker-compose.yml 文件:

version: '3'

networks: 
    my_test_app:

services: 

    # nginx
    nginx-service:
        image: nginx:stable-alpine
        container_name: nginx-container
        ports: 
            - "8080:80"
        volumes: 
            - ./app:/var/www/project
            - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
        depends_on: 
            - php-fpm-service
            - postgres-service
        networks: 
            - my_test_app  
  
    # php
    php-fpm-service:
        build: 
            context: .
            dockerfile: ./php-fpm/Dockerfile
        container_name: php-fpm-container
        ports:
            - "9000:9000"
        working_dir: /var/www/project
        volumes:
            - ./app:/var/www/project
        networks: 
            - my_test_app  

    # postgres
    postgres-service:
        image: postgres:alpine
        container_name: postgres-container
        ports: 
            - "6432:5432"
        volumes: 
            - ./postgres:/var/lib/postgresql/data
        restart: always
        environment: 
            POSTGRES_USER: root
            POSTGRES_PASSWORD: secret
            POSTGRES_DB: db_my_test_app
        networks: 
            - my_test_app

...和 ​​PHP 服务 Dockerfile(来自上述站点):

FROM php:7.4-fpm
RUN apt-get update && apt-get install -y libpq-dev
RUN docker-php-ext-install pdo pdo_pgsql pgsql
RUN ln -s /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini
RUN sed -i -e 's/;extension=pgsql/extension=pgsql/' /usr/local/etc/php/php.ini
RUN sed -i -e 's/;extension=pdo_pgsql/extension=pdo_pgsql/' /usr/local/etc/php/php.ini

您正在默认网络模式下配置 docker:bridge。为了使 php-fpm-service 能够访问 postgres-service,您需要进行以下修改:

docker-compose.yml 文件中,您需要将 depends_on 添加到 php-fpm-service

# php
php-fpm-service:
    build: 
        context: .
        dockerfile: ./php-fpm/Dockerfile
    container_name: php-fpm-container
    ports:
        - "9000:9000"
    working_dir: /var/www/project
    volumes:
        - ./app:/var/www/project
    networks: 
        - my_test_app  
    depends_on:
        - postgres-service

在您的 PHP 配置中,您需要将 localhost 修改为 postgres-service 并使用端口 5432:

$dsn = 'pgsql:host=postgres-service;port=5432;dbname=db_my_test_app';