Postgres environment with docker-compose
Tags: docker, postgres, devops
Published: 2022-07-08 21:08:15

---
title: Postgres environment with docker-compose
published: true
description: The article shows how to create a new isolated environment quickly.
tags: docker,postgres,devops
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9ko8j1ozax6sqi2u8tl.JPG
# Use a ratio of 100:42 for best results.
---

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](https://docs.docker.com/compose/) yaml file which is able to start a solution based on:
- [Postgres](https://www.postgresql.org/), as database server
- [Pgadmin](https://www.pgadmin.org/), as postgres management tool
- [NGinx](https://www.nginx.com/), as reverse proxy

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

```env
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>>
```

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.

```yaml
# 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
```
For example if ENV_NAME is **demo_dev** we will have the following result:

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

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](https://github.com/antdimot/devops/tree/main/docker/postgres) repository.