forked from GeneBO98/tradetally
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmigrate-postgres-16.sh
More file actions
executable file
·180 lines (146 loc) · 6.57 KB
/
migrate-postgres-16.sh
File metadata and controls
executable file
·180 lines (146 loc) · 6.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#!/bin/bash
# PostgreSQL 15 to 16 Migration Script for TradeTally
# This script safely migrates your PostgreSQL data from version 15 to 16
set -e # Exit on any error
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration - auto-detect compose file
if [[ -f "docker-compose.yaml" ]]; then
DOCKER_COMPOSE_FILE="docker-compose.yaml"
elif [[ -f "docker-compose.yml" ]]; then
DOCKER_COMPOSE_FILE="docker-compose.yml"
else
DOCKER_COMPOSE_FILE="docker-compose.dev.yaml"
fi
# Allow override via environment variable
DOCKER_COMPOSE_FILE="${COMPOSE_FILE:-$DOCKER_COMPOSE_FILE}"
echo -e "${BLUE}[INFO] Using compose file: $DOCKER_COMPOSE_FILE${NC}"
BACKUP_DIR="./postgres-migration-backup"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
BACKUP_FILE="tradetally_backup_${TIMESTAMP}.sql"
echo -e "${BLUE}=== TradeTally PostgreSQL 15 to 16 Migration ===${NC}"
echo -e "${YELLOW}[WARNING] This will temporarily stop your application and migrate your database.${NC}"
echo -e "${YELLOW}[WARNING] Make sure you have sufficient disk space for the backup.${NC}"
echo ""
# Check if docker-compose file exists
if [[ ! -f "$DOCKER_COMPOSE_FILE" ]]; then
echo -e "${RED}[ERROR] $DOCKER_COMPOSE_FILE not found!${NC}"
exit 1
fi
# Prompt for confirmation
read -p "Do you want to continue with the migration? (y/N): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}[CANCELLED] Migration cancelled by user.${NC}"
exit 0
fi
echo -e "${BLUE}[INFO] Starting PostgreSQL migration process...${NC}"
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Step 1: Create a full backup of the current database
echo -e "${BLUE}[STEP 1/6] Creating backup of current database...${NC}"
docker-compose -f "$DOCKER_COMPOSE_FILE" exec -T postgres pg_dumpall -U trader > "$BACKUP_DIR/$BACKUP_FILE"
if [[ $? -eq 0 ]]; then
echo -e "${GREEN}[SUCCESS] Database backup created: $BACKUP_DIR/$BACKUP_FILE${NC}"
# Show backup size
BACKUP_SIZE=$(du -h "$BACKUP_DIR/$BACKUP_FILE" | cut -f1)
echo -e "${BLUE}[INFO] Backup size: $BACKUP_SIZE${NC}"
else
echo -e "${RED}[ERROR] Failed to create database backup!${NC}"
exit 1
fi
# Step 2: Stop the current containers
echo -e "${BLUE}[STEP 2/6] Stopping current containers...${NC}"
docker-compose -f "$DOCKER_COMPOSE_FILE" down
# Determine volume name based on compose file
if [[ "$DOCKER_COMPOSE_FILE" == *"dev"* ]]; then
VOLUME_NAME="tradetally_postgres_data_dev"
else
VOLUME_NAME="tradetally_postgres_data"
fi
echo -e "${BLUE}[INFO] Using volume: $VOLUME_NAME${NC}"
# Step 3: Backup the PostgreSQL data volume
echo -e "${BLUE}[STEP 3/6] Backing up PostgreSQL data volume...${NC}"
docker run --rm -v "$VOLUME_NAME":/source -v "$(pwd)/$BACKUP_DIR":/backup alpine tar czf /backup/postgres_volume_backup_${TIMESTAMP}.tar.gz -C /source .
if [[ $? -eq 0 ]]; then
echo -e "${GREEN}[SUCCESS] PostgreSQL volume backed up${NC}"
else
echo -e "${RED}[ERROR] Failed to backup PostgreSQL volume!${NC}"
exit 1
fi
# Step 4: Remove the old PostgreSQL data volume
echo -e "${BLUE}[STEP 4/6] Removing old PostgreSQL data volume...${NC}"
docker volume rm "$VOLUME_NAME" || true
# Step 5: Update docker-compose to use PostgreSQL 16
echo -e "${BLUE}[STEP 5/6] Updating docker-compose to use PostgreSQL 16...${NC}"
sed -i.bak 's/postgres:15-alpine/postgres:16-alpine/g' "$DOCKER_COMPOSE_FILE"
# Step 6: Start PostgreSQL 16 and restore data
echo -e "${BLUE}[STEP 6/6] Starting PostgreSQL 16 and restoring data...${NC}"
# Start only PostgreSQL first
echo -e "${BLUE}[INFO] Starting PostgreSQL 16 container...${NC}"
docker-compose -f "$DOCKER_COMPOSE_FILE" up -d postgres
# Wait for PostgreSQL to be ready
echo -e "${BLUE}[INFO] Waiting for PostgreSQL 16 to be ready...${NC}"
for i in {1..30}; do
if docker-compose -f "$DOCKER_COMPOSE_FILE" exec -T postgres pg_isready -U trader -d tradetally; then
echo -e "${GREEN}[SUCCESS] PostgreSQL 16 is ready${NC}"
break
fi
if [[ $i -eq 30 ]]; then
echo -e "${RED}[ERROR] PostgreSQL 16 failed to start within 30 seconds${NC}"
echo -e "${YELLOW}[ROLLBACK] Restoring original configuration...${NC}"
mv "$DOCKER_COMPOSE_FILE.bak" "$DOCKER_COMPOSE_FILE"
exit 1
fi
echo -e "${YELLOW}[INFO] Waiting for PostgreSQL... (${i}/30)${NC}"
sleep 1
done
# Restore the database
echo -e "${BLUE}[INFO] Restoring database from backup...${NC}"
docker-compose -f "$DOCKER_COMPOSE_FILE" exec -T postgres psql -U trader -d postgres < "$BACKUP_DIR/$BACKUP_FILE"
if [[ $? -eq 0 ]]; then
echo -e "${GREEN}[SUCCESS] Database restored successfully${NC}"
else
echo -e "${RED}[ERROR] Failed to restore database!${NC}"
echo -e "${YELLOW}[INFO] You can manually restore using: ${NC}"
echo -e "${YELLOW}docker-compose -f $DOCKER_COMPOSE_FILE exec -T postgres psql -U trader -d postgres < $BACKUP_DIR/$BACKUP_FILE${NC}"
exit 1
fi
# Start all services
echo -e "${BLUE}[INFO] Starting all services...${NC}"
docker-compose -f "$DOCKER_COMPOSE_FILE" up -d
# Verify the migration
echo -e "${BLUE}[INFO] Verifying migration...${NC}"
sleep 5
# Check PostgreSQL version
PG_VERSION=$(docker-compose -f "$DOCKER_COMPOSE_FILE" exec -T postgres psql -U trader -d tradetally -t -c "SELECT version();" | head -1 | xargs)
echo -e "${BLUE}[INFO] Current PostgreSQL version: $PG_VERSION${NC}"
# Check if we can connect and query data
TRADE_COUNT=$(docker-compose -f "$DOCKER_COMPOSE_FILE" exec -T postgres psql -U trader -d tradetally -t -c "SELECT COUNT(*) FROM trades;" 2>/dev/null | xargs || echo "0")
echo -e "${BLUE}[INFO] Trade count in database: $TRADE_COUNT${NC}"
# Clean up backup file from docker-compose
rm -f "$DOCKER_COMPOSE_FILE.bak"
echo ""
echo -e "${GREEN}=== MIGRATION COMPLETED SUCCESSFULLY ===${NC}"
echo -e "${GREEN}[SUCCESS] PostgreSQL has been upgraded from 15 to 16${NC}"
echo -e "${BLUE}[INFO] Backups saved in: $BACKUP_DIR/${NC}"
echo -e "${BLUE}[INFO] - SQL backup: $BACKUP_FILE${NC}"
echo -e "${BLUE}[INFO] - Volume backup: postgres_volume_backup_${TIMESTAMP}.tar.gz${NC}"
echo ""
echo -e "${YELLOW}[RECOMMENDATION] Keep these backups until you're confident the migration was successful${NC}"
echo -e "${YELLOW}[RECOMMENDATION] Test your application thoroughly before deleting the backups${NC}"
# Optional cleanup prompt
echo ""
read -p "Do you want to clean up the backup files now? (y/N): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
rm -rf "$BACKUP_DIR"
echo -e "${GREEN}[INFO] Backup files cleaned up${NC}"
else
echo -e "${BLUE}[INFO] Backup files kept in: $BACKUP_DIR${NC}"
fi
echo -e "${GREEN}[COMPLETE] Migration process finished!${NC}"