The docker image pangolin:postgresql does not check if migrations have already been done #967

Closed
opened 2026-04-05 18:04:16 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @kevin-gillet on 9/3/2025

The application starts successfully on the first deployment, but subsequent container restarts fail during the migration phase.

The migration system attempts to recreate existing database tables and re-insert migration version records, resulting in constraint violations.

Configuration of the docker-compose stack :

  pangolin:
    container_name: pangolin
    healthcheck:
      interval: 3s
      retries: 20
      test:
        - CMD
        - curl
        - '-f'
        - http://localhost:3001/api/v1/
    image: fosrl/pangolin:postgresql-1.9.4
    restart: unless-stopped
    volumes:
      - ./pangolin/config:/app/config

This behavior is the same with the following images fosrl/pangolin:postgresql-1.9.[0-3] i tested.

Below are the error logs from a failed container restart:

root@debian-amd64[~]# docker logs 90e12ff1f7d2

> @fosrl/pangolin@0.0.0 start
> DB_TYPE=sqlite NODE_OPTIONS=--enable-source-maps NODE_ENV=development ENVIRONMENT=prod sh -c 'node dist/migrations.mjs && node dist/server.mjs'

Migrations table does not exist, creating it...
Running migrations...
Error running migrations: DrizzleQueryError: Failed query: CREATE TABLE "actions" (
        "actionId" varchar PRIMARY KEY NOT NULL,
        "name" varchar,
        "description" varchar
);

params: 
    at NodePgPreparedQuery.queryWithCache (/app/node_modules/src/pg-core/session.ts:73:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async <anonymous> (/app/node_modules/src/pg-core/dialect.ts:102:7)
    ... 4 lines matching cause stack trace ...
    at async ye (file:///app/dist/migrations.mjs:168:298)
    at async file:///app/dist/migrations.mjs:168:267 {
  query: 'CREATE TABLE "actions" (\n' +
    '\t"actionId" varchar PRIMARY KEY NOT NULL,\n' +
    '\t"name" varchar,\n' +
    '\t"description" varchar\n' +
    ');\n',
  params: [],
  cause: error: relation "actions" already exists
      at /app/node_modules/pg/lib/client.js:545:17
      at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
      at async <anonymous> (/app/node_modules/src/node-postgres/session.ts:149:14)
      at async NodePgPreparedQuery.queryWithCache (/app/node_modules/src/pg-core/session.ts:71:12)
      at async <anonymous> (/app/node_modules/src/pg-core/dialect.ts:102:7)
      at async NodePgSession.transaction (/app/node_modules/src/node-postgres/session.ts:258:19)
      at async PgDialect.migrate (/app/node_modules/src/pg-core/dialect.ts:95:3)
      at async migrate (/app/node_modules/src/node-postgres/migrator.ts:10:2)
      at async Te (file:///app/dist/migrations.mjs:168:695)
      at async ye (file:///app/dist/migrations.mjs:168:298) {
    length: 101,
    severity: 'ERROR',
    code: '42P07',
    detail: undefined,
    hint: undefined,
    position: undefined,
    internalPosition: undefined,
    internalQuery: undefined,
    where: undefined,
    schema: undefined,
    table: undefined,
    column: undefined,
    dataType: undefined,
    constraint: undefined,
    file: 'heap.c',
    line: '1159',
    routine: 'heap_create_with_catalog'
  }
}
Error running migrations: DrizzleQueryError: Failed query: insert into "versionMigrations" ("version", "executedAt") values ($1, $2)
params: 1.9.4,1756942541459
    at NodePgPreparedQuery.queryWithCache (/app/node_modules/src/pg-core/session.ts:73:11)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async Te (file:///app/dist/migrations.mjs:168:848)
    at async ye (file:///app/dist/migrations.mjs:168:298)
    at async file:///app/dist/migrations.mjs:168:267 {
  query: 'insert into "versionMigrations" ("version", "executedAt") values ($1, $2)',
  params: [ '1.9.4', 1756942541459 ],
  cause: error: duplicate key value violates unique constraint "versionMigrations_pkey"
      at /app/node_modules/pg-pool/index.js:45:11
      at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
      at async <anonymous> (/app/node_modules/src/node-postgres/session.ts:149:14)
      at async NodePgPreparedQuery.queryWithCache (/app/node_modules/src/pg-core/session.ts:71:12)
      at async Te (file:///app/dist/migrations.mjs:168:848)
      at async ye (file:///app/dist/migrations.mjs:168:298)
      at async file:///app/dist/migrations.mjs:168:267 {
    length: 225,
    severity: 'ERROR',
    code: '23505',
    detail: 'Key (version)=(1.9.4) already exists.',
    hint: undefined,
    position: undefined,
    internalPosition: undefined,
    internalQuery: undefined,
    where: undefined,
    schema: 'public',
    table: 'versionMigrations',
    column: undefined,
    dataType: undefined,
    constraint: 'versionMigrations_pkey',
    file: 'nbtinsert.c',
    line: '666',
    routine: '_bt_check_unique'
  }
}

Side note, this is weird to have > DB_TYPE=sqlite on a postgres DB backend image, could it be part of the cause ? I mean the requests seems to be well formed and played, but this is confusing.

*Originally created by @kevin-gillet on 9/3/2025* The application starts successfully on the first deployment, but subsequent container restarts fail during the migration phase. The migration system attempts to recreate existing database tables and re-insert migration version records, resulting in constraint violations. Configuration of the docker-compose stack : ``` pangolin: container_name: pangolin healthcheck: interval: 3s retries: 20 test: - CMD - curl - '-f' - http://localhost:3001/api/v1/ image: fosrl/pangolin:postgresql-1.9.4 restart: unless-stopped volumes: - ./pangolin/config:/app/config ``` This behavior is the same with the following images fosrl/pangolin:postgresql-1.9.[0-3] i tested. Below are the error logs from a failed container restart: ``` root@debian-amd64[~]# docker logs 90e12ff1f7d2 > @fosrl/pangolin@0.0.0 start > DB_TYPE=sqlite NODE_OPTIONS=--enable-source-maps NODE_ENV=development ENVIRONMENT=prod sh -c 'node dist/migrations.mjs && node dist/server.mjs' Migrations table does not exist, creating it... Running migrations... Error running migrations: DrizzleQueryError: Failed query: CREATE TABLE "actions" ( "actionId" varchar PRIMARY KEY NOT NULL, "name" varchar, "description" varchar ); params: at NodePgPreparedQuery.queryWithCache (/app/node_modules/src/pg-core/session.ts:73:11) at process.processTicksAndRejections (node:internal/process/task_queues:105:5) at async <anonymous> (/app/node_modules/src/pg-core/dialect.ts:102:7) ... 4 lines matching cause stack trace ... at async ye (file:///app/dist/migrations.mjs:168:298) at async file:///app/dist/migrations.mjs:168:267 { query: 'CREATE TABLE "actions" (\n' + '\t"actionId" varchar PRIMARY KEY NOT NULL,\n' + '\t"name" varchar,\n' + '\t"description" varchar\n' + ');\n', params: [], cause: error: relation "actions" already exists at /app/node_modules/pg/lib/client.js:545:17 at process.processTicksAndRejections (node:internal/process/task_queues:105:5) at async <anonymous> (/app/node_modules/src/node-postgres/session.ts:149:14) at async NodePgPreparedQuery.queryWithCache (/app/node_modules/src/pg-core/session.ts:71:12) at async <anonymous> (/app/node_modules/src/pg-core/dialect.ts:102:7) at async NodePgSession.transaction (/app/node_modules/src/node-postgres/session.ts:258:19) at async PgDialect.migrate (/app/node_modules/src/pg-core/dialect.ts:95:3) at async migrate (/app/node_modules/src/node-postgres/migrator.ts:10:2) at async Te (file:///app/dist/migrations.mjs:168:695) at async ye (file:///app/dist/migrations.mjs:168:298) { length: 101, severity: 'ERROR', code: '42P07', detail: undefined, hint: undefined, position: undefined, internalPosition: undefined, internalQuery: undefined, where: undefined, schema: undefined, table: undefined, column: undefined, dataType: undefined, constraint: undefined, file: 'heap.c', line: '1159', routine: 'heap_create_with_catalog' } } Error running migrations: DrizzleQueryError: Failed query: insert into "versionMigrations" ("version", "executedAt") values ($1, $2) params: 1.9.4,1756942541459 at NodePgPreparedQuery.queryWithCache (/app/node_modules/src/pg-core/session.ts:73:11) at process.processTicksAndRejections (node:internal/process/task_queues:105:5) at async Te (file:///app/dist/migrations.mjs:168:848) at async ye (file:///app/dist/migrations.mjs:168:298) at async file:///app/dist/migrations.mjs:168:267 { query: 'insert into "versionMigrations" ("version", "executedAt") values ($1, $2)', params: [ '1.9.4', 1756942541459 ], cause: error: duplicate key value violates unique constraint "versionMigrations_pkey" at /app/node_modules/pg-pool/index.js:45:11 at process.processTicksAndRejections (node:internal/process/task_queues:105:5) at async <anonymous> (/app/node_modules/src/node-postgres/session.ts:149:14) at async NodePgPreparedQuery.queryWithCache (/app/node_modules/src/pg-core/session.ts:71:12) at async Te (file:///app/dist/migrations.mjs:168:848) at async ye (file:///app/dist/migrations.mjs:168:298) at async file:///app/dist/migrations.mjs:168:267 { length: 225, severity: 'ERROR', code: '23505', detail: 'Key (version)=(1.9.4) already exists.', hint: undefined, position: undefined, internalPosition: undefined, internalQuery: undefined, where: undefined, schema: 'public', table: 'versionMigrations', column: undefined, dataType: undefined, constraint: 'versionMigrations_pkey', file: 'nbtinsert.c', line: '666', routine: '_bt_check_unique' } } ``` Side note, this is weird to have `> DB_TYPE=sqlite` on a postgres DB backend image, could it be part of the cause ? I mean the requests seems to be well formed and played, but this is confusing.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/pangolin#967