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
🌐
GitHub
github.com › kubedb › docs › blob › master › docs › guides › postgres › initialization › script_source.md
docs/docs/guides/postgres/initialization/script_source.md at master · kubedb/docs
PostgreSQL supports initialization with .sh, .sql and .sql.gz files. In this tutorial, we will use data.sql script from postgres-init-scripts git repository to create a TABLE dashboard in data Schema. We will use a ConfigMap as script source. You can use any Kubernetes supported volume as script source.
Author   kubedb
🌐
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 - 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 mountPath: /etc/rsalbums - name: init-builddb image: postgres:14 command: ["psql", "postgresql://postgres:postgres@postgresql/
Discussions

postgresql - How to mount a sql file in a Init Container in order to bootstrap Postgres Database - Stack Overflow
Was looking into something similar and found the following approach as of 11.5.24 (postgres:16.2 docker image and kubernetes v1.31): I had an existing SQL init file init.sql. 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
Running a shell script to initialize pods in kubernetes (initializing my db cluster) - Stack Overflow
And inside Volumes I will put the configMap name (postgres-init-script-configmap) which is the name of the config defined inside the configmap.yaml file. There is no need to create the configMap using kubernetes, The pod will take the configuration from the configMap file as long as you place ... More on stackoverflow.com
🌐 stackoverflow.com
postgresql - Kubernetes - Postgres - Create Tables - Stack Overflow
You can use this way which also works for Postgres: medium.com/better-programming/… (It's more Docker then Kubernetes related) ... have you been thinking about initContainer that will be checking if DB already exists and create it or do nothing? More on stackoverflow.com
🌐 stackoverflow.com
🌐
Eksworkshop
developers.eksworkshop.com › introduction to kubernetes › initializing postgresql database with kubernetes configmaps
Initializing PostgreSQL Database with Kubernetes ConfigMaps | EKS Developers Workshop
Name: db-init-script Namespace: my-cool-app Labels: <none> Annotations: <none> Data ==== init.sh: ---- #!/bin/bash ... This lab guided you through the process of creating a Kubernetes ConfigMap that securely initializes your PostgreSQL database within a Minikube environment.
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.
🌐
Stackgres
stackgres.io › doc › 1.1 › tutorial › using-initialdata › scripts
initialData Scripts :: StackGres Documentation
apiVersion: stackgres.io/v1 kind: SGCluster metadata: name: stackgres spec: initialData: scripts: - name: create-my-database script: | create database my_db owner postgres; and deploy to Kubernetes: kubectl apply -f sgcluster-with-raw-script.yaml · Note: Avoid this method to create sensitive data like user and passwords.
🌐
Belowthemalt
belowthemalt.com › 2022 › 09 › 18 › setup-of-spring-boot-application-initialization-of-postgresql-database-on-kubernetes-part-1
Setup of spring boot application & initialization of PostgreSQL database on Kubernetes - PART 1 - Blogs, Ideas, Train of Thoughts
September 19, 2022 - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: postgresql-claim0 labels: app: postgresql tier: database spec: accessModes: - ReadWriteOnce resources: requests: storage: 100Mi · Next we want to build a configuration map object, which will have our database initialization scripts · Configuration maps are kubernetes objects which are used to store non-confidential data in key-value pairs
Top answer
1 of 2
2

I finally decided to take the approach of creating a config file with the script we want to run and then call this configMap from inside the volume.

this is a short explanation:

In my pod.yaml file there is a VolumeMount called "/pgconf" which is the directory that the docker image reads any SQL script that you put there and run it when the pod is starting. And inside Volumes I will put the configMap name (postgres-init-script-configmap) which is the name of the config defined inside the configmap.yaml file.

There is no need to create the configMap using kubernetes, The pod will take the configuration from the configMap file as long as you place it in the same directory as the pod.yaml .

my POD yaml file:

apiVersion: v1
kind: Pod
metadata:
  name: "{{.Values.container.name.primary}}"
  labels:
    name: "{{.Values.container.name.primary}}"
spec:
  securityContext:
    fsGroup: 26
  restartPolicy: {{default "Always" .Values.restartPolicy}}

  containers:
  - name: {{.Values.container.name.primary}}
    image: "{{.Values.image.repository}}/{{.Values.image.container}}:{{.Values.image.tag}}"
    ports:
    - containerPort: {{.Values.container.port}}
    env:
    - name: PGHOST
      value: /tmp
    - name: PG_PRIMARY_USER
      value: primaryuser
    - name: PG_MODE
      value: primary
    resources:
      requests:
        cpu: {{ .Values.resources.cpu }}
        memory: {{ .Values.resources.memory }}
    volumeMounts:
    - mountPath: /pgconf
      name: init-script
      readOnly: true
  volumes:
  - name: init-script
    configMap:
      name: postgres-init-script-configmap

my configmap.yaml (Which contains the SQL script that will initial the DB):

apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-init-script-configmap
data:
  setup.sql: |-
    CREATE USER david WITH PASSWORD 'david';
2 of 2
2

It depends what exactly does your init script do. But the InitContainers should be helpful in such cases. Init containers are run before the main application container is started and can do some preparation work such as create configuration files etc.

You would still need your own Docker image, but it doesn't have to be the same image as the database one.

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 added to Kubernetes yaml, you could define something like this to wait for Postgres and RabbitMQ services to both become available: apiVersion: apps/v1 kind: Deployment metadata: name: my-rails-app labels: app: my-rails-app spec: selector: matchLabels: app: my-rails-app strategy: type: Recreate template: metadata: labels: app: my-rails-app spec: initContainers: - name: init-when-postgres-ready image: jeffvalore/k8s-when-ready:v0.1.0 args: - --type=service - --name=postgres - name: init-when-rabbitmq-ready image: jeffvalore/k8s-when-ready:v0.1.0 args: - --type=service - --name=rabbitmq containers: - image: my-rails-app:1.2.3 name: my-rails-app ports: - containerPort: 80
Top answer
1 of 2
5

this may help (here I have added configmap, persistent volume, persistent volume-claim, and Postgres deployment yaml. This yaml will automatically create a table named users in the Postgres database inside the Postgres-container. Thanks

apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
  labels:
    app: postgres
data:
  Postgres_DB: postgresdb

---
apiVersion: v1
kind: Secret
metadata:
  name: postgres-secret
data:
  Postgres_User: postgresadmin
  Postgres_Password: admin123

---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: postgres-pv-volume
  labels:
    type: local
    app: postgres
spec:
  storageClassName: manual
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  hostPath:
    path: "/mnt/data"

---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: postgres-pv-claim
  labels:
    app: postgres
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres-container
          image: postgres:latest
          imagePullPolicy: "IfNotPresent"
          lifecycle:
            postStart:
              exec:
                command: ["/bin/sh","-c","sleep 20 && PGPASSWORD=$POSTGRES_PASSWORD psql -w -d $POSTGRES_DB -U $POSTGRES_USER -c 'CREATE TABLE IF NOT EXISTS users (userid SERIAL PRIMARY KEY,username TEXT,password TEXT,token TEXT,type TEXT);'"]
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_DB
              valueFrom:
                configMapKeyRef:
                  name: postgres-config
                  key: Postgres_DB
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: Postgres_User
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: Postgres_Password               
          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: postgredb
      volumes:
        - name: postgredb
          persistentVolumeClaim:
            claimName: postgres-pv-claim

If you find this helpful, please mark it as answer.

2 of 2
3

You have multiple way:

The official postgresql docker image state (the 'Initialization scripts' section):

If you would like to do additional initialization in an image derived from this one, add one or more *.sql, *.sql.gz, or *.sh scripts under /docker-entrypoint-initdb.d

Those scripts are only run if the database is created. eg if you start/restart a pod with a data volume containing an already existing database, those scripts will not be launched.

With kubernetes, you can provide a configmap with the needed file (if file sizes below 1Mb) or provide a volume with your initialization file.

An another option can be the application itself. For instance you may use flywayDB or liquibase embeded in your application (springboot do that transparently).

🌐
Medium
medium.com › @pandit.summit › kubernetes-helm-initdb-as-a-job-633f0d1261be
Kubernetes helm initdb as a Job. How to run the sql scripts in existing… | by Pandit Biradar | Medium
November 14, 2019 - FROM postgres:10.10-alpine RUN addgroup -S appgroup && adduser -S appuser -G appgroup RUN mkdir p ~/dbscripts COPY DB/ dbscripts RUN chown appuser dbscripts && chgrp appgroup dbscripts USER appuser CMD [“nc”, “-l”, “1234”] 3. create helm folder create under that create test-initdb-helm which contains 2 files
🌐
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.
🌐
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.

🌐
Percona
percona.com › home › bootstrap postgresql on kubernetes
Bootstrap PostgreSQL on Kubernetes
September 24, 2025 - Init SQL lets you create a database cluster with some initial data. Everything is created with the postgres admin user. The process works like this: Create the ConfigMap resource with the SQL script.
🌐
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.
🌐
GitHub
github.com › bitnami › charts › issues › 9048
initdb scripts are not running in Postgres container · Issue #9048 · bitnami/charts
February 16, 2022 - 00_init_extensions.sh: | #!/bin/sh export PGPASSWORD=$POSTGRES_POSTGRES_PASSWORD psql -U postgres -d gis -c "create extension if not exists postgis; create extension if not exists hstore;" ... kind: PersistentVolumeClaim apiVersion: v1 metadata: name: postgres-seed-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 2Gi storageClassName: gcp-ssd · The script is run and the postgis extension is enabled
Author   JesalR
🌐
Postgresql
postgresql.eu › events › fosdem2019 › sessions › session › 2321 › slides › 157 › Deploying_PostgreSQL_on_Kubernetes.pdf pdf
Deploying PostgreSQL on Kubernetes
March 2, 2019 - ●You want Postgres → Commodity to your users · ●By no means an exhaustive list of solutions or · in-depth analysis but an attempt to demystify · What this is not · I. A demo of me fiddling with terminals and window tiling · techniques on the screen · II. Me typing in Kubernetes commands so you can see how ·
🌐
GitHub
github.com › helm › charts › issues › 9619
initdbScripts is set but doesn't run · Issue #9619 · helm/charts
November 28, 2018 - I install my chart: helm install --name postgres -f helm/tools/postgres/values.yaml stable/postgresql · What you expected to happen: The script will run when i install my chart for the first time · How to reproduce it (as minimally and precisely as possible): add the same configuration as I did · Anything else we need to know: I can see the script I added in /docker-entrypoint-initdb.d/ in running container, the db is up and running but databases and other stuff from my init script are not created.
🌐
Reddit
reddit.com › r/kubernetes › strategy to run database scripts on kubernetes
r/kubernetes on Reddit: Strategy to run database scripts on Kubernetes
June 4, 2023 - Init containers are executed sequentially and can be used to perform setup tasks. This ensures that the scripts are executed before the application container starts. e) Environment Variables: Pass any necessary configuration or environment variables ...