Happy Machine
Happy Machine

Reputation: 1163

Running postgres command in pod definition doesnt work

I'm just adding the containers part of the spec. Everything is otherwise set up and working fine and values are hardcoded here. This is a simple Postgres pod that is part of a single replica deployment with its own PVC to persist state. But the problem is having nothing to do with my pod/deployment setup.

containers:
    - name: postgres-container
      image: postgres
      imagePullPolicy: Always
      volumeMounts:
        - name: postgres-internal-volume
          mountPath: /var/lib/postgresql/data
          subPath: postgres
      envFrom:
        - configMapRef:
            name: postgres-internal-cnf
      ports:
        - containerPort: 5432
      command: ['psql']
      args: [-U postgres -tc "SELECT 1 FROM pg_database WHERE datname = 'dominion'" | grep -q 1 || psql -h localhost -p 5432 -U postgres -c "CREATE DATABASE dominion"]

This command will create a database if it does not already exist. If I create the deployment and exec into the pod and run this command everything works fine. If I however run it here the pod fails to spin up and I get this error:

psql: error: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?

I was under the impression that this error comes from the default connection values being incorrect, but here I am hardcoding the localhost and the port number.

Upvotes: 1

Views: 1182

Answers (1)

larsks
larsks

Reputation: 311606

With your pod spec, you've replaced the default command -- which starts up the postgres server -- with your own command, so the server never starts. The proper way to perform initialization tasks with the official Postgres image is in the documentation.

You want to move your initialization commands into a ConfigMap, and then mount the scripts into /docker-entrypoint-initdb.d as described in those docs.

The docs have more details, but here's a short example. We want to run CREATE DATABASE dominion when the postgres server starts (and only if it is starting with an empty data directory). We can define a simple SQL script in a ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-init-scripts
data:
  create-dominion-db.sql: |
    CREATE DATABASE dominion

And then mount that script into the appropriate location in the pod spec:

volumes:
  - name: postgres-init-scripts
    configMap:
      name: postgres-init-scripts
containers:
  - name: postgres-container
    image: postgres
    imagePullPolicy: Always
    volumeMounts:
      - name: postgres-internal-volume
        mountPath: /var/lib/postgresql/data
        subPath: postgres
      - name: postgres-init-scripts
        mountPath:
        /docker-entrypoint-initdb.d/create-dominion-db.sql
        subPath: create-dominion-db.sql
    envFrom:
      - configMapRef:
          name: postgres-internal-cnf
    ports:
      - containerPort: 5432

Upvotes: 2

Related Questions