init.sh
Overview
`init.sh` is a shell script designed to initialize and manage the lifecycle of a PostgreSQL database instance running inside a Docker container. It provides a controlled environment for starting the PostgreSQL server with specific configuration parameters and ensures graceful shutdown upon receiving termination signals.
The script achieves this by:
Starting the PostgreSQL server with customized runtime settings.
Capturing the process ID (PID) of the PostgreSQL server.
Installing signal traps to handle termination signals (
TERMandINT) gracefully.Ensuring the PostgreSQL process is properly terminated before the script exits.
This script is typically used as an entrypoint or initialization script in containerized environments where robust service start/stop behavior is critical.
File Components
1. start_service()
Purpose
Starts the PostgreSQL server with specific configuration overrides and runs it in the background.
Implementation Details
Uses docker-entrypoint.sh postgres to launch the PostgreSQL server.
Overrides the following PostgreSQL configuration parameters at runtime:
max_connections=100shared_buffers=128MBwal_buffers=16MBwork_mem=8MBplan_cache_mode=force_custom_plan
Runs the process in the background (
&) and captures its PID in the variablePID.
Parameters
None.
Returns
None explicitly, but sets the global variable
PIDto the process ID of the PostgreSQL server.
Usage Example
start_service
echo "PostgreSQL started with PID $PID"
2. stop_service()
Purpose
Gracefully stops the PostgreSQL server process by sending it a termination signal, then waits until the process has fully exited.
Implementation Details
Prints a message indicating the PID of the process being stopped.
Sends a
SIGTERMto the PostgreSQL process identified by$PID.Enters a loop that periodically checks if the process is still running using
kill -0 $PID.Waits with 1-second intervals until the process no longer exists.
Parameters
None.
Returns
None.
Usage Example
This function is intended to be called via signal trapping, but can be manually invoked as:
stop_service
echo "PostgreSQL stopped"
3. Signal Trapping
trap 'stop_service' TERM INT
Purpose
Sets up traps for the `TERM` (termination) and `INT` (interrupt, e.g., Ctrl+C) signals. When either signal is received, it runs the `stop_service` function.
This ensures the PostgreSQL server is cleanly shut down when the container or host system requests termination.
4. Script Execution Flow
start_serviceis called to launch PostgreSQL in the background.The script waits on the PostgreSQL process using
wait $PID.If a termination signal is caught,
stop_serviceis invoked to shut down PostgreSQL gracefully.
Important Implementation Details
set -e: The script exits immediately if any command fails, ensuring that errors don't cause the script to continue in an unstable state.Background Process Management: The PostgreSQL server is launched in the background with
&, allowing the script to install signal handlers and then wait explicitly for the process.Signal Propagation: By trapping termination signals and forwarding them to the PostgreSQL process, the script prevents abrupt container shutdowns that could lead to data corruption.
Polling Loop: Uses
kill -0 $PIDto check if the process is still alive without sending a real signal, which is a POSIX-compliant way to test process existence.
Interaction with Other System Components
Docker Entrypoint: This script wraps around the official
docker-entrypoint.shfor PostgreSQL, customizing its behavior.PostgreSQL Server: Directly manages the PostgreSQL process lifecycle inside the container.
Container Runtime: Responds to container lifecycle events (e.g., stop/restart) by handling termination signals.
System Signals: Listens for OS signals to gracefully stop the database service.
This script is a crucial part of the container startup routine, ensuring the database is launched with desired configuration parameters and stopped cleanly to maintain data integrity.
Visual Diagram
Below is a flowchart representing the main functions and control flow of `init.sh`:
flowchart TD
Start["Start Script"] --> SetTrap["Set trap for TERM and INT signals"]
SetTrap --> StartService["Call start_service()"]
StartService -->|Runs postgres in background| CapturePID["Capture PID of postgres process"]
CapturePID --> WaitProcess["wait $PID"]
%% Signal handling flow
subgraph SignalHandling["On TERM or INT signal"]
SignalCaught["Signal received"] --> CallStopService["Call stop_service()"]
CallStopService --> SendKill["kill $PID (SIGTERM)"]
SendKill --> LoopCheck["while kill -0 $PID"]
LoopCheck --> Sleep["sleep 1"]
Sleep --> LoopCheck
LoopCheck --> ExitStop["Postgres stopped"]
end
WaitProcess -->|Signal interrupts wait| SignalCaught
Summary
`init.sh` is a streamlined shell script that acts as a robust initializer and shutdown controller for a PostgreSQL service running in a Docker container. It configures specific PostgreSQL runtime parameters, manages the lifecycle of the database process, and ensures graceful shutdown by trapping termination signals and forwarding them to the database process. This behavior helps maintain database stability and data integrity in containerized environments.
Appendix: Usage in Container Context
Typically, this script would be specified as the entrypoint or command in a Dockerfile or Docker Compose configuration:
COPY init.sh /usr/local/bin/init.sh
ENTRYPOINT ["/usr/local/bin/init.sh"]
Or in a Docker Compose file:
services:
db:
image: postgres:latest
entrypoint: /usr/local/bin/init.sh
environment:
POSTGRES_PASSWORD: example
This ensures that the container runs PostgreSQL with the specified parameters and handles termination signals gracefully, enabling smooth restarts and shutdowns.