How to Run PostgreSQL Using Docker | by Mahbub Zaman | Towards Data Science

PostgreSQL has been around for over 30 years. It was first developed in 1986 as part of the POSTGRES project at the University of California at Berkeley. Now it is the world’s most advanced open-source relational database. Running PostgreSQL on different machines can be challenging, but Docker makes it easier. From this post, you’ll learn how to run PostgreSQL inside a Docker container.
As a programmer or data scientist, you have to work with databases at some point in your career. Since Docker has become a popular DevOps tool in recent years, you may have to use PostgreSQL with Docker. Before we dive into the setup, read the post below if you want to know some basics of Docker.
towardsdatascience.com
First, we need to install Docker. We will use a Docker compose file, a SQL dump file containing bootstrap data, and macOS in this setup. You can download these two files separately. Just make sure to put both docker-compose.yml and infile in the same folder. Alternatively, you can get the repository from here. Now, let’s discuss docker-compose and SQL dump files briefly.
Docker Compose: It’s a YAML file, and we can define containers and their properties inside. These containers are called services. For example, if your application has multiple stacks, such as a web server and a database server, we can use a docker-compose file.
SQL-dump: A sql-dump contains SQL queries in plain text. PostgreSQL provides the command-line utility program pg_dump to create and read dump files.
Let’s break down the individual ingredients of the docker-compose.yml file.
version: '3.8'services:db:    container_name: pg_container    image: postgres    restart: always    environment:      POSTGRES_USER: root      POSTGRES_PASSWORD: root      POSTGRES_DB: test_db    ports:      - "5432:5432"    volumes:      - $HOME/Desktop/PostgreSql-Snippets/infile:/infile      - pg_data:/var/lib/postgresql/data/volumes:  pg_data:
The first line defines the version of the Compose file, which is 3.8. There are other file formats — 1, 2, 2.x, and 3.x. Get more information on Compose file formats from Docker’s documentation here.
After that, we have the services hash, and it contains the services for an application. For our application, we only have one service called db.
Inside the db service, the first tag container_name is used to change the default container name to pg_container for our convenience. The second tag image is used to define the Docker image for the db service, and we are using the pre-built official image of PostgreSQL.
For the third tag restart, we have set the value always. What it does is it always automatically restarts the container by saving time. It restarts the container when either the Docker daemon restarts or the container itself is manually restarted. For example, every time you reboot your machine, you don’t have to manually start the container.
The fourth tag environment defines a set of environment variables. Later we will use these for database authentication purposes. Here we have POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB. Among these three variables, the only required one is the POSTGRES_PASSWORD. The default value of POSTGRES_USER is postgres, and for POSTGRES_DB it’s the value of POSTGRES_USER. You can read more about these variables from here.
The fifth tag is the ports tag and is used to define both host and container ports. It maps port 5432 on the host to port 5432 on the container.
Finally, the volumes tag is used to mount a folder from the host machine to the container. It comprises two fields separated by a colon, the first part is the path in the host machine and the second part is the path in the container. Remove this portion if you don’t want to mount the sql-dump into the container. The second line of volumes tag is used to store the database data, the first part is the name of the volume, and the second part is the path in the container where the database data is stored. But how do we know what’s that path exactly? We can determine the path by running the following command using the psql. We will discuss how to use psql later in this post.
show data_directory;
Remove the second line if you don’t want to back up your container’s database data. If you choose to remove both lines under the volumes tag, remove the volumes tag.
At the end of the docker-compose file, you can see that we have defined the volume pg_data under the volumes tag. It allows us to reuse the volume across multiple services. Read more about volumes tag here.
The moment of truth. Let’s run the following command from the same directory where the docker-compose.yml file is located. We can see that it starts and runs our entire app.
docker compose up
We can check if the container is running or not using the docker ps command on the host machine. As we can see, we have a running container called pg_container.
Moreover, we can see the image by running the docker images command.
Finally, we can see that a volume has been created by running the docker volume ls command.
What is psql? It’s a terminal-based interface to PostgreSQL, which allows us to run SQL queries interactively. First, let’s access our running container pg_container.
docker exec -it pg_container bash
I talked about how the above line works in the following article. Have a look.
towardsdatascience.com
Now we can connect to psql server using the hostname, database name, username, and password.
psql --host=pg_container --dbname=test_db --username=root
If you want to type less, use the following command. Find more options for PostgreSQL interactive terminal from here.
psql -h pg_container -d test_db -U root
Here, the password’s value is the root, which has been defined inside the docker-compose file earlier.
Now we can load the dump file into our test_db database. In this case, infile. It is accessible inside the container because we have mounted it from the host machine.
psql -h pg_container -d test_db -U root -f infile
If we run the PostgreSQL command \dt, we can see two tables called marks and students inside our database test_db.
Did we miss something? Not really, but yes! Since our data is backed up in the volume called postgresql-snippets_pg_data, we can remove the container without losing the database data. Let’s try that now. First, delete the container and then create it again.
docker rm pg_containerdocker compose up
Now after accessing the container and psql we can still see our data!
docker exec -it pg_container bashpsql -h pg_container -d test_db -U root\dt
In case you want to delete the backup volume, use the docker volume rm command. Read the documentation here.
docker volume rm postgresql-snippets_pg_data
Or you can use the docker-compose command. Read the documentation here.
docker-compose down --volumes
Great job! Now you know how to run a PostgreSQL database using Docker. Docker is one of the fascinating technology I came across. Not only it saves time, but it also helps you run an application on any machine. If you find this post helpful, check out the post below where I’ve talked about how to run MySQL and phpMyAdmin using Docker.