#!/bin/bash # --- AUTOMATIC PATH SETTING --- # This ensures the script always runs inside the folder where it lives PARENT_DIR="$(cd "$(dirname "$0")" && pwd)" cd "$PARENT_DIR" # --- .env LOADING --- # This safely loads the variables from .env without touching other files if [ -f "$PARENT_DIR/.env" ]; then set -a source "$PARENT_DIR/.env" set +a echo "[✔] Environment variables loaded." else echo "[!] No .env file found. Using defaults." fi # Container naming DB_CONTAINER_NAME="postgres_prod_trade" BACKUP_CONTAINER_NAME="postgres_backup_service_trade" IMAGE_TAG="10" # --- I. SETUP --- setup_environment() { echo "--- Phase 1: Environment Setup in $PARENT_DIR ---" # 1. Create folders relative to script location mkdir -p "$PARENT_DIR/config" "$PARENT_DIR/pgdata" "$PARENT_DIR/backups" echo "[✔] Directories verified: config, pgdata, backups" # 2. Extract default configs if they don't exist if [ ! -f "$PARENT_DIR/config/postgresql.conf" ]; then echo "[!] Configuration files are missing. Searching for templates..." if [ "$PARENT_DIR/config_template/postgresql.conf" ] && [ "$PARENT_DIR/config_template/postgresql.conf" ]; then read -p " config_template found, do you want to create template configuration from this files or from docker container? [y - config_template/n - docker]: " config_decision if [ "$config_decision" == "y" ]; then echo "[!] Copying custom templates from config_template/..." cp "$PARENT_DIR/config_template/postgresql.conf" "$PARENT_DIR/config/postgresql.conf" cp "$PARENT_DIR/config_template/pg_hba.conf" "$PARENT_DIR/config/pg_hba.conf" echo "[✔] Config files copied." elif [ "$config_decision" == "n" ]; then echo "[!] Extracting default config templates..." docker run --rm postgres:$IMAGE_TAG cat /usr/share/postgresql/$IMAGE_TAG/postgresql.conf.sample > "$PARENT_DIR/config/postgresql.conf" docker run --rm postgres:$IMAGE_TAG cat /usr/share/postgresql/$IMAGE_TAG/pg_hba.conf.sample > "$PARENT_DIR/config/pg_hba.conf" echo "[✔] Config files extracted." read -p " Make sure to update the configuration files to match your needs. Press any key: " else echo "[✘] Invalid input! Please run the script again and choose 'y' or 'n'." fi else echo "[!] Extracting default config templates..." docker run --rm postgres:$IMAGE_TAG cat /usr/share/postgresql/$IMAGE_TAG/postgresql.conf.sample > "$PARENT_DIR/config/postgresql.conf" docker run --rm postgres:$IMAGE_TAG cat /usr/share/postgresql/$IMAGE_TAG/pg_hba.conf.sample > "$PARENT_DIR/config/pg_hba.conf" echo "[✔] Config files extracted." read -p " Make sure to update the configuration files to match your needs. Press any key: " fi else echo "[i] Config files already exist. Skipping extraction." fi # 3. Set permissions (Postgres UID 999) echo "[!] Applying production permissions (sudo required)..." sudo chown -R 999:999 "$PARENT_DIR/pgdata" "$PARENT_DIR/config" "$PARENT_DIR/backups" echo "[✔] Permissions set." } # --- II. CONTAINER MANAGEMENT --- deploy_containers() { echo "--- Phase 2: Deploying Containers ---" docker compose up -d echo "[✔] Services started." } show_status() { echo "--- Service Status ---" docker compose ps echo "" echo "--- Resource Usage ---" docker stats --no-stream $DB_CONTAINER_NAME $BACKUP_CONTAINER_NAME } # --- III. SCRIPTS / UTILS --- run_backup() { echo "--- Phase 3: Manual Backup Trigger ---" docker exec $BACKUP_CONTAINER_NAME /backup.sh echo "[✔] Backup completed. Check ./backups/" } run_restore() { if [ -z "$1" ]; then echo "[✘] Error: Filename required. Usage: ./manage_db.sh restore filename.sql.gz" exit 1 fi FILE_PATH="$PARENT_DIR/$1" if [ ! -f "$FILE_PATH" ]; then echo "[✘] Error: File $FILE_PATH not found!" exit 1 fi echo "⚠️ WARNING: Restoring to database: ${POSTGRES_DB}" read -p "This will overwrite existing data. Confirm? (y/n): " confirm if [ "$confirm" == "y" ]; then echo "[!] Starting restore..." if [[ "$1" == *.gz ]]; then gunzip -c "$FILE_PATH" | docker exec -i $DB_CONTAINER_NAME psql -U $POSTGRES_USER -d $POSTGRES_DB elif [[ "$2" == *.gz ]]; then cat "$FILE_PATH" | docker exec -i $DB_CONTAINER_NAME psql -U $POSTGRES_USER -d $POSTGRES_DB else # Fallback for binary .dump files docker exec -i $DB_CONTAINER_NAME pg_restore -U $POSTGRES_USER -d $POSTGRES_DB --clean --if-exists < "$FILE_PATH" fi echo "[✔] Restore successful." else echo "[i] Restore aborted." fi } # --- COMMAND LOGIC --- case "$1" in setup) setup_environment ;; run|start) deploy_containers ;; stop) echo "[!] Stopping services..." docker compose stop ;; status) show_status ;; logs) docker compose logs -f ;; update) echo "[!] Rebuilding and restarting services..." docker compose up -d --remove-orphans ;; enter) echo "[!] Entering container terminal... (type 'exit' to leave)" sudo docker exec -it $DB_CONTAINER_NAME bash ;; psql) echo "[!] Entering SQL prompt..." # This automatically uses the DB and User from your .env sudo docker exec -it $DB_CONTAINER_NAME psql -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DB:-db} ;; backup) run_backup ;; restore) run_restore "$2" ;; *) echo "Usage: $0 {setup|run|stop|status|logs|update|enter|psql|backup|restore filename.sql.gz}" exit 1 esac