仅第一个 SQL 脚本在 Docker Postgres 容器内执行

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

我正在尝试在 docker 容器内运行两个 PSQL 脚本,我的想法是我想使用 docker healthcheck 功能来等待数据库准备好运行脚本,第一个创建自定义数据库,第二个是在该自定义数据库上运行

什么可能导致第一个脚本运行(创建数据库)但第二个脚本不运行?

这是 pg-server.Dockerfile

    # Use official PostgreSQL image
    FROM postgres:latest
    
    # Copy the initialization scripts into the container
    COPY ./00_init-database.sql /docker-entrypoint-initdb.d/
    COPY ./01_create-tables.sql /docker-entrypoint-initdb.d/

docker-compose 文件有这个

services:
  postgres:
    build:
      context: ./database
      dockerfile: pg-server.Dockerfile
    ports:
      - "5432:5432"
    volumes:
      - ./database/pg_data:/docker-entrypoint-initdb.d/
    environment:
      POSTGRES_DB: cloud_parking_db
      POSTGRES_USER: someUser
      POSTGRES_PASSWORD: somePassword
      INIT_DB: "true"
    healthcheck:
      test:
        [
          "CMD",
          "pg_isready",
          "-q",
          "-d",
          "cloud_parking_db",
          "-U",
          "someUser"
        ]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - cp_network

当我 docker-compose build 和 up 时,正在创建数据库,但未创建表

这是 postgress 容器的日志

2024-03-31 15:49:14 The files belonging to this database system will be owned by user "postgres".
2024-03-31 15:49:14 This user must also own the server process.
2024-03-31 15:49:14 
2024-03-31 15:49:14 The database cluster will be initialized with locale "en_US.utf8".
2024-03-31 15:49:14 The default database encoding has accordingly been set to "UTF8".
2024-03-31 15:49:14 The default text search configuration will be set to "english".
2024-03-31 15:49:14 
2024-03-31 15:49:14 Data page checksums are disabled.
2024-03-31 15:49:14 
2024-03-31 15:49:14 fixing permissions on existing directory /var/lib/postgresql/data ... ok
2024-03-31 15:49:14 creating subdirectories ... ok
2024-03-31 15:49:14 selecting dynamic shared memory implementation ... posix
2024-03-31 15:49:14 selecting default max_connections ... 100
2024-03-31 15:49:14 selecting default shared_buffers ... 128MB
2024-03-31 15:49:14 selecting default time zone ... Etc/UTC
2024-03-31 15:49:14 creating configuration files ... ok
2024-03-31 15:49:14 running bootstrap script ... ok
2024-03-31 15:49:14 performing post-bootstrap initialization ... ok
2024-03-31 15:49:15 syncing data to disk ... ok
2024-03-31 15:49:15 
2024-03-31 15:49:15 
2024-03-31 15:49:15 Success. You can now start the database server using:
2024-03-31 15:49:15 
2024-03-31 15:49:15     pg_ctl -D /var/lib/postgresql/data -l logfile start
2024-03-31 15:49:15 
2024-03-31 15:49:15 waiting for server to start....2024-03-31 20:49:15.075 UTC [48] LOG:  starting PostgreSQL 16.2 (Debian 16.2-1.pgdg120+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
2024-03-31 15:49:15 2024-03-31 20:49:15.078 UTC [48] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2024-03-31 15:49:15 2024-03-31 20:49:15.087 UTC [51] LOG:  database system was shut down at 2024-03-31 20:49:14 UTC
2024-03-31 15:49:15 2024-03-31 20:49:15.094 UTC [48] LOG:  database system is ready to accept connections
2024-03-31 15:49:15  done
2024-03-31 15:49:15 server started
2024-03-31 15:49:15 CREATE DATABASE
2024-03-31 15:49:15 
2024-03-31 15:49:15 
2024-03-31 15:49:15 /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
2024-03-31 15:49:15 
2024-03-31 15:49:15 waiting for server to shut down...2024-03-31 20:49:15.300 UTC [48] LOG:  received fast shutdown request
2024-03-31 15:49:15 .2024-03-31 20:49:15.302 UTC [48] LOG:  aborting any active transactions
2024-03-31 15:49:15 2024-03-31 20:49:15.304 UTC [48] LOG:  background worker "logical replication launcher" (PID 54) exited with exit code 1
2024-03-31 15:49:15 2024-03-31 20:49:15.304 UTC [49] LOG:  shutting down
2024-03-31 15:49:15 2024-03-31 20:49:15.307 UTC [49] LOG:  checkpoint starting: shutdown immediate
2024-03-31 15:49:15 2024-03-31 20:49:15.399 UTC [49] LOG:  checkpoint complete: wrote 923 buffers (5.6%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.020 s, sync=0.064 s, total=0.095 s; sync files=301, longest=0.004 s, average=0.001 s; distance=4257 kB, estimate=4257 kB; lsn=0/1913078, redo lsn=0/1913078
2024-03-31 15:49:15 2024-03-31 20:49:15.405 UTC [48] LOG:  database system is shut down
2024-03-31 15:49:15  done
2024-03-31 15:49:15 server stopped
2024-03-31 15:49:15 
2024-03-31 15:49:15 PostgreSQL init process complete; ready for start up.
2024-03-31 15:49:15 
2024-03-31 15:49:15 initdb: warning: enabling "trust" authentication for local connections
2024-03-31 15:49:15 initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
2024-03-31 15:49:15 2024-03-31 20:49:15.537 UTC [1] LOG:  starting PostgreSQL 16.2 (Debian 16.2-1.pgdg120+2) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
2024-03-31 15:49:15 2024-03-31 20:49:15.538 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2024-03-31 15:49:15 2024-03-31 20:49:15.538 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2024-03-31 15:49:15 2024-03-31 20:49:15.543 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2024-03-31 15:49:15 2024-03-31 20:49:15.550 UTC [64] LOG:  database system was shut down at 2024-03-31 20:49:15 UTC
2024-03-31 15:49:15 2024-03-31 20:49:15.560 UTC [1] LOG:  database system is ready to accept connections
2024-03-31 15:54:15 2024-03-31 20:54:15.550 UTC [62] LOG:  checkpoint starting: time
2024-03-31 15:54:19 2024-03-31 20:54:19.911 UTC [62] LOG:  checkpoint complete: wrote 46 buffers (0.3%); 0 WAL file(s) added, 0 removed, 0 recycled; write=4.324 s, sync=0.018 s, total=4.361 s; sync files=13, longest=0.008 s, average=0.002 s; distance=261 kB, estimate=261 kB; lsn=0/19544E8, redo lsn=0/19544B0

数据库脚本

00_init-database.sql

DO $$
BEGIN
    IF current_setting('INIT_DB') = 'true' THEN
        -- Drop the database if it already exists
        IF EXISTS (SELECT 1 FROM pg_database WHERE datname = 'cloud_parking_db') THEN
            DROP DATABASE cloud_parking_db;
        END IF;

        CREATE DATABASE cloud_parking_db;

    END IF;
END $$;

01_create-tables.sql
有这个

DO $$
BEGIN
    IF current_setting('INIT_DB') = 'true' THEN
        BEGIN;
            -- Create the ParkingUser table
            CREATE TABLE ParkingUser (
                UserId SERIAL PRIMARY KEY,
                Username VARCHAR(50) NOT NULL,
                Email VARCHAR(100) NOT NULL,
                Password VARCHAR(255) NOT NULL,
                Role VARCHAR(20) NOT NULL
            );

            -- Create the Country table
            CREATE TABLE Country (
                CountryId SERIAL PRIMARY KEY,
                Name VARCHAR(100) NOT NULL
            );
            -- more tables 
       COMMIT ;
    END IF;
END $$;
postgresql docker docker-compose
1个回答
0
投票

在您的 Compose 文件中

volumes:
  - ./database/pg_data:/docker-entrypoint-initdb.d/

volumes:
始终隐藏挂载点上映像中的任何内容,因此当容器启动时,您将看到
pg_data
目录的内容,而不是您在映像中复制的脚本。

postgres
图像的入口点包装脚本循环遍历初始化脚本。如果 initdb 目录为空,则循环顶部的 shell 扩展将仅返回
*
,并且您将收到在启动日志中引用的
ignoring /docker-entrypoint-initdb.d/*
消息。

您通常不应在映像中的非空目录上挂载卷,删除此块应该会有所帮助。

从主机目录名来看,你的意思是这个用来持久化数据库数据吗?在这种情况下,您的右侧目录是错误的,而您想要

volumes:
  - ./database/pg_data:/var/lib/postgresql/data

您看到的效果不是第一个 init 脚本运行,而是入口点脚本理解

POSTGRES_DB
环境变量并为您创建数据库。 (它永远不会存在,并且您不需要此脚本。)考虑通过应用程序框架的数据库迁移系统运行第二个脚本,以便您可以在数据库架构更改时增量运行它,这样它就不会存在特别与 Docker 相关。

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