How to Deploy PostgreSQL with Docker and Docker Compose
Tags: devops, postgres, sql
Published: 2023-11-15 08:57:49

In this article you will learn how to deploy [PostgreSQL](https://www.postgresql.org/) with [Docker](https://docs.docker.com/get-started/overview/) and [Docker Compose](https://docs.docker.com/compose/). Postgres is a free, open source and advanced database management system that supports both SQL(relational) and JSON(non-relational) querying. Docker on the other hand is an open platform used for developing, shipping and running applications as containers. Docker applications can be run on any platform once the image has been build.

## Table of Contents
[Prerequisites](#prerequisites)
[Deploying PostgreSQL with Docker](#deploying-postgresql-with-docker)
[Deploying PostgreSQL with Docker Compose](#deploying-postgresql-with-docker-compose)
[Conclusion](#conclusion)
### Prerequisites
Before delving further into this article the following requirements will be beneficial to have:
1. Basic knowledge of docker and its commands.
2. Familiarity with docker compose will come in handy.
3. An Understanding of how relational databases like 
   PostgreSQL work.

### Deploying PostgreSQL with Docker
The first approach you are going to use in deploying Postgres is searching the Postgres image from docker hub. You will then launch a Postgres container from the image pulled from [docker hub](https://hub.docker.com/_/postgres).
Begin by searching the Postgres image from the Docker Registry with the following command at the terminal.
```
docker search postgres
```
The output of the displayed available Postgres images from Docker hub should be similar to the one below.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pt1zfiwjcazsuhpd5ywm.png)

Having done the above you can go ahead to pull the latest PostgreSQL image with the following command.

```
docker pull postgres:latest
```
An output similar to the following pulling the latest Postgres image from the Docker hub will be observed.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45knhfmuew7oxbfcizpn.png)

You can verify the downloaded image with the following command
```
docker images
```
Now it's time to run your container from the downloaded Postgres image. To run the container execute the following command.

```
docker run --name postgres-container -e POSTGRES_USER=root -e POSTGRES_PASSWORD=secret -p 5432:5432 -d postgres 
```
Let's go through the above command that is used to create your container.
- You start by stating the name of the container which is postgres-container from the --name tag.
- The Postgres user will be root from the environment variable `POSTGRES_USER` and password will be secret from the environment variable `POSTGRES_PASSWORD`.
- Next you create a port mapping by binding the host network followed by a colon and then the corresponding container network with the -p tag. The port value 5432 used here is the same for both our host and container network but a different port number can still be used for both host and container network.
- Finally you state Postgres as the name of the image which will use the latest image tag pulled from the docker hub.
You can go ahead to press enter and Docker will start the Postgres container returning a long unique ID. To view all running containers use the `docker ps` command. The output of the above steps will be displayed as below.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e8ojv4hgg1qnxdghexk4.png)
 
The Postgres server is now ready to accept incoming connections. To execute it, use the `docker exec` command.

```
docker exec -it postgres-container psql -U root
```
The above command instructions are explained below:
- The -it flag instructs docker to run the command as an interactive TTY session. Afterward, you specify the name of the container which is `postgres-container`.
- You can now run psql command to access the Postgres console. Use the `-U` flag to tell `psql` that you want to connect as root user.
- And just like that you are inside the Postgres server and you can now create a database, table or do any administrative task required of Postgres server. A display similar to the following will be shown.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eyw26i5cvaiayh5fcudz.png)

To exit from the Postgres server just type \q in the shell inside the Postgres server as shown below.

```
root=# \q
```
With that, you have seen how to use Postgres with docker in the terminal. In the next section let's see how to deploy Postgres with an even better approach that is neater which is docker compose. 

### Deploying PostgreSQL with Docker Compose
To deploy Postgres with docker compose you will have to write a docker compose yaml file. All the steps will be in a single `YAML` file making it neat and clear to follow the steps of pulling the Postgres image and running it as a container.
To create the `yaml` file just type the following at the terminal in a folder of your choice to create the docker compose yaml file.

Create a folder where your `yaml` file will reside. At the terminal type the following

```
mkdir ~/docker-compose-pg && cd ~/docker-compose-pg
```
You can then create your docker-compose file as shown below.

```
touch docker-compose-pg.yaml
```
After creating the docker-compose-pg.yaml file, type the following in the file.

```
version: "3.8"
services:
  postgres:
    image: postgres:14-alpine
    restart: always
    environment:
      - POSTGRES_USER=root
      - POSTGRES_PASSWORD=secret
    ports:
      - "5432:5432"
    volumes:
     - db:/var/lib/postgresql/data
volumes:
  db: 
```
The created docker compose file has the following contents:
1. It uses the docker-compose file of [version 3.8](https://docs.docker.com/compose/compose-file/compose-file-v3/#service-configuration-reference)
2. Next you create a service named Postgres. A service is analogous to `docker run` when you want to run a container from an image.
3. The docker-compose file will use the postgres:14-alpine image from docker hub and will restart automatically if the container stops.
4. The next step is to define the environment variables. In your case, you define the Postgres user and password to be used when executing the Postgres database. To learn more about environment variables you can refer to [docker-compose environment guide](https://docs.docker.com/compose/environment-variables/set-environment-variables/)
5. The next step is to map the host port 5432 to the container port 5432 as Postgres will run in that port in the container.
6. The last part of your docker-compose is to manage the [volume](https://docs.docker.com/compose/compose-file/compose-file-v3/#volumes) which is named db. Volumes help in persisting the data during the lifetime of the container or should the container restart. To show volumes attached to your Postgres container just type `docker volume ls` and `docker volume inspect` to get the volume information.
You are now ready to start your Postgres container. Type the following command on the terminal.

```
docker-compose -f docker-compose-pg.yaml up -d
```
This command will start the Postgres container in the background and leave it running. Since your file has a different name from the default (docker-compose.yaml) file you will need to use the `-f` flag and then specify the name of your docker compose file which is docker-compose-pg.yaml.
The output will be similar to the following after running the command.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4y5l5zltcv9ey77a4o28.png)

To confirm that our container is running use the command below.
```
docker ps
```
The output should show you the name of the container as below which is postgresyaml-postgres-1. One thing to note is if you don't state the `container_name` inside the docker compose file, after the creation of the container, docker compose will assign the container name with the name of the location where your docker compose file is. In your case since the docker compose file `docker-compose-pg.yaml` lies in folder `postgresyaml` then the container name will contain the name of the folder combined with the service name and `1` appended to the name at the end. The name of the container will become `postgresyaml-postgres-1`.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ts4hlg6zy8p9frod0f26.png)

Now it's time to execute your container in the terminal and use the Postgres server. The docker command to use is shown below.

```
docker exec -it postgresyaml-postgres-1 psql -U root
```
And voila you are inside the Postgres server. You can type the following `SQL` commands in `psql` terminal to see the current timestamp and date. For the current timestamp type `select now();` and for the date `select current_date;`. The display will be as follows.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pyfn4fnup6mjeckxf0ex.png)

The setup is now complete and you can exit the Postgres server by using the `q` command.

### Conclusion
In this post, you learned how to deploy Postgres with docker and docker-compose. You first began by pulling the Postgres image from the docker hub. From the pulled image you deployed the Postgres container. A similar process was done with docker compose but in a cleaner approach which put all the container configurations in a yaml file. You can now deploy Postgres with both docker and docker compose.