Search code examples
postgresqldockerdocker-composedockerfile

PostgreSQL Server Too High Of A Version


I am currently getting this error message:

db-1      |
db-1      | PostgreSQL Database directory appears to contain a database; Skipping initialization
db-1      |
db-1      | 2023-12-09 23:47:52.107 UTC [1] FATAL:  database files are incompatible with server
db-1      | 2023-12-09 23:47:52.107 UTC [1] DETAIL:  The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 13.13 (Debian 13.13-1.pgdg120+1).
db-1 exited with code 1

My docker files is as follows:

version: '3'

services:
  server:
    image: registry.gitlab.com/commento/commento:v1.4.0
    ports:
      - 8080:8080
    environment:
      COMMENTO_ORIGIN: http://127.0.0.1:8080
      COMMENTO_PORT: 8080
      COMMENTO_POSTGRES: postgres://postgres:admin@db:5433/commento?sslmode=disable
    depends_on:
      - db
  db:
    image: postgres:13
    environment:
      POSTGRES_DB: postgres 
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: admin
    volumes:
      - postgres_data_volume:/Program Files/PostgreSQL/13/data

volumes:
  postgres_data_volume:

I have done everything I could possibly think of, which is the following:

  • Re-initialize the data directory after changing version number
  • Ensured I had the right version through initdb --version
  • Uninstalled PostgreSQL 16 version
  • Checked port numbers to ensure I was on the same port as the PostgreSQL 13 version

I am new to docker, but I have no idea on where to go from here. The tool I am using is Commento, which is no longer supported, which is why I am using an older PostgreSQL version.


Solution

  • I replicated your error, and indeed, you should do what was suggested in the comments: change the PostgreSQL version from 13 to 16 in your Docker Compose file.

    This is the Docker Compose test file I used:

    version: '3'
    
    services:
      db:
        image: postgres:16
        environment:
          POSTGRES_DB: postgres
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: admin
        volumes:
          - db_data:/var/lib/postgresql/data
    
    volumes:
      db_data:
    

    And these are the logs when running docker compose up for the first time:

    ...
    test-db-1  | PostgreSQL init process complete; ready for start up.
    test-db-1  | 
    test-db-1  | 2023-12-10 02:23:02.240 UTC [1] LOG:  starting PostgreSQL 16.1 (Debian 16.1-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
    test-db-1  | 2023-12-10 02:23:02.241 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
    test-db-1  | 2023-12-10 02:23:02.243 UTC [1] LOG:  could not create IPv6 socket for address "::": Address family not supported by protocol
    test-db-1  | 2023-12-10 02:23:02.255 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
    test-db-1  | 2023-12-10 02:23:02.272 UTC [63] LOG:  database system was shut down at 2023-12-10 02:23:02 UTC
    test-db-1  | 2023-12-10 02:23:02.284 UTC [1] LOG:  database system is ready to accept connections
    

    As you can see, the initialization of the database has been completed successfully, so the database is already populated with data stored in volume db_data. Now, I will change the PostgreSQL version to 13 (image: postgres:13), and this is the result:

    test-db-1  | PostgreSQL Database directory appears to contain a database; Skipping initialization
    test-db-1  | 
    test-db-1  | 2023-12-10 02:25:02.528 UTC [1] FATAL:  database files are incompatible with server
    test-db-1  | 2023-12-10 02:25:02.528 UTC [1] DETAIL:  The data directory was initialized by PostgreSQL version 16, which is not compatible with this version 13.13 (Debian 13.13-1.pgdg120+1).
    

    If I change the PostgreSQL version back to 16 again (image: postgres:16), everything returns to normal:

    test-db-1  | PostgreSQL Database directory appears to contain a database; Skipping initialization
    test-db-1  | 
    test-db-1  | 2023-12-10 02:26:03.538 UTC [1] LOG:  starting PostgreSQL 16.1 (Debian 16.1-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
    test-db-1  | 2023-12-10 02:26:03.540 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
    test-db-1  | 2023-12-10 02:26:03.542 UTC [1] LOG:  could not create IPv6 socket for address "::": Address family not supported by protocol
    test-db-1  | 2023-12-10 02:26:03.554 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
    test-db-1  | 2023-12-10 02:26:03.576 UTC [29] LOG:  database system was shut down at 2023-12-10 02:24:19 UTC
    test-db-1  | 2023-12-10 02:26:03.588 UTC [1] LOG:  database system is ready to accept connections
    

    By the way, I can't think of where the path /Program Files/PostgreSQL/13/data came from in your configuration, because in PostgreSQL Docker images the default path for PostgreSQL data is /var/lib/postgresql/data (as shown in my configuration), unless you set another path in the PGDATA environment variable.

    Edit 1:

    I just noticed that you need to use an older version of PostgreSQL. Therefore, you will have to reinitialize the database because, even though PostgreSQL has tools to migrate data from an older version to a newer one, I don't believe (but I could be mistaken) it has tools to migrate data from a newer version to an older one (as is your case). For this, you have two easy options:

    1. Rename volume postgres_data_volume so that a new volume is created, and PostgreSQL initializes the database again. This is the best option because you will keep the old volume postgres_data_volume (and all its data) in case you need it later.
    2. Delete the volume postgres_data_volume (only do this if you don't have important data in the database) using command docker compose down -v and execute command docker compose up to recreate it, which will also get PostgreSQL to initialize the database again.