You have to mount the SQL file as a volumen from a configmap and use the psql cli to execute the commands from mounted file.
To execute commands from file you can change the command parameter on the yaml by this:
psql -a -f sqlCommand.sql
The configmap needs to be created using the file you pretend to mount more info here
kubectl create configmap sqlCommands.sql --from-file=sqlCommands.sql
Then you have to add the configmap and the mount statement on your job yaml and modify the command to use the mounted file.
apiVersion: batch/v1
kind: Job
metadata:
name: init-db
spec:
template:
metadata:
name: init-db
labels:
app: init-postgresdb
spec:
containers:
- image: "docker.io/bitnami/postgresql:11.5.0-debian-9-r60"
name: init-db
command: [ "bin/sh", "-c", "psql -a -f /sqlCommand.sql" ]
volumeMounts:
- name: sqlCommand
mountPath: /sqlCommand.sql
env:
- name: DB_HOST
value: "knotted-iguana-postgresql"
- name: DB_DATABASE
value: "postgres"
volumes:
- name: sqlCommand
configMap:
# Provide the name of the ConfigMap containing the files you want
# to add to the container
name: sqlCommand.sql
restartPolicy: OnFailure
Answer from wolmi on Stack Overflowpostgresql - Create or update existing postgres db container through kubernetes job - Stack Overflow
initdb scripts are not running in Postgres container
postgresql - How to mount a sql file in a Init Container in order to bootstrap Postgres Database - Stack Overflow
Postgres init script
You have to mount the SQL file as a volumen from a configmap and use the psql cli to execute the commands from mounted file.
To execute commands from file you can change the command parameter on the yaml by this:
psql -a -f sqlCommand.sql
The configmap needs to be created using the file you pretend to mount more info here
kubectl create configmap sqlCommands.sql --from-file=sqlCommands.sql
Then you have to add the configmap and the mount statement on your job yaml and modify the command to use the mounted file.
apiVersion: batch/v1
kind: Job
metadata:
name: init-db
spec:
template:
metadata:
name: init-db
labels:
app: init-postgresdb
spec:
containers:
- image: "docker.io/bitnami/postgresql:11.5.0-debian-9-r60"
name: init-db
command: [ "bin/sh", "-c", "psql -a -f /sqlCommand.sql" ]
volumeMounts:
- name: sqlCommand
mountPath: /sqlCommand.sql
env:
- name: DB_HOST
value: "knotted-iguana-postgresql"
- name: DB_DATABASE
value: "postgres"
volumes:
- name: sqlCommand
configMap:
# Provide the name of the ConfigMap containing the files you want
# to add to the container
name: sqlCommand.sql
restartPolicy: OnFailure
You should make a docker file for the same first, execute it and map the same working docker image to the kubernetes job yaml file.
You can add an entrypoint.sh in docker file, where you can place your scripts to be executed
You will have to do the following:
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;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.sqlAnd 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.
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. - I ran
kubectl create configmap initsql --from-file=init.sqlto generate aconfigMapfile. I renamed the file something likepostgres-init.yaml. - I
kubectl apply -f postgres-init.yaml. - I have a standard-fare
postgres-deployment.yaml- basically copied from the official examples with a few modification. - In
volumes, I added:volumes: - ... - name: sql-init-mount configMap: name: initsql items: - key: init.sql path: init.sql - In the same
postgres-deployment.yamlI added to thepostgres containeritself:volumeMounts: - mountPath: /docker-entrypoint-initdb.d name: sql-init-mount - The official
postgresDocker image supports automatic initialization of any scripts dropped intodocker-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:
minikube dashboardthe deployedpostgres podcan be found and you can easilyexecin (if you're doing this locally) to verify the existing of the file (created corrected) and run:psql -U postgres -d postgresto login and query.
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.