How to Run PostgreSQL Using Docker
By: Mahbub Zaman
Tags: Programming, Software Engineering, Postgresql, Data Science, Docker

Setup

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.

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

Inspection

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 .

docker ps

Moreover, we can see the image by running the docker images command.

docker images

Finally, we can see that a volume has been created by running the docker volume ls command.

docker volume ls

Connect to psql

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.

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.

Load data from a file

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_container

docker-compose up

Now after accessing the container and psql we can still see our data!

docker exec -it pg_container bash

psql -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.