env vars in postgres deployment not working

12/5/2019

First off, I'm pretty sure I know why this isn't working: I'm pulling the Docker postgres:11-alpine image, modifying it, but then trying to change the env: in the k8s deployment.yaml on a custom image. I think that is the issue.

Basically, I'm trying to accomplish this per the Docker postgres docs:

docker run --name some-postgres -e POSTGRES_PASSWORD='foo' POSTGRES_USER='bar'

This is what I have:

Dockerfile.dev

FROM postgres:11-alpine
EXPOSE 5432
COPY ./db/*.sql /docker-entrypoint-initdb.d/

postgres.yaml (secrets will be moved after I'm done playing with this)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: postgres
  template:
    metadata:
      labels:
        component: postgres
    spec:
      containers:
        - name: postgres
          image: testproject/postgres
          ports:
            - containerPort: 5432
          env: 
            - name: POSTGRES_DB
              value: "test_dev"
            - name: POSTGRES_USER
              value: "bar"
            - name: POSTGRES_PASSWORD
              value: "foo"
          volumeMounts:
            - name: postgres-storage
              mountPath: /var/lib/postgresql/data
              subPath: postgres
      volumes:
        - name: postgres-storage
          persistentVolumeClaim:
            claimName: postgres-storage
---
apiVersion: v1
kind: Service
metadata:
  name: postgres-cluster-ip-service
spec:
  type: ClusterIP
  selector:
    component: postgres
  ports:
    - port: 5432
      targetPort: 5432

When I use Skaffold to spin the cluster up locally, however, the env: "don't take" as I can still access the DB using the defaults POSTGRES_USER=postgres and POSTGRES_PASSWORD=''.

I bet if I did image: postgres then the env: would work, but then I'm not sure how to do the equivalent of this that is in the Dockerfile:

COPY ./db/*.sql /docker-entrypoint-initdb.d/

Any suggestions?

Here is the skaffold.yaml if that is helpful too:

apiVersion: skaffold/v1beta15
kind: Config
build:
  local:
    push: false
  artifacts:
    - image: testproject/postgres
      docker:
        dockerfile: ./db/Dockerfile.dev
      sync:
        manual:
          - src: "***/*.sql"
            dest: .
    - image: testproject/server
      docker:
        dockerfile: ./server/Dockerfile.dev
      sync:
        manual:
          - src: "***/*.py"
            dest: .
deploy:
  kubectl:
    manifests:
      - k8s/ingress.yaml 
      - k8s/postgres.yaml
      - k8s/server.yaml
-- eox.dev
docker
kubernetes
skaffold

1 Answer

12/5/2019

The Docker postgres docs mention the following:

Warning: the Docker specific variables will only have an effect if you start the container with a data directory that is empty; any pre-existing database will be left untouched on container startup.

Are you sure that you're starting your deployment with an empty data directory? Could it be that PostgreSQL starts and allows you to login using the credentials that were specified in the environment variables during the first time your started it with that persistent volume?

If that's not it, have a look at the environment variables of the running pod. kubectl describe POD should tell you which environment variables are actually passed through to the pod. Maybe something in your Skaffold setup overwrites the environment variables? You could have a look in the pod by running env when execing into the pod. Also don't forget the logs, the PostgreSQL container should log which user account it creates during startup.

-- Niels Slot
Source: StackOverflow