How to Run Postgresql 14/15 with Docker and Docker-Compose

In this guide we are going to explore how to run Postresql 14 locally with docker and docker compose. This can be helpful if you want to run Postgresql locally without installing it in your server or if you want to run multiple versions of Postgresql seamlessly.

Also check:

Prerequisites

To follow along, ensure you have the following:

  • Docker installed locally and permissions to use it to launch containers
  • Docker compose is installed locally
  • Basic knowledge of the command line

Using the docker run command

We are going to use the docker run command to achieve our goal. The version of postgres that we want is postgres:14-alpine - a minimal version of Postgres container.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ docker run -d \
        --name my-postgres \
        -p 5432:5432 \
        -v ~/apps/postgres:/var/lib/postgresql/data \
        -e POSTGRES_PASSWORD=S3cret \
        -e POSTGRES_USER=citizix_user \
        -e POSTGRES_DB=citizix_db \
         postgres:14-alpine

Unable to find image 'postgres:14-alpine' locally
14-alpine: Pulling from library/postgres
a0d0a0d46f8b: Pull complete
5034a66b99e6: Pull complete
82e9eb77798b: Pull complete
c6b2245b2f36: Pull complete
ccd761727716: Pull complete
3da258773353: Pull complete
2c7ee7bc69e8: Pull complete
c3db0bb7841b: Pull complete
Digest: sha256:3908426c31b425eceee65541c320ed5e9ad921ea4f30eebff8f9129062bebd28
Status: Downloaded newer image for postgres:14-alpine
ba2fcc0b78a98c3949693c1868215ed0551413726f0f74c14af1659412ddbe9e

In the above command:

  • The -d instructs docker container to run as a detached process. It run container in background and print container ID
  • -p is for port mapping. We are instructing the container to expose the container port externally. Container port 5432 is mapped to host port 5432. That means the service can be accessed through localhost:5432
  • The -v directive is used to mount volumes. In our case we are mounting the container volume /var/lib/postgresql/data to host path ~/apps/postgres. Containers are ephemeral devices that will contain its data for the time it is running. Once a container is stopped, its data is lost. Mounting volumes ensures that the data is added to a host path that can be reused when the container is restarted.
  • The -e argument is for the environment variables. The supplied environment variables will be used to set up a Postgres user, password and a database.

To check that our container is running as expected, use the docker ps command:

1
2
3
4
$ docker ps

CONTAINER ID   IMAGE                COMMAND                  CREATED          STATUS          PORTS                                       NAMES
ba2fcc0b78a9   postgres:14-alpine   "docker-entrypoint.s..."   43 seconds ago   Up 40 seconds   0.0.0.0:5432->5432/tcp, :::5432->5432/tcp   my-postgres

In my case the container is running as my-postgres the name we gave it. We can login to the container using the docker exec command while executing /bin/bash interactively. Here we are also logging in to posgtres with the credentials we specified above and checking the version.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ docker exec -it my-postgres /bin/bash
bash-5.1# psql -U citizix_user -d citizix_db;
psql (14.0)
Type "help" for help.

citizix_db=# select version();
                                                   version
--------------------------------------------------------------------------------------------------------------
 PostgreSQL 14.0 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20210424) 10.3.1 20210424, 64-bit
(1 row)

citizix_db=#

If you need to clean up the container when not in use, you can stop and remove the container using this command:

1
2
3
4
docker stop my-postgres

# Removing
docker rm my-postgres

Using the docker-compose tool

We can achieve the same functionality with docker-compose. Docker Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your applicationā€™s services.

Docker Compose allows you to define the service (Postgres in our case) with properties like the image to use, ports to expose, volumes to mount and environment variables.

Here is how we would use docker-compose to achieve the functionality above. Save this as docker-compose.yaml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
version: '3.9'

services:
  postgres:
    image: postgres:14-alpine
    ports:
      - 5432:5432
    volumes:
      - ~/apps/postgres:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=S3cret
      - POSTGRES_USER=citizix_user
      - POSTGRES_DB=citizix_db

Now bring up the containers:

1
2
3
4
$ docker-compose up -d

Creating network "pg_default" with the default driver
Creating pg_postgres_1 ... done

The commands:

  • up brings up the container
  • -d in a detached mode

Verify the container processes using the ps command:

1
2
3
4
$ docker-compose ps
    Name                   Command              State                    Ports
------------------------------------------------------------------------------------------------
pg_postgres_1   docker-entrypoint.sh postgres   Up      0.0.0.0:5432->5432/tcp,:::5432->5432/tcp

To login to the container and login to postgres, use this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
$ docker-compose exec postgres /bin/bash

bash-5.1# psql -U citizix_user -d citizix_db;
psql (14.0)
Type "help" for help.

citizix_db=# select version();
                                                   version
--------------------------------------------------------------------------------------------------------------
 PostgreSQL 14.0 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20210424) 10.3.1 20210424, 64-bit
(1 row)

citizix_db=#

Conclusion

In this guide we managed to run Postgres 14 as a container in our system, we explored using the docker run command while passing the required arguments an alternative approach of simplifying the process with docker-compose

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy