Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/build-latest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ jobs:
run-scenario-tests:
runs-on: ubuntu-latest
needs: [build-docker-image]
timeout-minutes: 20
timeout-minutes: 60
if: |
(github.event_name != 'pull_request' || github.event.pull_request.user.login != 'dependabot[bot]') &&
github.actor != 'dependabot[bot]' &&
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,6 @@ jobs:
- name: publish_release
id: tag_releases
run: |
gh release create v${{ matrix.postgresMajorVersion }}.${{ matrix.postgisMajorVersion }}.${{ matrix.postgisMinorRelease }}--v${{ steps.current_date.outputs.formatted }}--${{ steps.latest_commit_hash.outputs.commit }} --notes ${{ steps.latest_commit_hash.outputs.commit }} --target develop --repo $GITHUB_REPOSITORY
gh release create v${{ matrix.postgresMajorVersion }}-${{ matrix.postgisMajorVersion }}.${{ matrix.postgisMinorRelease }}--v${{ steps.current_date.outputs.formatted }}--${{ steps.latest_commit_hash.outputs.commit }} --notes ${{ steps.latest_commit_hash.outputs.commit }} --target develop --repo $GITHUB_REPOSITORY
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
venv
.venv
__pycache__

scenario_tests/datadir_init/default-pg-data-dir
scenario_tests/datadir_init/local-pg-data-dir
.env
87 changes: 80 additions & 7 deletions Advanced-Configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ to specify different empty directory, like this
The containers will use above parameters to initialize a new db cluster in the specified directory.
If the directory is not empty, then the initialization parameter will be ignored.

Also make sure that the `DEFAULT_COLLATION`,`DEFAULT_CTYPE` also
correspond to installed locales. The image installs the following
locales by default

```
LANGS=en_US.UTF-8,id_ID.UTF-8
```

If the environment variables `DEFAULT_COLLATION`,`DEFAULT_CTYPE`
referer to a locale that is not installed, it will default
to the C locale.

These are some initialization parameters that will only be used to initialize a new cluster. If the
container uses an existing cluster, it is ignored (for example, when the container restarts).

Expand All @@ -86,15 +98,76 @@ directory will always be available, even though it doesn't need the environment
If you didn't persist this location, Postgres will not be able to find the `pg_wal` directory and
consider the instance to be broken.

In addition to that, we have another parameter: `RECREATE_DATADIR` that can be used to force
database re-initializations. If this parameter is specified as `TRUE` it will act as explicit
consent to delete `DATADIR` and create new db cluster.
#### PostgreSQL Datadir Recreation Modes

The PostgreSQL datadir recreation behavior can be controlled using the
`DATADIR_RECREATE_MODE` environment variable. This feature gives you
fine-grained control over when the database cluster should be reinitialized.

##### Environment Variable

| Variable | Values | Default |
|--------------|--------------|---------|
| DATADIR_RECREATE_MODE | never, once, always, empty | never |


###### Recreation Modes
| Variable | Values | Default |
|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------|
| never | Never recreates the datadir. If the datadir is empty on first start, it will be initialized. Subsequent starts always use the existing datadir. |Production environments where data persistence is critical. |
| once | Recreates the datadir only once during the container's lifetime. A marker file (/tmp/postgres_recreate_once.marker) tracks if recreation has already occurred. | Testing scenarios where you need a fresh database on first run but want to preserve data between restarts. |
| always | Recreates the datadir on every container start. All existing data will be lost on each restart. | CI/CD pipelines, ephemeral environments, or when you need a completely fresh state every time. |
| empty | Recreates the datadir only if the datadir is empty. If the datadir contains any data, recreation is skipped. | Development environments where you want automatic initialization for new volumes but never want to accidentally wipe existing data. |


Examples

* Never recreate datadir (production default)
```
docker run -e DATADIR_RECREATE_MODE=never -v pg_data:/var/lib/postgresql kartoza/postgis:18-3.6
```
* Recreate once per container lifetime
```
docker run -e DATADIR_RECREATE_MODE=once -v pg_data:/var/lib/postgresql kartoza/postgis:18-3.6
```
* Always recreate on every start
```
docker run -e DATADIR_RECREATE_MODE=always -v pg_data:/var/lib/postgresql kartoza/postgis:18-3.6
```
* Recreate only if datadir is empty
```
docker run -e DATADIR_RECREATE_MODE=empty -v pg_data:/var/lib/postgresql kartoza/postgis:18-3.6
```

###### Backward Compatibility
The following legacy environment variables are still supported
and automatically mapped to the new modes:


| Legacy Variable | Maps to Mode | Description |
|--------------|-------------------|-----------------------|
| RECREATE_DATADIR=true | once | Recreate datadir once |
| RECREATE_ONCE=true | once | Recreate datadir once |
| RECREATE_ALWAYS=true | always | Always recreate datadir |

Note: The new DATADIR_RECREATE_MODE takes precedence over legacy variables.
It's recommended to migrate to the new variable for better control.

**Notes**:

Data Loss Warning: Modes always and once (on first run) will completely wipe your PostgreSQL datadir.
Ensure you have proper backups when using these modes with persistent volumes.

* Marker File: The once mode creates a marker file at /tmp/postgres_recreate_once.marker inside the container.
Removing this file will cause recreation to occur on the next container start.

* Empty Directory Detection: The empty and never modes both initialize the database if
the datadir is completely empty. This ensures the container can start successfully
with fresh volumes.

* `RECREATE_DATADIR`: Force database re-initialization in the location `DATADIR`
* WAL Directory Support: All recreation modes work seamlessly with custom WAL directories
configured via POSTGRES_INITDB_WALDIR.

If you used `RECREATE_DATADIR` and successfully created a new cluster. Remember that you should
remove this parameter afterwards. Because, if it was not omitted, it will always recreate new db
cluster after every container restarts.

### Postgres Encoding

Expand Down
15 changes: 4 additions & 11 deletions scenario_tests/collations/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,24 @@ set -e
source ../test-env.sh

# Run service
if [[ $(dpkg -l | grep "docker-compose") > /dev/null ]];then
VERSION='docker-compose'
else
VERSION='docker compose'
fi
determine_compose_version

${VERSION} up -d

if [[ -n "${PRINT_TEST_LOGS}" ]]; then
${VERSION} logs -f &
fi

sleep 30


services=("pg" "pg-new" "pg-gosu" "pg-new-gosu")

for service in "${services[@]}"; do

# Execute tests
until ${VERSION} exec -T $service pg_isready; do
sleep 30
echo "Wait service to be ready"
done;
wait_for_postgres $service
echo "Execute test for $service"
${VERSION} exec -T $service /bin/bash /tests/test.sh
run_tests "$service"

done

Expand Down
29 changes: 11 additions & 18 deletions scenario_tests/datadir_init/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ set -e

source ../test-env.sh

if [[ $(dpkg -l | grep "docker-compose") > /dev/null ]];then
VERSION='docker-compose'
else
VERSION='docker compose'
fi
determine_compose_version


# Run service for root user
Expand All @@ -19,27 +15,26 @@ if [[ -n "${PRINT_TEST_LOGS}" ]]; then
${VERSION} logs -f &
fi

sleep 30


services=("pg-local" "pg-default" "pg-new" "pg-recreate")

for service in "${services[@]}"; do

# Execute tests
until ${VERSION} exec -T $service pg_isready; do
sleep 5
echo "Wait service to be ready"
done;

wait_for_postgres $service
echo "Execute test for $service"
${VERSION} exec -T $service /bin/bash /tests/test.sh
run_tests "$service"

done

# special meta test to check the setup
echo "starting wal tests ----------------"
bash ./test_custom_waldir.sh

${VERSION} down -v

echo "completed wal tests ----------------"

# Run service for none root user
mkdir default-pg-data-dir
Expand All @@ -50,19 +45,17 @@ if [[ -n "${PRINT_TEST_LOGS}" ]]; then
${VERSION} -f docker-compose-gs.yml logs -f &
fi

sleep 30


services=("pg-local" "pg-default" "pg-new" "pg-recreate")

for service in "${services[@]}"; do

# Execute tests
until ${VERSION} -f docker-compose-gs.yml exec -T $service pg_isready; do
sleep 5
echo "Wait service to be ready"
done;

wait_for_postgres $service "docker-compose-gs.yml"
echo "Execute test for $service"
${VERSION} -f docker-compose-gs.yml exec -T $service /bin/bash /tests/test.sh
run_tests "$service" "docker-compose-gs.yml"

done

Expand Down
29 changes: 7 additions & 22 deletions scenario_tests/datadir_init/test_custom_waldir.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ set -e

source ../test-env.sh

if [[ $(dpkg -l | grep "docker-compose") > /dev/null ]];then
VERSION='docker-compose'
else
VERSION='docker compose'
fi
determine_compose_version

# This test is special
# It is used to check the meta level of the setup.
Expand All @@ -25,19 +21,15 @@ echo "### Checking Container Recreation"
${VERSION} down
${VERSION} up -d pg-local pg-default pg-new pg-recreate

sleep 60

services=("pg-local" "pg-default" "pg-new" "pg-recreate")

for service in "${services[@]}"; do

# Execute tests
until ${VERSION} exec -T $service pg_isready; do
sleep 5
echo "Wait service to be ready"
done;
wait_for_postgres $service
echo "Execute test for $service"
${VERSION} exec -T $service /bin/bash /tests/test.sh
run_tests "$service"

done

Expand Down Expand Up @@ -66,13 +58,9 @@ service="pg-custom-waldir-correct"
for ((i=1;i<=2;i++)); do
echo "attempt $i"
${VERSION} up -d $service
sleep 60
until ${VERSION} exec -T $service pg_isready; do
sleep 5
echo "Wait service to be ready"
done;
wait_for_postgres $service
echo "Execute test for $service"
${VERSION} exec -T $service /bin/bash /tests/test.sh
run_tests "$service"
${VERSION} down
done

Expand All @@ -90,12 +78,9 @@ while true; do
fi
sleep 5
done;
until ${VERSION} exec -T $service pg_isready; do
sleep 5
echo "Wait service to be ready"
done;
wait_for_postgres $service
echo "Execute test for $service"
${VERSION} exec -T $service /bin/bash /tests/test.sh
run_tests "$service"
${VERSION} down

# Check that if the pg_wal is empty, then something is wrong and we should exit
Expand Down
Loading
Loading