Administrator guide for deploying PostgreSQL and PostGIS with Docker on the project workstation.
This guide documents how the database environment is set up so that it can be reproduced on a new workstation. It focuses on the infrastructure pattern and deployment sequence, not on project-specific secrets.
If the workstation will be administered remotely, enable the required operating-system services first. For Windows, OpenSSH is sufficient for remote administration.
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Start-Service sshd
Set-Service -Name sshd -StartupType Automatic
Get-Service sshd
Install Docker Desktop and verify that both Docker and Docker Compose are available:
docker --version
docker compose version
Create a local environment file from the template and fill in the real values outside of version control.
Copy-Item .env.example .env
Recommended pattern for the local .env file:
POSTGRES_DB=<database-name>
POSTGRES_USER=<database-admin-user>
POSTGRES_PASSWORD=<strong-random-password>
PGADMIN_DEFAULT_EMAIL=<admin-email>
PGADMIN_DEFAULT_PASSWORD=<strong-random-password>
POSTGIS_HOST=<database-hostname>
POSTGIS_PORT=5432
POSTGIS_DB=<database-name>
POSTGIS_USER=<database-admin-user>
POSTGIS_PASSWORD=<strong-random-password>
DATABASE_URL=postgresql://<database-admin-user>:<url-encoded-password>@<database-hostname>:5432/<database-name>
Guidelines:
From the repository root:
docker compose up -d
docker compose ps
Expected result:
Optional log check:
docker compose logs -f postgis
Run a direct check inside the container:
docker exec -it <postgis-container-name> psql -U <database-admin-user> -d <database-name> -c "SELECT PostGIS_Version();"
The result should return the installed PostGIS version.
The repository initializes the database from SQL files under sql/init. Confirm that the expected schemas and core tables exist after the first startup.
docker exec -it <postgis-container-name> psql -U <database-admin-user> -d <database-name>
Then run:
SELECT schema_name
FROM information_schema.schemata
WHERE schema_name NOT IN ('pg_catalog', 'information_schema');
If the database must be reachable from other clients, expose it only through the intended network boundary.
Recommended pattern:
Example firewall rules on Windows:
New-NetFirewallRule -DisplayName "PostgreSQL Private Access" `
-Direction Inbound `
-LocalPort 5432 `
-Protocol TCP `
-Action Allow `
-Profile Private
New-NetFirewallRule -DisplayName "pgAdmin Private Access" `
-Direction Inbound `
-LocalPort 5050 `
-Protocol TCP `
-Action Allow `
-Profile Private
Verify from a client machine using the private hostname instead of a literal IP:
Test-NetConnection -ComputerName <database-hostname> -Port 5432
psql -h <database-hostname> -p 5432 -U <database-admin-user> -d <database-name>
Create a backup:
docker exec <postgis-container-name> pg_dump -U <database-admin-user> -d <database-name> -F c -f /tmp/backup.dump
docker cp <postgis-container-name>:/tmp/backup.dump ./backups/backup_$(Get-Date -Format 'yyyyMMdd').dump
Restore a backup:
docker cp ./backups/<backup-file>.dump <postgis-container-name>:/tmp/restore.dump
docker exec <postgis-container-name> pg_restore -U <database-admin-user> -d <database-name> -c /tmp/restore.dump