Fix data directory permission errors in Docker container

- Change CONFIG_DIR from relative 'data' to absolute '/data' path in installation.py
  This fixes PermissionError when trying to create /app/data instead of using
  the mounted volume at /data

- Update telemetry marker file paths to use absolute /data path for consistency

- Add ensure_data_directory() function to entrypoint_fixed.sh to:
  - Create /data directory if it doesn't exist
  - Set proper permissions (755) on /data
  - Attempt to set ownership to current user
  - Create /data/uploads subdirectory

This resolves the 'Permission denied: data' errors when accessing /admin/settings
and ensures the data volume is properly initialized at container startup.
This commit is contained in:
Dries Peeters
2025-11-28 22:47:55 +01:00
parent 6ad96f114a
commit c07aaa77fc
3 changed files with 47 additions and 4 deletions

View File

@@ -16,7 +16,7 @@ from typing import Dict, Optional
class InstallationConfig:
"""Manages installation-specific configuration"""
CONFIG_DIR = "data"
CONFIG_DIR = "/data"
CONFIG_FILE = "installation.json"
def __init__(self):

View File

@@ -302,7 +302,7 @@ def send_health_ping() -> bool:
return send_telemetry_ping(event_type="health")
def should_send_telemetry(marker_file: str = "data/telemetry_sent") -> bool:
def should_send_telemetry(marker_file: str = "/data/telemetry_sent") -> bool:
"""
Check if telemetry should be sent based on marker file.
@@ -318,7 +318,7 @@ def should_send_telemetry(marker_file: str = "data/telemetry_sent") -> bool:
return not os.path.exists(marker_file)
def mark_telemetry_sent(marker_file: str = "data/telemetry_sent") -> None:
def mark_telemetry_sent(marker_file: str = "/data/telemetry_sent") -> None:
"""
Create a marker file indicating telemetry has been sent.
@@ -360,7 +360,7 @@ def check_and_send_telemetry() -> bool:
if not is_telemetry_enabled():
return False
marker_file = os.getenv("TELEMETRY_MARKER_FILE", "data/telemetry_sent")
marker_file = os.getenv("TELEMETRY_MARKER_FILE", "/data/telemetry_sent")
if should_send_telemetry(marker_file):
success = send_install_ping()

View File

@@ -663,6 +663,46 @@ except Exception as e:
return 0
}
# Function to ensure data directory permissions
ensure_data_directory() {
log "Ensuring /data directory exists and has proper permissions..."
# Create /data directory if it doesn't exist
if [ ! -d "/data" ]; then
log "Creating /data directory..."
mkdir -p /data
fi
# Try to set permissions (best effort - may fail if we don't have permission)
# This is useful when the volume is mounted with different ownership
if [ -w "/data" ]; then
log "Setting permissions on /data directory..."
chmod 755 /data 2>/dev/null || true
# Get current user info
CURRENT_UID=$(id -u 2>/dev/null || echo "1000")
CURRENT_GID=$(id -g 2>/dev/null || echo "1000")
# Try to change ownership if we have permission (requires root or matching ownership)
if [ "$CURRENT_UID" = "0" ] || [ -O "/data" ]; then
log "Setting ownership of /data to current user (UID: $CURRENT_UID, GID: $CURRENT_GID)..."
chown "$CURRENT_UID:$CURRENT_GID" /data 2>/dev/null || true
else
log "Cannot change ownership of /data (not root and not owner), but directory is writable"
fi
# Ensure subdirectories exist
mkdir -p /data/uploads 2>/dev/null || true
chmod 755 /data/uploads 2>/dev/null || true
log "✓ /data directory setup complete"
else
log "⚠ /data directory is not writable - this may cause issues"
log "Current user: $(whoami) (UID: $(id -u 2>/dev/null || echo 'unknown'))"
log "Directory permissions: $(ls -ld /data 2>/dev/null || echo 'cannot read')"
fi
}
# Function to verify database integrity
verify_database_integrity() {
local db_url="$1"
@@ -851,6 +891,9 @@ main() {
log "Database URL: $db_url"
# Ensure data directory has proper permissions
ensure_data_directory
# Wait for database to be available
if ! wait_for_database "$db_url"; then
log "✗ Failed to connect to database"