Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save farunurisonmez/ae191fa94721009f8c474b43a339dba6 to your computer and use it in GitHub Desktop.
Save farunurisonmez/ae191fa94721009f8c474b43a339dba6 to your computer and use it in GitHub Desktop.
Docker Compose Configuration for PostgreSQL 17 on Ubuntu 24.04.1 with Static IP and Custom Settings
services:
db:
container_name: postgres
image: postgres:latest
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
ports:
- "5432:5432" # Expose port to the outside
volumes:
- postgres_db:/var/lib/postgresql/data
networks:
postgres_network:
ipv4_address: 172.18.0.3 # Static IP address is assigned here
command: >
postgres -c max_connections=${PG_MAX_CONNECTIONS}
-c shared_buffers=${PG_SHARED_BUFFERS}
-c work_mem=${PG_WORK_MEM}
-c maintenance_work_mem=${PG_MAINTENANCE_WORK_MEM}
-c effective_cache_size=${PG_EFFECTIVE_CACHE_SIZE}
-c random_page_cost=${PG_RANDOM_PAGE_COST}
-c wal_level=${PG_WAL_LEVEL}
-c statement_timeout=${PG_STATEMENT_TIMEOUT}
-c idle_in_transaction_session_timeout=${PG_IDLE_TRANSACTION_TIMEOUT}
-c lock_timeout=${PG_LOCK_TIMEOUT}
-c wal_writer_delay=${PG_WAL_WRITER_DELAY}
-c checkpoint_timeout=${PG_CHECKPOINT_TIMEOUT} -c wal_buffers=${PG_WAL_BUFFERS}
# Sets the maximum number of connections (PG_MAX_CONNECTIONS)
# Shared memory size (PG_SHARED_BUFFERS)
# Memory allocated per query (PG_WORK_MEM)
# Maximum memory used for maintenance operations (PG_MAINTENANCE_WORK_MEM)
# Estimated amount of data PostgreSQL can cache (PG_EFFECTIVE_CACHE_SIZE)
# Sets the random page access cost (PG_RANDOM_PAGE_COST)
# Write-Ahead Logging (WAL) level (PG_WAL_LEVEL)
# Timeout for queries (PG_STATEMENT_TIMEOUT)
# Timeout for idle transactions (PG_IDLE_TRANSACTION_TIMEOUT)
# Timeout for locked transactions (PG_LOCK_TIMEOUT)
# Write-ahead logging delay (PG_WAL_WRITER_DELAY)
# ${PG_CHECKPOINT_TIMEOUT}: Sets the checkpoint frequency (PG_CHECKPOINT_TIMEOUT)
# ${PG_WAL_BUFFERS}: WAL buffer size (PG_WAL_BUFFERS)
deploy:
resources:
limits:
# CPU limit (1.5 CPU cores are limited)
cpus: "1.5"
# Memory limit (8GB of RAM is available)
memory: 8GB
# Resources available beyond the limits
reservations:
# If resources are available, reserve this amount
cpus: "1" # 1 CPU core will be reserved
memory: 4GB
volumes:
postgres_db:
driver: local # A local volume is created using the local driver to store the container data.
# The 'postgres_db' volume is used to persist PostgreSQL database data.
# This volume ensures that the data is retained even if the container is stopped or removed.
# The 'local' driver stores the data on the host machine. This ensures that database data is preserved even when the Docker container is removed.
networks:
postgres_network:
driver: bridge
ipam:
config:
- subnet: "172.18.0.0/16" # Subnet configuration for the network

Dockerized PostgreSQL 17 Service on Ubuntu 24.04.1 (AMD64)

Overview

This document outlines the configuration and deployment process of a Dockerized PostgreSQL database service using Docker Compose, optimized for use on Ubuntu 24.04.1. The setup ensures high availability, persistent data storage, and efficient resource management, while adhering to best practices for containerized services in production environments.

Table of Contents

  1. System Requirements
  2. Project Structure
  3. Technologies Used
  4. PostgreSQL Configuration
  5. Docker Configuration
  6. Volume Management
  7. Network Configuration
  8. Environment Variables
  9. Resource Management
  10. Deployment and Start Instructions
  11. Troubleshooting
  12. License

System Requirements

Before setting up the Dockerized PostgreSQL service, ensure that the following requirements are met:

  • Docker: Version 20.10 or higher
  • Docker Compose: Version 1.27.0 or higher
  • Ubuntu 24.04.1: Ensure your system is up to date by running sudo apt-get update && sudo apt-get upgrade.

Project Structure

This project leverages Docker Compose to manage a PostgreSQL service along with essential configuration files. The structure is as follows:

.
├── docker-compose.yml          # Main Docker Compose configuration file
├── .env                        # Environment variables file
└── data/                       # (Optional) Directory for persistent volume storage

Key Components

  • docker-compose.yml: The primary configuration file that defines services, volumes, and networks. It ensures that PostgreSQL runs within a Docker container and interacts with the host machine or other services.
  • .env: A file containing sensitive environment variables such as database credentials.
  • data/: Directory for storing PostgreSQL data if not using Docker volumes (optional).

Technologies Used

  • Docker: A platform for developing, shipping, and running applications in containers. Docker ensures that PostgreSQL runs consistently across environments.
  • PostgreSQL: A powerful, open-source relational database management system (RDBMS). It handles structured data storage and management.
  • Docker Compose: A tool for defining and managing multi-container Docker applications. It simplifies the orchestration of multiple services with one configuration file.

PostgreSQL Configuration

PostgreSQL is configured with a set of optimizations to enhance performance and resource management. Key configurations include:

  • max_connections: Defines the maximum number of database connections allowed.
  • shared_buffers: Defines the amount of memory the database server uses for shared memory buffers.
  • work_mem: Defines the memory allocated for internal operations like sorting and hash tables.
  • effective_cache_size: Defines the effective size of the disk cache.
  • wal_level: Defines the level of Write-Ahead Logging for PostgreSQL’s durability.

These settings are customizable based on the project’s requirements and expected workload.


Docker Configuration

The configuration of the PostgreSQL service is contained in the docker-compose.yml file. Below is a breakdown of the configuration:

docker-compose.yml Example

version: "3.8"

services:
  db:
    container_name: postgres
    image: postgres:latest
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    ports:
      - "5432:5432"  # Exposing PostgreSQL port for external access
    volumes:
      - postgres_db:/var/lib/postgresql/data  # Persistent storage for PostgreSQL data
    networks:
      postgres_network:
        ipv4_address: 172.18.0.3  # Static IP for consistent service access
    command: >
      postgres -c max_connections=${PG_MAX_CONNECTIONS}
               -c shared_buffers=${PG_SHARED_BUFFERS}
               -c work_mem=${PG_WORK_MEM}
               -c maintenance_work_mem=${PG_MAINTENANCE_WORK_MEM}
               -c effective_cache_size=${PG_EFFECTIVE_CACHE_SIZE}
               -c random_page_cost=${PG_RANDOM_PAGE_COST}
               -c wal_level=${PG_WAL_LEVEL}
               -c statement_timeout=${PG_STATEMENT_TIMEOUT}
               -c idle_in_transaction_session_timeout=${PG_IDLE_TRANSACTION_TIMEOUT}
               -c lock_timeout=${PG_LOCK_TIMEOUT}
               -c wal_writer_delay=${PG_WAL_WRITER_DELAY}
               -c checkpoint_timeout=${PG_CHECKPOINT_TIMEOUT}
               -c wal_buffers=${PG_WAL_BUFFERS}

volumes:
  postgres_db:
    driver: local  # Persist PostgreSQL data on the host machine

networks:
  postgres_network:
    driver: bridge
    ipam:
      config:
        - subnet: "172.18.0.0/16"  # Custom network with static subnet

Explanation of Key Sections:

  • PostgreSQL Service (db):

    • The service runs PostgreSQL from the official Docker image (postgres:latest).
    • Environment variables are used to configure the PostgreSQL instance (username, password, and database name).
    • Port 5432 is exposed for external access, enabling applications to connect to the PostgreSQL service.
    • Persistent data storage is achieved using Docker volumes (postgres_db).
  • Networks:

    • A custom network (postgres_network) is defined, allowing for easy communication between services.
    • Static IP addresses are assigned to containers, ensuring consistency in networking.
  • Volumes:

    • The postgres_db volume ensures data persistence. Even if the container is stopped or removed, the PostgreSQL data will remain intact.

Volume Management

Docker volumes provide a persistent storage mechanism, which is critical for databases. By using the volume postgres_db, database data is stored outside the container, ensuring that it remains persistent across container restarts and removals.

Volume Configuration:

  • postgres_db is created using the local driver, ensuring the data is stored on the host system’s file system.
  • Data is mounted to /var/lib/postgresql/data, the default data directory for PostgreSQL in the container.

This approach ensures the PostgreSQL data persists, providing a stable and reliable database solution for production environments.


Network Configuration

The custom Docker network postgres_network ensures that services can securely and efficiently communicate with each other within isolated environments.

  • Driver: The bridge driver is used for network isolation. This ensures that the PostgreSQL service runs in its own network segment, isolated from the host and other external services.
  • IPAM Configuration: The subnet 172.18.0.0/16 is specified, allowing for static IP addressing within the network, providing consistent network access.

Environment Variables

Environment variables are critical for securely managing configuration values. The following variables are used to configure the PostgreSQL instance:

  • POSTGRES_USER: The PostgreSQL superuser.
  • POSTGRES_PASSWORD: The password for the PostgreSQL user.
  • POSTGRES_DB: The default database created upon initialization.

Optional Environment Variables:

  • PG_MAX_CONNECTIONS: Maximum allowed database connections.
  • PG_SHARED_BUFFERS: The amount of memory allocated to shared buffers.
  • PG_WORK_MEM: Memory used for internal operations like sorting.
  • PG_EFFECTIVE_CACHE_SIZE: Defines the amount of memory the operating system uses for caching.

These variables are typically defined in the .env file to keep them secure and outside the version-controlled codebase.


Resource Management

To ensure optimal performance in a production environment, resource limits are set for the PostgreSQL container. This includes both CPU and memory usage:

deploy:
  resources:
    limits:
      cpus: "1.5"  # Limit to 1.5 CPU cores
      memory: 8GB   # Limit memory usage to 8GB
    reservations:
      cpus: "1"     # Reserve 1 CPU core
      memory: 4GB   # Reserve 4GB of memory

These limits prevent the container from over-consuming host resources and allow for better resource allocation across multiple services.


Deployment and Start Instructions

  1. Clone the repository (if applicable).
  2. Navigate to the project directory.
  3. Create a .env file with the necessary environment variables:
    POSTGRES_USER=myuser
    POSTGRES_PASSWORD=mypassword
    POSTGRES_DB=mydatabase
    PG_MAX_CONNECTIONS=200
    PG_SHARED_BUFFERS=256MB
    PG_WORK_MEM=64MB
  4. Start the services using Docker Compose:
    docker-compose up -d

This will pull the necessary Docker images, create the containers, and start the PostgreSQL service.


Troubleshooting

  • Issue: PostgreSQL is not starting
    Check the logs using:

    docker-compose logs db

    Ensure that the .env file contains correct values, especially for POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB.

  • Issue: Unable to connect to PostgreSQL
    Ensure that port 5432 is not blocked by a firewall or other security settings.


License

This project is licensed under the MIT License.

POSTGRES_USER=testuser
POSTGRES_PASSWORD=testpassword
POSTGRES_DB=test_db
PG_MAX_CONNECTIONS=4000
PG_SHARED_BUFFERS=2GB
PG_WORK_MEM=128MB
PG_MAINTENANCE_WORK_MEM=512MB
PG_EFFECTIVE_CACHE_SIZE=4GB
PG_RANDOM_PAGE_COST=1.1
PG_WAL_LEVEL=logical
PG_STATEMENT_TIMEOUT=0
PG_IDLE_TRANSACTION_TIMEOUT=0
PG_LOCK_TIMEOUT=0
PG_WAL_WRITER_DELAY=300ms
PG_CHECKPOINT_TIMEOUT=30min
PG_WAL_BUFFERS=16MB
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment