Docker Compose: Postgres & pgAdmin in single stack

Docker Compose: Postgres & pgAdmin in single stack

About

There are situations were you need to have your own development purposes PostgresSQL.

That's not an tricky thing to spin own pgsql instance, because you don't even need to use docker compose. Single container from pulled image would be sufficient.

But what if we would want to have our own stack with pgAdmin altogether with Postgres instance?

With docker-compose it's quite easy... Let's go!

First things, first

The first thing is to create a directory for our initial files:

cd repos

mkdir postgres && touch docker-compose.yml

code docker-compose.yml

While editing our future compose file, we define compose version.

About versioning there is so much written, that I will not care about (if you want to know more: Google is your friend...).

First we define our version:

version: '3.7'

Basics

Then, we define our stack name, right above services:

name: postgres-server
services:
  postgres-server:
    container_name: postgres-server
    hostname: postgresql
    image: postgres:latest

Then we create service, name it and add, container_name all together with host name and base image.

Next, we would like to persist our data, initialize default user, database, setup port forwarding etc:

    volumes:
      - 'postgres-server-master_data:/var/lib/postgresql/data'
    environment:
      - POSTGRES_PASSWORD=${DATABASE_PASSWORD:-postgres}
      - POSTGRES_USER=${DATABASE_USER:-postgres}
      - POSTGRES_DB=${DATABASE_DEFAULT:-postgres}
    networks:
      - services
    ports:
      - 5432:5432
    restart: always

Section called networks: is needed for future to stack up two services into same network, as you imagine in order to make them visible for each other.

As you can see, I use the trick with default ENV's, were if .env file is not given, docker compose will use default passwords.

Volume & network

Then we map volume:

volumes:
  postgres-server-master_data:
    driver: local
    name: postgres-server-master_data

And define network:

networks:
  services:
    name: ${DATABASE_NETWORK:-postgres-server}

pgAdmin

But that's not the end, because we are still missing the pgAdmin.

First, we need to create folder which we will use to store pgAdmin data:

mkdir pgadmin_data && sudo chown -R 5050:5050 pgadmin_data

Then we need to add another 'few things' to our compose-file:

  pgadmin:
    container_name: postgres-pgadmin
    hostname: postgres-pgadmin
    image: dpage/pgadmin4
    environment:
      - PGADMIN_DEFAULT_EMAIL=${PGADMIN_DEFAULT_EMAIL:-admin@admin.com}
      - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_DEFAULT_PASSWORD:-admin}
    networks:
      - services
    volumes:
      - ./pgadmin_data:/var/lib/pgadmin
    ports:
      - "5050:80"
    restart: on-failure
    depends_on:
      - postgres-server

Important is section depends-on which points our postgres service and will stop 'deployment' of second container if first fails during its startup.

As you can see, both services have host names with appropriate names in order to distinguish them easily inside our stack.

Least, the last, we map data into volume:

  pgadmin_data:
    driver: local
    name: pgadmin_data

Deployment

Start-up:

docker compose up -d

Stopping

To stop or start just type:

docker compose stop

# or
docker compose start

Removal of container

docker compose down

Cleaning

In order to delete volumes and stop containers, use:

docker compose down -v && sudo rm -r pgadmin_data

pgAdmin

Stack contains pgAdmin for server/cluster management through website.

Web version of pgAdmin is accessible via address: http://localhost:5050.

If everything is okay, we should see something like this:

image.png

Logging in

Defaults (if ENV is not given) are:

  • /admin for pgAdmin
  • postgres@postgres/postgres for database

Yaml

Final docker-compose.yml should look like this:

version: '3.7'

name: postgres-server
services:
  postgres-server:
    container_name: postgres-server
    hostname: postgresql
    image: postgres:latest
    volumes:
      - 'postgres-server-master_data:/var/lib/postgresql/data'
    environment:
      - POSTGRES_PASSWORD=${DATABASE_PASSWORD:-postgres}
      - POSTGRES_USER=${DATABASE_USER:-postgres}
      - POSTGRES_DB=${DATABASE_DEFAULT:-postgres}
    networks:
      - services
    ports:
      - 5432:5432
    restart: always

  pgadmin:
    container_name: postgres-pgadmin
    hostname: postgres-pgadmin
    image: dpage/pgadmin4
    environment:
      - PGADMIN_DEFAULT_EMAIL=${PGADMIN_DEFAULT_EMAIL:-admin@admin.com}
      - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_DEFAULT_PASSWORD:-admin}
    networks:
      - services
    volumes:
      - ./pgadmin_data:/var/lib/pgadmin
    ports:
      - "5050:80"
    restart: on-failure
    depends_on:
      - postgres-server

volumes:
  postgres-server-master_data:
    driver: local
    name: postgres-server-master_data
  pgadmin_data:
    driver: local
    name: pgadmin_data

networks:
  services:
    name: ${DATABASE_NETWORK:-postgres-server}

Note

The default host name for our Postgres is set to: postgresql.