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.
- System Requirements
- Project Structure
- Technologies Used
- PostgreSQL Configuration
- Docker Configuration
- Volume Management
- Network Configuration
- Environment Variables
- Resource Management
- Deployment and Start Instructions
- Troubleshooting
- License
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
.
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
- 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).
- 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 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.
The configuration of the PostgreSQL service is contained in the docker-compose.yml
file. Below is a breakdown of the configuration:
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
-
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
).
- The service runs PostgreSQL from the official Docker image (
-
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.
- A custom network (
-
Volumes:
- The
postgres_db
volume ensures data persistence. Even if the container is stopped or removed, the PostgreSQL data will remain intact.
- The
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 thelocal
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.
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 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.
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.
- Clone the repository (if applicable).
- Navigate to the project directory.
- 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
- 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.
-
Issue: PostgreSQL is not starting
Check the logs using:docker-compose logs db
Ensure that the
.env
file contains correct values, especially forPOSTGRES_USER
,POSTGRES_PASSWORD
, andPOSTGRES_DB
. -
Issue: Unable to connect to PostgreSQL
Ensure that port5432
is not blocked by a firewall or other security settings.
This project is licensed under the MIT License.