A process started by docker exec (docker exec) shares the suspect's filesystem, environment, network, DNS resolver and limits, so it sees exactly what the application sees. Question the hardened API from inside, then from the host:
A=l3-booknest-prod-api-1
docker exec $A sh -c 'id -un; env | grep ^PGPASS'
docker exec $A node -e \
'fetch("http://localhost:3000/ready").then(r => r.text()).then(console.log)'
docker exec $A touch /app/probe
sudo nsenter -t "$(docker inspect -f '{{.State.Pid}}' $A)" -n ss -tn | head -3node
PGPASSWORD_FILE=/run/secrets/db_password
{"status":"ready"}
touch: cannot touch '/app/probe': Read-only file system
State Recv-Q Send-Q Local Address:Port Peer Address:Port
ESTAB 0 0 172.19.0.3:48116 172.19.0.2:5432
ESTAB 0 0 172.19.0.3:48122 172.19.0.2:5432The password arrives as a secret file, not a variable; /ready proves the API reaches PostgreSQL 1,289 from where it runs; the read-only root filesystem of AppArmor and Read-Only FS holds. The last command needs no tool in the container at all: nsenter joins only the network namespace (-n) of the container's main process and runs the host's ss there, listing the API's pooled connections to PostgreSQL (-m, -p and -u enter the mount, PID and UTS namespaces). Never repair production by editing files in a container: the next deployment replaces it.