DEV Community

Cover image for Postgres environment with docker-compose
Antonio Di Motta
Antonio Di Motta

Posted on

Postgres environment with docker-compose

Are you looking for a way to start a new development environment quickly? If this is the case this article could be useful for you.

Summarizing the Wikipedia definition, an environment is a set of resources able to run a software solution. Generally its possible to have many environments each of which has specific goal. For instance, development (dev), system integration test (sit), end to end test (e2e), user acceptance test (uat) and production (prod). All of these must be completely isolated each other, for example we should be sure that the front-end of sit is not able to connect to database of e2e. To do that, we have to design the network system and storage system to avoid any overlaps even if it happens accidentally and if we have many environments it can become a hard job.

Docker-compose is a great tool to start an environment creating all compute resources to run the solution but also the infrastructure resources like networking and storage ready to guarantee the isolation required. To prove this, I wrote a docker-compose yaml file which is able to start a solution based on:

Next, I parametrized the composer yaml with a .env properties file which contains some environment parameters:

ENV_NAME=<<environment-name>>
NGINX_RELEASE=1.21
NGINX_HOSTPORT=8081
POSTGRES_RELEASE=12
POSTGRES_USER=<<postgres-user>>
POSTGRES_PASSWORD=<<postgres-password>>
PGADMIN_RELEASE=latest
PGADMIN_EMAIL=<<pgadmin-user>>
PGADMIN_PASSWORD=<<pgadmin-password>>
Enter fullscreen mode Exit fullscreen mode

The most important of them is the first one ENV_NAME is used for identify the scope of networks, volumes and containers. Below an example of how to use it.

# Use postgres/example user/password credentials
version: '3.7'

services:
  proxy:
    image: nginx:${NGINX_RELEASE}
    container_name: ${ENV_NAME}_nginx
    restart: unless-stopped
    environment:
      NGINX_HOST: ${ENV_NAME}
      NGINX_PORT: ${NGINX_HOSTPORT}
    networks:
      - frontend
    volumes:
      - ./config/templates:/etc/nginx/templates
      - ./config/certs:/etc/nginx/certs
    ports:
      - ${NGINX_HOSTPORT}:${NGINX_HOSTPORT}
      - 443:443

  pgadmin:
    image: dpage/pgadmin4:${PGADMIN_RELEASE}
    container_name: ${ENV_NAME}_pgadmin
    depends_on:
      - postgres
    environment:
      PGADMIN_DEFAULT_EMAIL: ${PGADMIN_EMAIL}
      PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_PASSWORD}
    networks:
      - frontend
      - backend
    volumes:
      - pga_data:/var/lib/pgadmin

  postgres:
    image: postgres:${POSTGRES_RELEASE}
    container_name: ${ENV_NAME}_postgres
    restart: always
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - ps_data:/var/lib/postgresql/data
    networks:
      - backend     

volumes:
  ps_data:
    name: ${ENV_NAME}_postgres
  pga_data:
    name: ${ENV_NAME}_pgadmin

networks:
  frontend:
    name: ${ENV_NAME}_frontend
  backend:
    name: ${ENV_NAME}_backend
Enter fullscreen mode Exit fullscreen mode

For example if ENV_NAME is demo_dev we will have the following result:

Image description

As you can see the networks, the volumes and the containers names have been customized, so if we will start again the composer with different environments parameters, we will have a new environment isolated from the previous one.

The code is available on my github repository.

Top comments (0)