How to Run PostgreSQL with Docker: A Step-by-Step Guide

This tutorial shows how to quickly run PostgreSQL and the pgAdmin management tool in a Docker container using Docker Compose.

PostgreSQL is a free and open-source, object-relational database management system. It has been around for over 30 years and advertises itself as “the most advanced open-source relational database in the world.”

At the same time, Docker has become the IT industry standard for easy packaging, deploying, and running distributed applications. It provides an excellent opportunity to containerize your database and prevent system clutter with dependencies resulting from local package installation.

But before we move on, let’s answer a few essential questions.

Why Use PostgreSQL on Docker?

There are several reasons why using PostgreSQL on Docker can be advantageous:

  1. Portability: Docker provides a consistent environment for running PostgreSQL across different systems and platforms. This means you can ensure your application runs the same way regardless of the underlying infrastructure. In addition, it is easier to test and debug your apps in different environments and ensures that they will run consistently in production.
  2. Isolation: Docker containers provide an isolated environment for running PostgreSQL instances, so you can run multiple instances on the same host without worrying about conflicts or dependencies.
  3. Scalability: Docker makes deploying PostgreSQL instances on any platform easy and scaling them as needed. This allows for greater flexibility in managing database resources, as you can easily spin up new instances or adjust the number of containers running at any given time.

Why Use Docker Compose?

Docker Compose is a tool that allows you to run multi-container Docker applications. It is a command-line utility that simplifies the process of orchestrating Docker containers by using a YAML file to define an application’s services, networks, and volumes.

In other words, Docker Compose allows you to define all the services that make up your application in a single file and then use the docker-compose command to start, stop, and manage those services. This makes it easy to set up and manage complex applications that rely on multiple containers.

This is what we will do in this guide when we deploy in parallel PostgreSQL and pgAdmin – the most popular open-source administration and management tool for the PostgreSQL database. That will allow us to immediately start managing and administering our PostgreSQL instance without wasting time searching for additional tools to manage it.

Step 1: Install Docker Compose

Presumably, you already have Docker installed on your system. If you don’t, the following links will show you how to quickly and easily install it for the distribution you are using, such as Ubuntu, Debian, AlmaLinux, or Rocky Linux.

The other essential component is Docker Compose. Remember, it is provided separately from Docker. Therefore, you must Install Docker before adding Docker Compose; otherwise, Compose will not function.

Installing it is pretty simple, even if it is not already on your Linux system. Type the following commands:

sudo curl -L "https://github.com/docker/compose/releases/download/v2.16.0/docker-compose-linux-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-composeCode language: JavaScript (javascript)
Install Docker Compose.
Install Docker Compose.

At the time of writing, we were using Docker Compose 2.16.0. To check if there is a new one, follow this link and replace the “2.16.0” part in the first command above with the one you want.

Next, run the command below to ensure Docker Compose is installed and functioning correctly. You should receive a response similar to the one shown.

docker-compose version
Check the Docker Compose version.
Check the Docker Compose version.

Everything seems fine, so let’s get to the actual part.

Step 2: Create a Docker Compose File

As mentioned in the guide’s beginning, Docker Compose allows you to build and run stacks of multiple containers. To use it, you must first create a “docker-compose.yaml” file that configures the containers for your application. Then, you can use a single command such as “docker-compose up” to start all the containers and link them together.

So let’s create our master file describing the PostgreSQL and pgAdmin services for our containerized stack. First, we’ll create a directory with a name of our choice, for example, “pg,” then, with your preferred text editor, create a file named “docker-compose.yaml” inside it:

mkdir pg && cd pg
vim docker-compose.yamlCode language: CSS (css)

Then, add the following content to it:

version: "3.8"
services:
  postgres:
    image: postgres
    restart: always
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: mypgdbpass
    volumes:
      - postgres_data:/var/lib/postgresql/data
  pgadmin:
    image: dpage/pgadmin4
    restart: always
    ports:
      - "5050:80"
    environment:
      PGADMIN_DEFAULT_EMAIL: [email protected]
      PGADMIN_DEFAULT_PASSWORD: mypgadminpass
    volumes:
      - pgadmin_data:/var/lib/pgadmin
    depends_on:
      - postgres

volumes:
  postgres_data:
  pgadmin_data:Code language: JavaScript (javascript)

Save and close the file. Don’t be worried if something in its contents is unclear to you. Now I will explain it, so let’s break down this syntax.

  • services: Define the two services Docker needs to run, “postgres” and “pgadmin.”
  • image: Specifies the Docker Hub images that will be downloaded and used for our services. We don’t apply a tag for them since we want to use the most recent versions. However, if you need a specific one, you can look at the available for PostgreSQL and pgAdmin and use it, specifying it as, for example, “postgres:15.2-alpine.”
  • restart: Configure the Docker container always to restart if it stops unexpectedly.
  • ports: Map the TCP port on your host machine to the container port. This way, the containerized service is exposed outside the container and can be accessed remotely.
  • environment: Set environment variables for application authentication and setup. Be sure to change the values of the “POSTGRES_PASSWORD” environment for the PostgreSQL’s “postgres” admin user and pgAdmin (“PGADMIN_DEFAULT_EMAIL” and “PGADMIN_DEFAULT_PASSWORD“) to what you want.
  • volumes: Mount named Docker volumes for application files to persist your data. Otherwise, the data will be lost when the container restarts.
  • depends_on: Allows you to run services in order. In our case, the “pgadmin” service will not start until “postgres” is not up and running.

Step 3: Run PostgreSQL and pgAdmin as Docker Containers

Finally, we are ready to run PostgreSQL and pgAdmin using Docker Compose. To do this, execute the below-given command from the “pg” directory where your “docker-compose.yaml” file resides.

Deploy and run the containers in the background:

docker-compose up -d

The images will start downloading. The entire process can take a few minutes, depending on your internet connection speed. In the end, you should see a screen similar to the one below, informing you that all containers have been successfully created and started.

Run PostgreSQL and pgAdmin as Docker containers.
Run PostgreSQL and pgAdmin as Docker containers.

Of course, the delay before the actual start of the PostgreSQL and pgAdmin containers using Docker Compose will only be the first time because it is necessary to download the images from the Internet. All subsequent runs will take seconds since the Docker images are available locally on your Linux system.

Step 4: Connect pgAdmin to the PostgreSQL Container

Open your browser and point it to “http://localhost:5050” or “http://ip-address:5050” on the server where you ran the PostgreSQL and pgAdmin Docker containers.

The pgAdmin login page will greet you. Enter the username and password you specified as values for the “PGADMIN_DEFAULT_EMAIL” and “PGADMIN_DEFAULT_PASSWORD” variables in the “docker-compose.yaml” file.

pgAdmin 4 login page.
pgAdmin 4 login page.

Next, click on “Add New Server.”

Add a new server to pgAdmin.
Add a new server to pgAdmin.

A new modal window will open where you can configure the PostgreSQL server connection settings. First, enter your preferred connection name in the “Name” field.

Adding a new connection to the PostgreSQL server.
Adding a new connection to the PostgreSQL server.

Then select the “Connection” tab. In the “Host name/address” field, enter the name of the Docker’s PostgreSQL container’s service as defined in the “docker-compose.yaml” file. In our case, it is “postgres.” Finally, enter the password given as the value of “POSTGRES_PASSWORD” and save your changes by clicking the “Save” button.

Adding a new connection to the PostgreSQL server.
Adding a new connection to the PostgreSQL server.

The application will connect to the PostgreSQL Docker container, and you can monitor and administrate the database server using pgAdmin’s feature-rich web interface.

pgAdmin successfully connected to the Docker PostgreSQL container.
pgAdmin successfully connected to the Docker PostgreSQL container.

Alternatively, you can gain an interactive PostgreSQL shell by attaching it to the container and running the psql command to interact directly with the PostgreSQL database. To do this, you must first enter the container. However, you need to know its name. To find it, type:

docker ps
Finding the name of the Docker container.
Finding the name of the Docker container.

In the example shown, our PostgreSQL container is named “pg-postgres-1.” You can also use the container ID instead of a name, which in the example shown is “37c52cf79923.” To connect directly to it, we need to run the following:

docker exec -it pg-postgres-1 psql -U postgres

This provides the full PostgreSQL command-line interface to use all the familiar commands and flags.

Running psql commands inside the Docker container.
Running psql commands inside the Docker container.

Finally, let me walk you through the essential Docker Compose commands for managing your containerized PostgreSQL/pgAdmin stack.

Essential Docker Compose Commands

The essential Docker Compose commands you can use in practice are shown below with examples. Remember to execute them from the “pg” directory, where the “docker-compose.yaml” resides.

List All Docker Containers

To view a list of all the containers that are currently running in your deployment, type:

docker-compose ps
List all Docker containers.
List all Docker containers.

Stop All Docker Containers

To stop all docker containers that are running in the background, use the command as shown below:

docker-compose stop
Stop all Docker containers.
Stop all Docker containers.

Of course, you can stop only one of the containers, not all of them. Run “docker-compose stop” followed by the service name defined in the “docker-compose.yaml” file. Notice not the container name but the service name.

For example, to stop the PostgreSQL container, defined with the “postgres” service name, type the following:

docker-compose stop postgres
Stop a single container.
Stop a single container.

Similarly, you can start it again later by executing “docker-compose start postgres.”

Start All Docker Containers

From your project directory (“pg“), start up your application by running the command as shown below:

docker-compose start
Start all Docker containers.
Start all Docker containers.

View the Containers’ Logs

The “docker-compose logs” command displays log output from services. For example, run the command followed by the service name to view the PostgreSQL container logs.

docker-compose logs postgres

Additionally, if you want to aggregate the logs of every container in your stack and track what’s happening in them in real-time, type:

docker-compose logs -f

Stop and Remove All Containers

The following command stops and removes containers and networks created previously by the “docker-compose up” command:

docker-compose down
Stop and destroy containers.
Stop and destroy containers.

Additionally, if you want to stop and remove containers alongside their associated Docker images, use the following command:

docker-compose down --rmi all
Stop and remove containers alongside with the Docker images.
Stop and remove containers alongside their Docker images.

If, in addition to stopping and removing the containers, you want the permanently stored data in the Docker volumes to be also deleted, perform the following:

docker-compose down -v
Stop and remove containers along with their persistent data.
Stop and remove containers along with their persistent data.

Attention! Note that you will lose all data this way. In this case, the entire contents of the PostgreSQL database (“pgadmin_data” volume). So, think twice before you execute this command.

Conclusion

Docker has revolutionized the way developers deploy and manage applications. One of the most significant use cases using it is the ease of deploying and accessing applications built within containers without worrying about dependencies and installations. With its ability to provide a consistent environment and simplify the deployment process, Docker has become a go-to solution for developers and system administrators.

This tutorial showed you how to quickly run PostgreSQL and the pgAdmin management tool in a Docker container using Docker Compose. Following the step-by-step instructions outlined in this guide, you can have your PostgreSQL and pgAdmin environments up and running in minutes.

Let me know if you have any questions or suggestions in the comments below, and I’ll be happy to follow up with you.

Bobby Borisov

Bobby Borisov

Bobby, an editor-in-chief at Linuxiac, is a Linux professional with over 20 years of experience. With a strong focus on Linux and open-source software, he has worked as a Senior Linux System Administrator, Software Developer, and DevOps Engineer for small and large multinational companies.

Think You're an Ubuntu Expert? Let's Find Out!

Put your knowledge to the test in our lightning-fast Ubuntu quiz!
Ten questions to challenge yourself to see if you're a Linux legend or just a penguin in the making.

1 / 10

Ubuntu is an ancient African word that means:

2 / 10

Who is the Ubuntu's founder?

3 / 10

What year was the first official Ubuntu release?

4 / 10

What does the Ubuntu logo symbolize?

5 / 10

What package format does Ubuntu use for installing software?

6 / 10

When are Ubuntu's LTS versions released?

7 / 10

What is Unity?

8 / 10

What are Ubuntu versions named after?

9 / 10

What's Ubuntu Core?

10 / 10

Which Ubuntu version is Snap introduced?

The average score is 68%