Running PostgreSQL using Docker
Updated
TL;DR
Running PostgreSQL via Docker is one of the things you can do to quickly try postgresql without installing or configuring it locally. It's one of the benefits of using Docker. In this quick tutorial, you will get to know how you can run postgresql inside a docker container terminal using psql (a terminal interface to interact with postgresql databases).
Pulling Official PostgreSQL Image
Pull the official image of postgresql from Docker Hub using the docker pull command.
docker pull postgresYou can specify the version of postgresql to pull.
docker pull postgres:latest
docker pull postgres:16This will create a postgres image. You can verify that using the docker images command.
docker images
# output
REPOSITORY TAG IMAGE ID CREATED SIZE
postgres latest cff6b68a194a 5 weeks ago 432MBRunning the Image
Running the image means executing the image inside an isolated environment known as a container. It can be done using the docker run command.
docker run --name pgcontainer -e POSTGRES_PASSWORD=specify_your_password -d postgresLet's understand each flag/argument:
--name:- the name of the container to be created. (example:pgcontainer)-e:- environment variables to be fed into the container (here:POSTGRES_PASSWORD=specify_your_password).-d:- runs the container in a detached mode (in background) without blocking the terminal.- the last argument
postgresis the name of the image.
Run docker run --help for more information.
You can verify the container is running by using the docker ps command which will list all the running containers. A status of Up means the container is up and running.
docker ps
# Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ebeab2ca77e9 postgres "docker-entrypoint.s…" About an hour ago Up About an hour 5432/tcp pgcontainerExecuting Commands Inside Container
You can execute commands inside the container by accessing it's terminal shell using the docker exec command. The -it flag specifies the mode (interactive) in which you want to access the shell. It is meant to keep the input stream alive even if the container is in detached mode. The below command will spin up a psql instance which you can use to create and interact with databases.
docker exec -it pgcontainer psql -U postgresWhen you execute the above command, you can interact with the psql interface as shown below:
psql (16.3 (Debian 16.3-1.pgdg120+1))
Type "help" for help.
postgres=# |Connecting From Your Machine (Port Mapping)
If you look closely at the docker ps output above, the ports column says 5432/tcp instead of a mapped port like 0.0.0.0:5432->5432/tcp. That means the database port is exposed inside the container, but it is not reachable from your host machine. Any app running on your machine (a Node server, a GUI client, psql installed locally) will fail to connect.
To fix that, stop the container and run it again with the -p flag to map the container's port to a port on your machine:
docker run --name pgcontainer -e POSTGRES_PASSWORD=specify_your_password -p 5432:5432 -d postgresThe format is -p <host_port>:<container_port>. If you already have a local PostgreSQL running on 5432, map the container to a different port instead, for example -p 5433:5432, and connect to 5433 from your apps.
From your application, the connection string now looks like this:
postgresql://postgres:specify_your_password@localhost:5432/postgresPersisting Data With Volumes
A container's filesystem is ephemeral, remove the container and your databases are gone with it. To keep the data across container restarts and removals, mount a volume where PostgreSQL stores its data:
docker run --name pgcontainer -e POSTGRES_PASSWORD=specify_your_password -p 5432:5432 -v pgdata:/var/lib/postgresql/data -d postgresHere, pgdata is a named volume managed by Docker (list them with docker volume ls). Even if you docker rm the container, a new container mounting the same volume will find your data intact.
Using Docker Compose
Typing a long docker run command every time gets old, and real projects usually need more than one service running alongside the database. A compose.yml file solves both:
services:
db:
image: postgres:16
container_name: pgcontainer
environment:
POSTGRES_PASSWORD: specify_your_password
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:Then run docker compose up -d to start it, and docker compose down to stop it. The data lives in the pgdata volume, so down won't wipe your databases unless you pass the -v flag.
Conclusion
This is just one of the ways you can use postgres' image independently using docker. For more advanced and integrated usage of postgres along with multiple services, consider using docker compose.