<p>I used the following yaml to create a postgres deployment in my kubernetes cluser.</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: database-secret
  namespace: todo-app
data:
  # todoappdb
  db_name: dG9kb2FwcGRiCg==
  # todo_db_user
  username: dG9kb19kYl91c2VyCg==
  # password
  password: cGFzc3dvcmQK
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: database
  namespace: todo-app
  labels:
    app: database
spec:
  replicas: 1
  selector:
    matchLabels:
      app: database
  template:
    metadata:
      labels:
        app: database
    spec:
      containers:
        - name: database
          image: postgres:11
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: database-secret
                  key: password
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: database-secret
                  key: username
            - name: POSTGRES_DB
              valueFrom:
                secretKeyRef:
                  name: database-secret
                  key: db_name
---
apiVersion: v1
kind: Service
metadata:
  name: database
  namespace: todo-app
  labels:
    app: database
spec:
  type: NodePort
  selector:
    app: database
  ports:
    - port: 5432
</code></pre>
<p>When I try to run psql in the pod itself using the following command.</p>
<pre class="lang-sh prettyprint-override"><code>kubectl exec -it database-5764d75d58-msf7h  -n todo-app -- psql -U todo_db_user -d todoappdb
</code></pre>
<p>I get the following error.</p>
<pre class="lang-sh prettyprint-override"><code>psql: FATAL:  role &quot;todo_db_user&quot; does not exist
</code></pre>
<p>Here are the logs of the pod.</p>
<pre><code>The files belonging to this database system will be owned by user &quot;postgres&quot;.
This user must also own the server process.

The database cluster will be initialized with locale &quot;en_US.utf8&quot;.
The default database encoding has accordingly been set to &quot;UTF8&quot;.
The default text search configuration will be set to &quot;english&quot;.

Data page checksums are disabled.

fixing permissions on existing directory /var/lib/postgresql/data/pgdata ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default timezone ... Etc/UTC
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok

Success. You can now start the database server using:

    pg_ctl -D /var/lib/postgresql/data/pgdata -l logfile start


WARNING: enabling &quot;trust&quot; authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
waiting for server to start....2022-01-15 12:46:26.009 UTC [49] LOG:  listening on Unix socket &quot;/var/run/postgresql/.s.PGSQL.5432&quot;
2022-01-15 12:46:26.015 UTC [50] LOG:  database system was shut down at 2022-01-15 12:46:25 UTC
2022-01-15 12:46:26.017 UTC [49] LOG:  database system is ready to accept connections
 done
server started
CREATE DATABASE


/usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*

waiting for server to shut down...2022-01-15 12:46:26.369 UTC [49] LOG:  received fast shutdown request
.2022-01-15 12:46:26.369 UTC [49] LOG:  aborting any active transactions
2022-01-15 12:46:26.370 UTC [49] LOG:  background worker &quot;logical replication launcher&quot; (PID 56) exited with exit code 1
2022-01-15 12:46:26.371 UTC [51] LOG:  shutting down
2022-01-15 12:46:26.376 UTC [49] LOG:  database system is shut down
 done
server stopped

PostgreSQL init process complete; ready for start up.

2022-01-15 12:46:26.482 UTC [1] LOG:  listening on IPv4 address &quot;0.0.0.0&quot;, port 5432
2022-01-15 12:46:26.482 UTC [1] LOG:  listening on IPv6 address &quot;::&quot;, port 5432
2022-01-15 12:46:26.483 UTC [1] LOG:  listening on Unix socket &quot;/var/run/postgresql/.s.PGSQL.5432&quot;
2022-01-15 12:46:26.489 UTC [77] LOG:  database system was shut down at 2022-01-15 12:46:26 UTC
2022-01-15 12:46:26.492 UTC [1] LOG:  database system is ready to accept connections
</code></pre>
<p>Is there something wrong with the config?</p>
<p>When I don't use POSTGRES_USER env var, it works using role <code>postgres</code>. Also, with the current config I tried to use psql with the <code>postgres</code> role but that doesn't work either.</p>

<p>You have an error in your <code>Secret</code>. If you base64-decode these values:</p>
<pre><code>data:
  # todoappdb
  db_name: dG9kb2FwcGRiCg==
  # todo_db_user
  username: dG9kb19kYl91c2VyCg==
  # password
  password: cGFzc3dvcmQK
</code></pre>
<p>You will find that they all include a terminal <code>\n</code> character:</p>
<pre><code>$ kubectl get secret database-secret -o json &gt; secret.json
$ jq '.data.username|@base64d' secret.json
&quot;todo_db_user\n&quot;
$ jq '.data.password|@base64d' secret.json
&quot;password\n&quot;
$ jq '.data.db_name|@base64d' secret.json
&quot;todoappdb\n&quot;
</code></pre>
<p>I suspect this is because you generate the values by running something
like:</p>
<pre><code>$ echo password | base64
</code></pre>
<p>But of course, the <code>echo</code> command emits a trailing newline (<code>\n</code>).</p>
<p>There are two ways of solving this:</p>
<ol>
<li><p>Use <code>stringData</code> instead of <code>data</code> in your <code>Secret</code> so you can just
write the unencoded values:</p>
<pre><code>apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: database-secret
stringData:
  db_name: todoappdb
  username: todo_db_user
  password: password
</code></pre>
</li>
<li><p>Instruct <code>echo</code> to not emit a trailing newline:</p>
<pre><code>$ echo -n todo_db_user | base64
</code></pre>
<p>(Or use something like <code>printf</code> which doesn't emit a newline by
default).</p>
</li>
</ol>
<p>I would opt for the first option (using <code>stringData</code>) because it's much simpler.</p>
