Description
Name and Version
bitnami/pgbouncer:1.23.1
What architecture are you using?
amd64
What steps will reproduce the bug?
When running the Bitnami PGBouncer Docker image on AWS ECS Fargate, configuring PGBouncer to use a Unix domain socket via PGBOUNCER_SOCKET_DIR
(e.g., /var/run/pgbouncer
) results in a "Permission denied" error when PGBouncer attempts to bind the socket.
This occurs because:
- The ECS task definition mounts a volume (e.g., an ECS-managed empty volume) at the specified
PGBOUNCER_SOCKET_DIR
. - In Fargate, such volumes are typically mounted with
root
ownership. - The PGBouncer container is started with
user: "0"
(root) to allow the entrypoint to perform initial setup. - The Bitnami
entrypoint.sh
script runs, and eventually,/opt/bitnami/scripts/pgbouncer/run.sh
attempts to start the PGBouncer daemon. Thisrun.sh
script drops privileges and runs the daemon as thepgbouncer
user (or the user specified byPGBOUNCER_DAEMON_USER
). - The non-root
pgbouncer
user does not have write permission to the root-ownedPGBOUNCER_SOCKET_DIR
, leading to thebind(): Permission denied
error.
What is the expected behavior?
Ideally the setup.sh
or entrypoint.sh
script, when run as root, would correctly prepare the PGBOUNCER_SOCKET_DIR
by changing its ownership to PGBOUNCER_DAEMON_USER:PGBOUNCER_DAEMON_GROUP
if PGBOUNCER_SOCKET_DIR
is configured.
What do you see instead?
The PGBouncer logs show:
<timestamp> UTC [1] WARNING cannot listen on unix:/var/run/pgbouncer/.s.PGSQL.6432: bind(): Permission denied
<timestamp> UTC [1] FATAL failed to create unix socket
Additional information
As a workaround, I've overridden the PGBouncer container's command in the ECS task definition. This ensures that the socket directory's ownership and permissions are corrected after PGBouncer's own setup.sh
runs but before the run.sh
script (and thus the PGBouncer daemon) attempts to use it.
The PGBouncer container definition in our AWS CDK (TypeScript) looks like this:
// Relevant part of ECS Task Definition for PGBouncer container
// pgbouncerSocketPath = "/var/run/pgbouncer";
// ...
user: "0", // Run the container's initial process (entrypoint) as root
command: [
"sh",
"-c",
// 1. Run PGBouncer's standard setup script
"/opt/bitnami/scripts/pgbouncer/setup.sh && " +
// 2. Fix ownership and permissions for the socket directory
`chown pgbouncer:pgbouncer ${pgbouncerSocketPath} && ` +
`chmod 0700 ${pgbouncerSocketPath} && ` + // Changed from 0755 to 0700 for stricter socket dir permissions
// 3. Execute the original run script to start PGBouncer daemon
"exec /opt/bitnami/scripts/pgbouncer/run.sh"
],
environment: {
PGBOUNCER_SOCKET_DIR: pgbouncerSocketPath,
PGBOUNCER_DAEMON_USER: "pgbouncer", // Explicitly set, though it's the default
PGBOUNCER_DAEMON_GROUP: "pgbouncer", // Explicitly set, though it's the default
// ... other PGBouncer environment variables ...
},
// ... volume mounts for pgbouncerSocketPath, etc. ...