Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
7318b3a
Initial PostgreSQL guide structure
igor-alexandrov Dec 12, 2025
0a9ffb0
dhi: postgresql, part 2 and 4 , final drafts
Dec 31, 2025
9238c68
Added two first sections to the first part of the PostgreSQL guide.
igor-alexandrov Jan 5, 2026
0942ec7
Added the Named Volumes section
igor-alexandrov Jan 5, 2026
c92e89e
Added the "Bind Mounts" section
igor-alexandrov Jan 5, 2026
46d3879
Added the Compose section
igor-alexandrov Jan 5, 2026
7df793d
Updated the first section based on comments from Edith Puclla
igor-alexandrov Jan 14, 2026
7ca2716
Update PostgreSQL Modules 2 and 4 with feedback fixes
Jan 22, 2026
dcd11dc
Added DHI examples
igor-alexandrov Feb 3, 2026
bc3e9c8
Added more DHI examples
igor-alexandrov Feb 3, 2026
3468d44
Adding Networking and Connectivity part
edithturn Feb 3, 2026
b8a6385
Fix the reference links
edithturn Feb 4, 2026
85114f5
Adding description and fixing level of doc tittle
edithturn Feb 4, 2026
8fe9952
Fixing bash format for code snippeds
edithturn Feb 4, 2026
d680956
Remove content form the static resource
edithturn Feb 5, 2026
e42a58b
Fixing minor error in the doc spellings
edithturn Feb 5, 2026
2a3ae04
Fixing validate check for grammar
edithturn Feb 5, 2026
f705491
Change postgresql version from 17 to 18
edithturn Feb 25, 2026
4225f8c
Update content/guides/postgresql/_index.md
edithturn Mar 2, 2026
443a06a
Update content/guides/postgresql/_index.md
edithturn Mar 2, 2026
db69c02
Update content/guides/postgresql/_index.md
edithturn Mar 2, 2026
a958f1a
Update content/guides/postgresql/_index.md
edithturn Mar 2, 2026
6b247e4
Update content/guides/postgresql/_index.md
edithturn Mar 2, 2026
740f2d5
Update content/guides/postgresql/companions-for-postgresql.md
edithturn Mar 2, 2026
c9f20c7
Update content/guides/postgresql/companions-for-postgresql.md
edithturn Mar 2, 2026
b5526d4
Update content/guides/postgresql/companions-for-postgresql.md
edithturn Mar 2, 2026
69393f9
Update content/guides/postgresql/companions-for-postgresql.md
edithturn Mar 2, 2026
5ee696d
Update content/guides/postgresql/companions-for-postgresql.md
edithturn Mar 2, 2026
a725f71
Update content/guides/postgresql/companions-for-postgresql.md
edithturn Mar 2, 2026
6aff1eb
Update content/guides/postgresql/advanced-configuration-and-initializ…
igor-alexandrov Mar 2, 2026
d89eae6
Update content/guides/postgresql/advanced-configuration-and-initializ…
igor-alexandrov Mar 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions content/guides/postgresql/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: PostgreSQL specific guide
linkTitle: PostgreSQL
description: Containerize PostgreSQL databases using Docker
keywords: Docker, getting started, postgresql, language
summary: |
This guide explains how to containerize PostgreSQL databases using
Docker.
toc_min: 1
toc_max: 2
tags: [databases]
params:
time: 20 minutes
---

222 changes: 222 additions & 0 deletions content/guides/postgresql/advanced-configuration-and-initialization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
---
title: Advanced Configuration and Initialization
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
title: Advanced Configuration and Initialization
title: Advanced configuration and initialization

linkTitle: Advanced Configuration and Initialization
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not needed if same as title.

Suggested change
linkTitle: Advanced Configuration and Initialization

weight: 20
description: Configure PostgreSQL initialization scripts, tune performance parameters, and set timezone and locale settings for containerized deployments.
keywords:
- PostgreSQL Docker
- Docker Compose PostgreSQL
- container database
- PostgreSQL performance tuning
---

With persistent storage configured in the previous section, you're ready to customize PostgreSQL for real-world use. This guide covers advanced configuration techniques for running PostgreSQL in Docker containers, including automated database initialization, performance tuning, and timezone configuration.

## Overview

While PostgreSQL containers can be started quickly with default settings, production environments require customized configurations. This guide explains how to:

- Automate database, schema, and user creation during container startup
- Tune PostgreSQL performance parameters for containerized workloads
- Configure timezone and locale settings

## Initialization scripts

The official PostgreSQL Docker image supports running initialization scripts automatically when the container starts for the first time. Any files placed in the `/docker-entrypoint-initdb.d/` directory are executed in alphabetical order.

### How initialization works

When the container starts, it checks whether the PostgreSQL data directory is empty. If the directory already contains data, PostgreSQL starts immediately without running any initialization. If the directory is empty, the container runs `initdb` to create a new database cluster, then executes all scripts in `/docker-entrypoint-initdb.d/` in alphabetical order before starting PostgreSQL.

### Supported file formats

| Format | Description |
|--------|-------------|
| `.sql` | SQL commands executed directly |
| `.sql.gz` | Gzip-compressed SQL files |
| `.sh` | Shell scripts executed with bash |

> **Important:** Initialization scripts only run when the PostgreSQL data directory is empty. If you mount a volume containing existing data, initialization is skipped. This behavior prevents overwriting existing databases.

## Mounting initialization scripts

Use Docker Compose to mount initialization scripts into the container. First, create a project directory:

```console
$ mkdir -p postgres-project/init-db
$ cd postgres-project
```

Create a `compose.yaml` file:

```yaml
services:
db:
image: postgres:18
volumes:
- ./init-db:/docker-entrypoint-initdb.d
- postgres_data:/var/lib/postgresql
environment:
POSTGRES_PASSWORD: mysecretpassword

volumes:
postgres_data:
```

All scripts in the `./init-db` directory execute when the container starts for the first time. This is great for bootstrapping databases.

## Initialization script example

Create a file named `init.sql` in your `init-db` directory:

```sql
CREATE TABLE users (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(100) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```

This script runs automatically when the container starts for the first time, creating your initial database schema.

> **Note:** Ensure initialization scripts have proper read permissions. If you encounter "Permission denied" errors, run `chmod 644 init-db/*.sql` to make the files readable by the container.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> **Note:** Ensure initialization scripts have proper read permissions. If you encounter "Permission denied" errors, run `chmod 644 init-db/*.sql` to make the files readable by the container.
> [!NOTE]
>
> Ensure initialization scripts have proper read permissions. If you encounter "Permission denied" errors, run `chmod 644 init-db/*.sql` to make the files readable by the container.


## Performance tuning

Default PostgreSQL settings are conservative to work on systems with limited resources. For production workloads, you should tune these parameters based on your container's allocated resources.

### Method 1: Custom configuration file

For complete control, mount a custom `postgresql.conf` file. First, extract the default configuration:

```console
$ docker run -i --rm postgres:18 cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf
```

Edit `my-postgres.conf` with your desired settings, then mount it in your Compose file:

```yaml
services:
db:
image: postgres:18
volumes:
- ./my-postgres.conf:/etc/postgresql/postgresql.conf
- ./init-db:/docker-entrypoint-initdb.d
- postgres_data:/var/lib/postgresql
command: postgres -c config_file=/etc/postgresql/postgresql.conf
environment:
POSTGRES_PASSWORD: mysecretpassword

volumes:
postgres_data:
```

## Key configuration parameters

The following tables list important `postgresql.conf` parameters for containerized PostgreSQL deployments.

### Connection settings

| Parameter | Description | Default |
|-----------|-------------|---------|
| `listen_addresses` | IP addresses to listen on | `localhost` |
| `port` | TCP port number | `5432` |
| `max_connections` | Maximum concurrent connections | `100` |

### Memory settings

| Parameter | Description | Recommended starting value |
|-----------|-------------|---------------------------|
| `shared_buffers` | Shared memory for caching | 25% of container memory |
| `work_mem` | Memory per query operation | 4MB - 64MB |
| `maintenance_work_mem` | Memory for VACUUM, CREATE INDEX | 64MB - 256MB |
| `effective_cache_size` | Planner's cache size estimate | 50-75% of container memory |

> **Docker memory limits:** When tuning memory parameters, set explicit memory limits on your container using `deploy.resources.limits.memory` in Compose or `--memory` with `docker run`. Without limits, PostgreSQL sees the host's total RAM and may allocate more than intended. For example, if your container should use 4GB maximum, set `shared_buffers` to approximately 1GB (25%).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> **Docker memory limits:** When tuning memory parameters, set explicit memory limits on your container using `deploy.resources.limits.memory` in Compose or `--memory` with `docker run`. Without limits, PostgreSQL sees the host's total RAM and may allocate more than intended. For example, if your container should use 4GB maximum, set `shared_buffers` to approximately 1GB (25%).
#### Docker memory limits
When tuning memory parameters, set explicit memory limits on your container using `deploy.resources.limits.memory` in Compose or `--memory` with `docker run`. Without limits, PostgreSQL sees the host's total RAM and may allocate more than intended. For example, if your container should use 4GB maximum, set `shared_buffers` to approximately 1GB (25%).


### I/O settings

| Parameter | Description | Recommended starting value |
|-----------|-------------|---------------------------|
| `effective_io_concurrency` | Concurrent disk I/O operations | `200` for SSDs, `2` for HDDs |

### Timeout settings

| Parameter | Description | Default |
|-----------|-------------|---------|
| `statement_timeout` | Max time for any statement | `0` (disabled) |
| `lock_timeout` | Max time to wait for a lock | `0` (disabled) |
| `deadlock_timeout` | Time before checking for deadlock | `1s` |
| `transaction_timeout` | Max time for a transaction | `0` (disabled) |

> **Note:** Setting `shared_buffers` too high in a container can exceed kernel shared memory limits. Use no more than 25-30% of the container's memory limit.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
> **Note:** Setting `shared_buffers` too high in a container can exceed kernel shared memory limits. Use no more than 25-30% of the container's memory limit.
> [!NOTE]
>
> Setting `shared_buffers` too high in a container can exceed kernel shared memory limits. Use no more than 25-30% of the container's memory limit.


## Timezone and locale configuration

Proper localization ensures timestamps and sorting behave correctly for your application's users.

```yaml
services:
db:
image: postgres:18
volumes:
- postgres_data:/var/lib/postgresql
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
environment:
POSTGRES_PASSWORD: mysecretpassword
TZ: America/New_York

volumes:
postgres_data:
```

Alternatively, set the timezone using a PostgreSQL command-line parameter:

```yaml
services:
db:
image: postgres:18
command: ["postgres", "-c", "timezone=America/New_York"]
environment:
POSTGRES_PASSWORD: mysecretpassword
```

### Setting the locale

Specify locale settings during database initialization using the `POSTGRES_INITDB_ARGS` environment variable:

```yaml
services:
db:
image: postgres:18
volumes:
- postgres_data:/var/lib/postgresql
environment:
POSTGRES_PASSWORD: mysecretpassword
POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8"

volumes:
postgres_data:
```

This affects collation (sorting) and character processing behavior. Changing this variable after database creation has no effect—it only applies during the first run when the data directory is initialized.

## Connecting to the database

You can interact with PostgreSQL running in a container even without `psql` installed on your host machine.

### Interactive shell

Open a `psql` session inside the container:

```console
$ docker exec -it postgres-container psql -U postgres
```

Connect to a specific database:

```console
$ docker exec -it postgres-container psql -U postgres -d mydb
```
Loading