You will have to do the following:

  1. Make the content of the SQL file as a ConfigMap like this, for example:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: mariadb-config
    data:
      mariadb-schema: "DROP DATABASE IF EXISTS test;\n\nCREATE DATABASE IF NOT EXISTS test;
    
  2. Make a volume from this config map in your deployment yaml like this:

     volumes:
     - name: mariadb-schema-config-vol
       configMap:
         name: mariadb-config
         defaultMode: 420
         items:
         - key: mariadb-schema
           path: mariadb-schema.sql
    

    And volume mount like this:

     volumeMounts:
     - mountPath: /var/db/config
       name: mariadb-schema-config-vol
    

Then your init container command will be like:

    ['sh', '-c', 'psql -a -f /var/db/config/mariadb-config.sql']

For your second question, make a shell script that reads the env variables (The db credentials - I am presuming that you are having them in secrets and using them as env variables) and then invoke this command:

   psql -a -f /var/db/config/mariadb-config.sql

So to make this happen the content of this script should be in a config map and execute the script from a volume mount, just like the above example.

Hope this helps.

Answer from Amit on Stack Overflow
🌐
Docker
hub.docker.com › _ › postgres
postgres - Official Image | Docker Hub
After the entrypoint calls initdb to create the default postgres user and database, it will run any *.sql files, run any executable *.sh scripts, and source any non-executable *.sh scripts found in that directory to do further initialization before starting the service. Warning: scripts in /docker-entrypoint-initdb.d are only run if you start the container with a data directory that is empty; any pre-existing database will be left untouched on container startup.
🌐
GitHub
gist.github.com › onjin › 2dd3cc52ef79069de1faa2dfd456c945
example docker compose for postgresql with db init script · GitHub
This is because Postgres does not execute init scripts if postgres-data folder is present. So I just renamed it to postgres and it works like a charm! ... Thanks @Juliannnnshipit for your help. I got it working. ... #!/usr/bin/env bash psql "postgres://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_HOST/$POSTGRES_DB?sslmode=disable" <<-EOSQL -- YOUR SQL Statements here EOSQL ... postgresdb: image: postgres:9.4 container_name: postgresdb environment: - POSTGRES_USER=${DB_USER} - POSTGRES_PASSWORD=${DB_PASS} - POSTGRES_DB=${DB_NAME} - DATABASE_HOST=${DB_HOST} ports: - 5433:5432 volumes: - ./contrib/setup.sh:/docker-entrypoint-initdb.d/initdb.sh - ./pgdata:/var/lib/postgresql/data
Discussions

postgresql - How to mount a sql file in a Init Container in order to bootstrap Postgres Database - Stack Overflow
I am working on adding an init-container in my app's deployment.yaml so I can decouple my postgres db bootstrap or schema evolution. As V1 I am trying to mount a sql file that will include the More on stackoverflow.com
🌐 stackoverflow.com
bash - How to create User/Database in script for Docker Postgres - Stack Overflow
I have been trying to set up a container for a development postgres instance by creating a custom user & database. I am using the official postgres docker image. In the documentation it instructs you to insert a bash script inside of the /docker-entrypoint-initdb.d/ folder to set up the database ... More on stackoverflow.com
🌐 stackoverflow.com
docker - How to initialize PostgreSQL database directly within a Dockerfile? - Stack Overflow
# syntax = docker/dockerfile:1.4.0 ...ous/pg/bin/pg_isready; do sleep 1; done; RUN psql -f init.sql · But it looks like the postgresql never started (or stayed up). ... I don't want to run PostgreSQL as a separate container, I want to just run this whole thing in a box, is it ... More on stackoverflow.com
🌐 stackoverflow.com
postgresql - Create or update existing postgres db container through kubernetes job - Stack Overflow
I need to write a Kubernetes job to connect to the Postgres DB container and run the scripts from SQL file. I need to understand two things here ... apiVersion: batch/v1 kind: Job metadata: name: init-db spec: template: metadata: name: init-db labels: app: init-postgresdb spec: containers: ... More on stackoverflow.com
🌐 stackoverflow.com
October 18, 2019
🌐
Docker
docs.docker.com › guides › pre-seeding database with schema and data at startup for development environment
Pre-seeding database with schema and data at startup for development environment | Docker Docs
Now that you have learned how to launch Postgres and pre-seed the database using an SQL script, it’s time to learn how to mount an SQL file directly into the Postgres containers’ initialization directory (/docker-entrypoint-initdb.d).
Top answer
1 of 2
1

You will have to do the following:

  1. Make the content of the SQL file as a ConfigMap like this, for example:

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: mariadb-config
    data:
      mariadb-schema: "DROP DATABASE IF EXISTS test;\n\nCREATE DATABASE IF NOT EXISTS test;
    
  2. Make a volume from this config map in your deployment yaml like this:

     volumes:
     - name: mariadb-schema-config-vol
       configMap:
         name: mariadb-config
         defaultMode: 420
         items:
         - key: mariadb-schema
           path: mariadb-schema.sql
    

    And volume mount like this:

     volumeMounts:
     - mountPath: /var/db/config
       name: mariadb-schema-config-vol
    

Then your init container command will be like:

    ['sh', '-c', 'psql -a -f /var/db/config/mariadb-config.sql']

For your second question, make a shell script that reads the env variables (The db credentials - I am presuming that you are having them in secrets and using them as env variables) and then invoke this command:

   psql -a -f /var/db/config/mariadb-config.sql

So to make this happen the content of this script should be in a config map and execute the script from a volume mount, just like the above example.

Hope this helps.

2 of 2
0

Was looking into something similar and found the following approach as of 11.5.24 (postgres:16.2 docker image and kubernetes v1.31):

  1. I had an existing SQL init file init.sql.
  2. I ran kubectl create configmap initsql --from-file=init.sql to generate a configMap file. I renamed the file something like postgres-init.yaml.
  3. I kubectl apply -f postgres-init.yaml.
  4. I have a standard-fare postgres-deployment.yaml - basically copied from the official examples with a few modification.
  5. In volumes, I added:
    volumes:
      - ...
      - name: sql-init-mount
        configMap:
          name: initsql
          items:
           - key: init.sql
             path: init.sql
    
  6. In the same postgres-deployment.yaml I added to the postgres container itself:
    volumeMounts:
      - mountPath: /docker-entrypoint-initdb.d
        name: sql-init-mount
    
  7. The official postgres Docker image supports automatic initialization of any scripts dropped into docker-entrypoint-initdb.d.

I had a suspicion that using a configMap might accomplish the same thing without using containerInit or any commands. Turns out I was correct, you may need to wait moment but if you:

  1. minikube dashboard the deployed postgres pod can be found and you can easily exec in (if you're doing this locally) to verify the existing of the file (created corrected) and run: psql -U postgres -d postgres to login and query.
🌐
Mkyong
mkyong.com › home › docker › how to run an init script for docker postgres
How to run an init script for Docker Postgres - Mkyong.com
September 22, 2023 - To run the init script, copy the `*.sql` to the Docker Postgres container `/docker-entrypoint-initdb.d` directory.
Top answer
1 of 10
654

EDIT - since Jul 23, 2015

The official postgres docker image will run .sql scripts found in the /docker-entrypoint-initdb.d/ folder.

So all you need is to create the following sql script:

init.sql

CREATE USER docker;
CREATE DATABASE docker;
GRANT ALL PRIVILEGES ON DATABASE docker TO docker;

and add it in your Dockerfile:

Dockerfile

FROM library/postgres
COPY init.sql /docker-entrypoint-initdb.d/

But since July 8th, 2015, if all you need is to create a user and database, it is easier to just make use to the POSTGRES_USER, POSTGRES_PASSWORD and POSTGRES_DB environment variables:

docker run -e POSTGRES_USER=docker -e POSTGRES_PASSWORD=docker -e POSTGRES_DB=docker library/postgres

or with a Dockerfile:

FROM library/postgres
ENV POSTGRES_USER docker
ENV POSTGRES_PASSWORD docker
ENV POSTGRES_DB docker

for images older than Jul 23, 2015

From the documentation of the postgres Docker image, it is said that

[...] it will source any *.sh script found in that directory [/docker-entrypoint-initdb.d] to do further initialization before starting the service

What's important here is "before starting the service". This means your script make_db.sh will be executed before the postgres service would be started, hence the error message "could not connect to database postgres".

After that there is another useful piece of information:

If you need to execute SQL commands as part of your initialization, the use of Postgres single user mode is highly recommended.

Agreed this can be a bit mysterious at the first look. What it says is that your initialization script should start the postgres service in single mode before doing its actions. So you could change your make_db.ksh script as follows and it should get you closer to what you want:

NOTE, this has changed recently in the following commit. This will work with the latest change:

export PGUSER=postgres
psql <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL

Previously, the use of --single mode was required:

gosu postgres postgres --single <<- EOSQL
    CREATE USER docker;
    CREATE DATABASE docker;
    GRANT ALL PRIVILEGES ON DATABASE docker TO docker;
EOSQL
2 of 10
63

By using docker-compose:

Assuming that you have following directory layout:

$MYAPP_ROOT/docker-compose.yml
           /Docker/init.sql
           /Docker/db.Dockerfile

File: docker-compose.yml

version: "3.3"
services:
  db:
    build:
      context: ./Docker
      dockerfile: db.Dockerfile
    volumes:
      - ./var/pgdata:/var/lib/postgresql/data
    ports:
      - "5432:5432"

File: Docker/init.sql

CREATE USER myUser;

CREATE DATABASE myApp_dev;
GRANT ALL PRIVILEGES ON DATABASE myApp_dev TO myUser;

CREATE DATABASE myApp_test;
GRANT ALL PRIVILEGES ON DATABASE myApp_test TO myUser;

File: Docker/db.Dockerfile

FROM postgres:11.5-alpine
COPY init.sql /docker-entrypoint-initdb.d/

Composing and starting services:

docker-compose -f docker-compose.yml up --no-start
docker-compose -f docker-compose.yml start
🌐
Red Hat
developers.redhat.com › learning › learn:openshift:build-and-populate-database-using-kubernetes-init-containers › resource › resources:create-postgresql-instance-configmap-and-deployment-objects
Create the PostgreSQL instance, ConfigMap, and Deployment objects | Build and populate a database using Kubernetes init containers | Red Hat Developer
February 17, 2026 - Rather than recreate the contents here, you can view the Kubernetes documentation for Init Containers to see how they work. Likewise, you can view the Kubernetes documentation related to configuring a pod to use a ConfigMap. When those two pieces of knowledge are combined, you get a deployment that, in our case, includes the following (an explanation follows this section of the YAML file): spec: initContainers: - name: init-createdb image: postgres:14 command: ["psql", "postgresql://postgres:postgres@postgresql", "-f", "/etc/rsalbums/create_database.sql"] volumeMounts: - name: albums-volume mo
Find elsewhere
🌐
Coding With Spike!
codingwithspike.wordpress.com › 2019 › 12 › 09 › patterns-for-initializing-containers-in-kubernetes
Patterns for Initializing Containers in Kubernetes | Coding With Spike!
December 9, 2019 - When running a kubectl get pods command, it will let you know what init container it is executing, so you may see a pod’s status show Init 1/2 to indicate that one of the two init containers has run so far. Each initContainer also has it’s own log and events, so debugging these items becomes easier. For this example let’s say we want to ensure that our Postgres DB, now that we know it is running from 1) above, has our expected user in it.
🌐
Medium
medium.com › @jinnabaalu › initialise-postgres-container-with-data-d6aeef722b47
Initialise postgres container with data | by Jinna Baalu | Medium
October 4, 2024 - Get the data initialised with the container · Create a docker-compose.yml · services: postgress-postgresql: image: postgres:bullseye container_name: postgres volumes: - postgresql_data:/var/lib/postgresql/data/ - ./init.sql:/docker-entrypoint-initdb.d/init.sql environment: - POSTGRES_USER=postgress - POSTGRES_PASSWORD=MyStrongPassword123 ports: - 5432:5432 networks: - postgres networks: postgres: volumes: postgresql_data: Create a init.sql with the script ·
🌐
Docker
docker.com › blog › how-to-use-the-postgres-docker-official-image
How to Use the Postgres Docker Official Image | Docker
But there are also other variables that influence container behavior: POSTGRES_USER – Specifies a user with superuser privileges and a database with the same name. Postgres uses the default user when this is empty. POSTGRES_DB – Specifies a name for your database or defaults to the POSTGRES_USER value when left blank. POSTGRES_INITDB_ARGS – Sends arguments to postgres_initdb and adds functionality
Published   November 6, 2024
🌐
Reddit
reddit.com › r/docker › postgres init script
r/docker on Reddit: Postgres init script
April 12, 2025 -

I have a standard postgres container running, with the pg_data volume mapped to a directory on the host machine.

I want to be able to run an init script everytime I build or re-build the container, to run migrations and other such things. However, any script or '.sql' file placed in /docker-entrypoint-initdb.d/ only gets executed if the pg_data volume is empty.

What is the easiest solution to this – at the moment I could make a pg_dump pf the pg_data directory, then remove it’s content, and restore from the pg_dump, but it seems pointlessly convoluted and open to errors with potential data loss.

🌐
GitHub
github.com › helm › charts › issues › 14721
[stable/postgresql] Can not run the initContainer when `volumePermissions.securityContext.runAsUser=1001` is set · Issue #14721 · helm/charts
June 12, 2019 - Describe the bug I have an issue with #14538 and try to enable the initContainer, the PSP is set to runAsNonRoot is active in my kubernetes, so If I need to set volumePermissions.securityContext.runAsUser=1001, then I got an error chown:...
Author   sd7y
🌐
Medium
dsysd-dev.medium.com › setting-up-your-own-postgres-database-using-docker-container-b46e5ee22d3a
Setting up your own postgres database using docker container | by dsysd dev | Medium
December 29, 2023 - It also includes a volume mount for initializing the database with an SQL script and uses a custom network. Here’s a breakdown of the key components: Docker Compose Version: — `version: ‘3.8’`: Specifies the version of the Docker Compose file syntax. 2. Services: — `postgres`: Defines a service named “postgres.” · - `image: postgres:latest`: Specifies the PostgreSQL Docker image to use. `latest` refers to the latest version of the image. — `container_name: my_db_pg_container`: Assigns a custom name to the PostgreSQL container.
🌐
Reddit
reddit.com › r/docker › specify an initialization script for postgres, using docker run
r/docker on Reddit: Specify an initialization script for Postgres, using docker run
July 21, 2021 -

I there a way to specify an initialization script for Postgres, using docker run?

If I use Docker Compose, this line will copy the script and run it:

volumes:
  - ./init.sql:/docker-entrypoint-initdb.d/init.sql

However, this syntax doesn't work in the CLI:

$ docker volume create postgres-data
$ docker run --detach \
	--rm \
	--name postgres \
	--publish 5432:5432 \
	--env-file .env \
	--volume postgres-data:/var/lib/postgresql/data \
	--volume ./init.sql:/docker-entrypoint-initdb.d/init.sql \
	postgres:9.6.22

docker: Error response from daemon: create ./init.sql: "./init.sql" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path.

Is this possible?

🌐
Mikebarkas
mikebarkas.dev › how-to-use-variables-psql-initcontainer
Run psql in an initContainer - Mike Barkas
February 2, 2025 - Using psql container and running the psql command directly in the initContainer will have some limitations. Writing long commands will have to be done in the yaml file. ... spec: initContainers: - name: init-db image: my-psql-container command: - /bin/sh - -c - psql -h ${DB_HOST} -U ${DB_USER} -d ${DB_NAME} -c "CREATE TABLE ...." env: - name: DB_HOST value: "my-db-host"