Specifying superuser PostgreSQL password for a Docker Container
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
The official PostgreSQL Docker image expects you to set the initial superuser password at container startup. If you do not configure it correctly, the container either refuses to start or comes up with an authentication setup that is unsafe for anything beyond temporary local testing.
The Standard Way: POSTGRES_PASSWORD
For the official image, the usual method is the POSTGRES_PASSWORD environment variable. It sets the password for the default postgres superuser during first-time database initialization.
This works only the first time the data directory is initialized. If the container already has a persistent volume with an existing cluster, changing the environment variable later does not automatically reset the database password.
Setting The Database Name And User At The Same Time
You can also initialize a custom database and application user alongside the superuser password.
In this case, POSTGRES_USER becomes the initial superuser-like account created by the image startup logic, and POSTGRES_PASSWORD sets its password. The default postgres role may still exist, but your application can connect as appuser.
Docker Compose Example
For local development, Docker Compose keeps the configuration readable.
Start it with:
Once the container is ready, verify the login:
Safer Secret Handling
Hard-coding passwords directly in shell history or compose files is acceptable only for disposable local environments. For anything more serious, use a secret file.
The PostgreSQL image supports POSTGRES_PASSWORD_FILE, which points to a file inside the container.
This avoids exposing the password in plain environment output. The container entrypoint reads the file and uses its contents during initialization.
Changing The Password After Initialization
If the container already created the database cluster, update the password from inside PostgreSQL rather than by editing the container definition.
This is an important operational detail. Many people restart a container with a new POSTGRES_PASSWORD value and expect it to apply automatically. It does not if the data directory already exists.
Initialization Scripts
If you need additional setup, place SQL or shell scripts in /docker-entrypoint-initdb.d/. They are executed only on first initialization.
That is useful when you want repeatable local environments without manually logging in after startup.
Common Pitfalls
The biggest mistake is forgetting that initialization variables apply only when PostgreSQL creates a new data directory. With a reused volume, environment changes do not retroactively update roles or passwords.
Another issue is storing secrets directly in source control. A compose file with a real production password is a preventable security failure. Use secret files, environment injection from a secure system, or an orchestrator-level secret mechanism.
It is also easy to confuse POSTGRES_USER with ordinary application-role creation later in a migration. The startup variables define the initial cluster state. They are not a substitute for proper database migration scripts.
Finally, avoid disabling authentication checks just to get a container running faster. If a password is required, set one explicitly and verify it with a real login test.
Summary
- Use
POSTGRES_PASSWORDto set the initial PostgreSQL superuser password in the official Docker image. - The environment variables only affect first-time initialization of the data directory.
- Use Docker Compose for readability and
POSTGRES_PASSWORD_FILEfor safer secret handling. - Change passwords later with
ALTER USER, not by expecting container variables to rewrite an existing cluster. - Treat database credentials as secrets, even in containerized development setups.
Related reading
- Spring Boot containers can not connect to the Kafka container
- Spring Boot in Docker
- Spring boot Unable to start embedded Tomcat servlet container
- standard_init_linux.go178 exec user process caused exec format error
- Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly
- Speed up fetching posts for my social network app by using query instead of observing a single event repeatedly
- Spring 3.0 - Unable to locate Spring NamespaceHandler for XML schema namespace http//www.springframework.org/schema/security
- Spring AMQP + RabbitMQ 3.3.5 ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.