@@ -68,31 +68,42 @@ log "Starting PostgreSQL service..."
6868start_postgresql () {
6969 local CURRENT_UID=$( id -u)
7070
71- # Always use /tmp for PostgreSQL to work with any UID
72- export PGDATA=/tmp/postgresql/data
73- export PGHOST=/tmp
74-
75- # Clean up any previous attempts
71+ # Use UID-scoped directories to avoid permission conflicts when container
72+ # is restarted with a different UID (e.g., root -> non-root or vice versa)
73+ # This prevents "Permission denied" errors from stale directories owned by other UIDs
74+ export PGBASE=" /tmp/postgresql-${CURRENT_UID} "
75+ export PGDATA=" ${PGBASE} /data"
76+ export PGHOST=" ${PGBASE} "
77+
78+ # Clean up any previous attempts for THIS UID
7679 rm -rf " $PGDATA " 2> /dev/null || true
80+ rm -rf " $PGBASE " 2> /dev/null || true
7781 mkdir -p " $PGDATA "
7882
7983 log " Initializing PostgreSQL cluster in $PGDATA (UID: $CURRENT_UID )..."
8084
85+ # Verify we have proper access to the directory
86+ if [ ! -w " $PGDATA " ] || [ ! -x " $PGDATA " ]; then
87+ log " ERROR: Cannot write to or execute in $PGDATA "
88+ ls -ld " $PGBASE " " $PGDATA " 2>&1 | add_timestamps || true
89+ return 1
90+ fi
91+
8192 # Check if running as root - root cannot run initdb directly
8293 if [ " $CURRENT_UID " -eq 0 ]; then
8394 log " Running as root, using 'su - postgres' to initialize and run PostgreSQL..."
8495
8596 # Change ownership of the data directory to postgres user
86- chown -R postgres:postgres " $PGDATA "
97+ chown -R postgres:postgres " $PGBASE "
8798
8899 # Initialize as postgres user
89100 if ! su - postgres -c " initdb -D $PGDATA --auth-local=trust --auth-host=trust --username=postgres" 2>&1 | add_timestamps; then
90101 log " ERROR: Failed to initialize PostgreSQL as postgres user"
91102 return 1
92103 fi
93104
94- # Start PostgreSQL as postgres user
95- if ! su - postgres -c " pg_ctl -D $PGDATA -o \" -c listen_addresses='localhost' -c unix_socket_directories='/tmp ' -c shared_buffers=128MB -c max_connections=200 -c logging_collector=on -c log_line_prefix='%t '\" -l $PGDATA /logfile start" 2>&1 | add_timestamps; then
105+ # Start PostgreSQL as postgres user with UID-scoped socket directory
106+ if ! su - postgres -c " pg_ctl -D $PGDATA -o \" -c listen_addresses='localhost' -c unix_socket_directories='$PGBASE ' -c shared_buffers=128MB -c max_connections=200 -c logging_collector=on -c log_line_prefix='%t '\" -l $PGDATA /logfile start" 2>&1 | add_timestamps; then
96107 log " ERROR: Failed to start PostgreSQL"
97108 cat " $PGDATA /logfile" 2> /dev/null | add_timestamps
98109 return 1
@@ -106,9 +117,9 @@ start_postgresql() {
106117 return 1
107118 fi
108119
109- # Start PostgreSQL
120+ # Start PostgreSQL with UID-scoped socket directory
110121 if ! pg_ctl -D " $PGDATA " \
111- -o " -c listen_addresses='localhost' -c unix_socket_directories='/tmp ' -c shared_buffers=128MB -c max_connections=200 -c logging_collector=on -c log_line_prefix='%t '" \
122+ -o " -c listen_addresses='localhost' -c unix_socket_directories='$PGBASE ' -c shared_buffers=128MB -c max_connections=200 -c logging_collector=on -c log_line_prefix='%t '" \
112123 -l " $PGDATA /logfile" \
113124 start 2>&1 | add_timestamps; then
114125 log " ERROR: Failed to start PostgreSQL"
@@ -119,27 +130,30 @@ start_postgresql() {
119130
120131 log " PostgreSQL started successfully"
121132
122- # Wait for PostgreSQL to be ready
133+ # Wait for PostgreSQL to be ready (use UID-scoped socket directory)
123134 for i in {1..30}; do
124- if pg_isready -h /tmp -p 5432 2> /dev/null; then
135+ if pg_isready -h " $PGBASE " -p 5432 2> /dev/null; then
125136 log " PostgreSQL is ready"
126137 break
127138 fi
128139 log " Waiting for PostgreSQL to start... ($i /30)"
129140 sleep 1
130141 done
131142
132- # Create the database
143+ # Create the database (use UID-scoped socket directory)
133144 log " Creating database 'fdr'..."
134145 if [ " $CURRENT_UID " -eq 0 ]; then
135- su - postgres -c " createdb -h /tmp -U postgres fdr" 2>&1 | add_timestamps || true
146+ su - postgres -c " createdb -h $PGBASE -U postgres fdr" 2>&1 | add_timestamps || true
136147 else
137- createdb -h /tmp -U postgres fdr 2>&1 | add_timestamps || true
148+ createdb -h " $PGBASE " -U postgres fdr 2>&1 | add_timestamps || true
138149 fi
139150
140- # Update DATABASE_URL for Prisma to use the Unix socket
141- export DATABASE_URL=" postgresql://postgres:postgres@localhost:5432/fdr?host=/tmp"
142- log " DATABASE_URL configured for Unix socket in /tmp"
151+ # Update DATABASE_URL for Prisma to use the UID-scoped Unix socket
152+ export DATABASE_URL=" postgresql://postgres:postgres@localhost:5432/fdr?host=${PGBASE} "
153+ log " DATABASE_URL configured for Unix socket in $PGBASE "
154+
155+ # Write PGBASE to a known file so health check scripts can find the socket directory
156+ echo " $PGBASE " > /tmp/postgres-socket-dir
143157
144158 return 0
145159}
@@ -187,11 +201,11 @@ if [ "$USE_SEEDED_DATA" = "true" ] && [ -f "$SEED_POSTGRES_DUMP" ]; then
187201 log " Restoring PostgreSQL from seeded dump..."
188202 CURRENT_UID=$( id -u)
189203 if [ " $CURRENT_UID " -eq 0 ]; then
190- su - postgres -c " pg_restore -h /tmp -p 5432 -U postgres -d fdr --clean --if-exists '$SEED_POSTGRES_DUMP '" 2>&1 | add_timestamps || {
204+ su - postgres -c " pg_restore -h $PGBASE -p 5432 -U postgres -d fdr --clean --if-exists '$SEED_POSTGRES_DUMP '" 2>&1 | add_timestamps || {
191205 log " Warning: pg_restore had some errors (this may be normal for clean restore)"
192206 }
193207 else
194- pg_restore -h /tmp -p 5432 -U postgres -d fdr --clean --if-exists " $SEED_POSTGRES_DUMP " 2>&1 | add_timestamps || {
208+ pg_restore -h " $PGBASE " -p 5432 -U postgres -d fdr --clean --if-exists " $SEED_POSTGRES_DUMP " 2>&1 | add_timestamps || {
195209 log " Warning: pg_restore had some errors (this may be normal for clean restore)"
196210 }
197211 fi
281295
282296# ----------- Start MINIO setup -----------
283297
298+ # Configure MinIO client (mc) to use a writable config directory
299+ # When running as an arbitrary UID (e.g., 65532) that doesn't exist in /etc/passwd,
300+ # $HOME may default to "/" which isn't writable, causing "mc alias set" to fail.
301+ # Setting MC_CONFIG_DIR ensures mc can write its config regardless of the UID.
302+ export MC_CONFIG_DIR=" /tmp/mc-config"
303+ mkdir -p " $MC_CONFIG_DIR " 2> /dev/null || true
304+
284305# Clean up any existing MinIO system files to avoid overlay filesystem issues
285306# MinIO's .minio.sys can cause "rename across devices" errors if it exists from a previous layer
286307log " Cleaning up MinIO system files..."
0 commit comments