first commit

This commit is contained in:
2026-03-16 00:02:58 +06:00
commit c11f0bd5bc
36 changed files with 11938 additions and 0 deletions

38
postgres/fhir/init.sql Normal file
View File

@@ -0,0 +1,38 @@
-- =============================================================================
-- postgres/fhir/init.sql
-- Runs once on first container start (postgres-fhir).
-- Creates the application user that HAPI uses at runtime.
-- Flyway migrations run as superuser separately.
-- =============================================================================
-- Application user — read/write to HAPI JPA tables
-- Password injected from FHIR_DB_APP_PASSWORD environment variable
-- via docker-compose. The \getenv syntax requires psql — use DO block instead.
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = current_setting('app.db_user', true)) THEN
-- User created by the entrypoint using POSTGRES_* env vars equivalent.
-- This script creates it explicitly for auditability.
NULL;
END IF;
END
$$;
-- Create app user. Password set via environment variable substitution
-- in the Docker entrypoint. The actual CREATE USER is handled by
-- the entrypoint script reading FHIR_DB_APP_USER/PASSWORD env vars.
-- This script grants the necessary privileges after user creation.
-- Grant connect
GRANT CONNECT ON DATABASE fhirdb TO hapi_app;
-- Grant schema usage and object privileges
-- Flyway creates all tables as superuser; we then grant hapi_app access.
-- These grants run after Flyway migrations on first startup via Spring Boot
-- ApplicationListener — see DataSourceConfig.java.
-- Pre-grant public schema access:
GRANT USAGE ON SCHEMA public TO hapi_app;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO hapi_app;
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT USAGE, SELECT ON SEQUENCES TO hapi_app;

View File

@@ -0,0 +1,81 @@
# =============================================================================
# postgres/fhir/postgresql.conf
# PostgreSQL 15 configuration tuned for HAPI FHIR JPA workload.
# Container memory limit: 2GB (set in docker-compose deploy.resources).
#
# Tuning methodology:
# shared_buffers = 25% of container RAM
# effective_cache = 75% of container RAM
# work_mem = (RAM - shared_buffers) / (max_connections * 2)
# maintenance_work_mem = 10% of RAM
#
# For 2GB container:
# shared_buffers = 512MB
# effective_cache_size = 1536MB
# work_mem = 8MB (conservative — many parallel queries)
# maintenance_work_mem = 200MB
# =============================================================================
# Connection settings
# max_connections must be > pgBouncer pool_size to leave headroom for
# superuser connections (Flyway, maintenance).
# pgBouncer pool_size=20 + 5 superuser = 25 total.
max_connections = 30
superuser_reserved_connections = 3
# Memory
shared_buffers = 512MB
effective_cache_size = 1536MB
work_mem = 8MB
maintenance_work_mem = 200MB
# Write performance
# wal_buffers: 16MB is good for write-heavy workloads
wal_buffers = 16MB
checkpoint_completion_target = 0.9
# synchronous_commit=on: do not disable — data integrity is non-negotiable
# for a national health record system.
synchronous_commit = on
# Query planner
# random_page_cost=1.1: appropriate for SSD storage (not spinning disk).
# If storage is HDD, set to 4.0.
random_page_cost = 1.1
effective_io_concurrency = 200
# Logging — errors and slow queries only
# log_min_duration_statement: log queries taking >500ms.
# Adjust down to 100ms if you want more visibility during initial deployment.
log_destination = stderr
logging_collector = off # Docker captures stderr directly
log_min_messages = WARNING
log_min_error_statement = ERROR
log_min_duration_statement = 500
log_line_prefix = '%t [%p] %u@%d '
log_checkpoints = on
log_connections = off # pgBouncer already logs connections
log_disconnections = off
log_lock_waits = on
log_temp_files = 0
# Autovacuum — keep defaults but tune for HAPI's high-write token tables
autovacuum = on
autovacuum_max_workers = 3
autovacuum_naptime = 30s
# HFJ_SPIDX_TOKEN is written heavily — lower threshold for autovacuum
autovacuum_vacuum_scale_factor = 0.02
autovacuum_analyze_scale_factor = 0.01
# Timezone — all timestamps in UTC
timezone = 'UTC'
log_timezone = 'UTC'
# Locale
lc_messages = 'en_US.UTF-8'
lc_monetary = 'en_US.UTF-8'
lc_numeric = 'en_US.UTF-8'
lc_time = 'en_US.UTF-8'
# Statistics
track_io_timing = on
track_counts = on