From a73d2b49595b5363e2c99c373bdd78b43aa446b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20D=C3=BCren?= Date: Tue, 18 Mar 2025 18:48:26 +0100 Subject: [PATCH] Fixed filesystem access issues and network binding for dual-instance Ente setup --- start.sh | 432 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 322 insertions(+), 110 deletions(-) diff --git a/start.sh b/start.sh index 9e82680..f2bf967 100644 --- a/start.sh +++ b/start.sh @@ -1,7 +1,7 @@ #!/bin/bash # Better signal handling - forward signals to child processes -trap 'kill -TERM $SERVER_PID; kill -TERM $CADDY_PID; exit' TERM INT +trap 'kill -TERM $SERVER_PID; kill -TERM $PUBLIC_SERVER_PID; kill -TERM $CADDY_PID; exit' TERM INT set -eu @@ -231,6 +231,7 @@ mkdir -p /app/data/caddy # Define ports CADDY_PORT=3080 API_PORT=8080 +PUBLIC_ALBUMS_PORT=8081 # New port for public albums service # Check if ports are available echo "==> Checking port availability" @@ -246,6 +247,12 @@ else echo "==> Port $API_PORT is available for API server" fi +if lsof -i:$PUBLIC_ALBUMS_PORT > /dev/null 2>&1; then + echo "==> WARNING: Port $PUBLIC_ALBUMS_PORT is already in use" +else + echo "==> Port $PUBLIC_ALBUMS_PORT is available for Public Albums server" +fi + # Determine available memory and set limits accordingly if [[ -f /sys/fs/cgroup/cgroup.controllers ]]; then # cgroup v2 memory_limit=$(cat /sys/fs/cgroup/memory.max) @@ -343,11 +350,15 @@ if [ -d "$SERVER_DIR/cmd/museum" ]; then if [ -f "$MAIN_GO" ]; then echo "==> Patching main.go to force correct database host" - # Create a backup of the original file - cp "$MAIN_GO" "${MAIN_GO}.orig" + # Create writable directory for patched files + mkdir -p /app/data/patched + + # Copy the file to a writable location before patching + cp "$MAIN_GO" "/app/data/patched/main.go" + WRITABLE_MAIN_GO="/app/data/patched/main.go" # Look for setupDatabase function and patch it - DB_SETUP_LINE=$(grep -n "func setupDatabase" "$MAIN_GO" | cut -d: -f1) + DB_SETUP_LINE=$(grep -n "func setupDatabase" "$WRITABLE_MAIN_GO" | cut -d: -f1) if [ -n "$DB_SETUP_LINE" ]; then echo "==> Found setupDatabase function at line $DB_SETUP_LINE" @@ -356,25 +367,24 @@ if [ -d "$SERVER_DIR/cmd/museum" ]; then sed -i "${DB_SETUP_LINE}a\\ \\tlog.Printf(\"Forcing database host to %s\", \"${CLOUDRON_POSTGRESQL_HOST}\")\\ \\tos.Setenv(\"PGHOST\", \"${CLOUDRON_POSTGRESQL_HOST}\")\\ -\\tos.Setenv(\"PGHOSTADDR\", \"${CLOUDRON_POSTGRESQL_HOST}\")" "$MAIN_GO" +\\tos.Setenv(\"PGHOSTADDR\", \"${CLOUDRON_POSTGRESQL_HOST}\")" "$WRITABLE_MAIN_GO" echo "==> Patched setupDatabase function" fi # If there's a connection string being built, patch that too - CONN_STR_LINE=$(grep -n "postgres://" "$MAIN_GO" | head -1 | cut -d: -f1) + CONN_STR_LINE=$(grep -n "postgres://" "$WRITABLE_MAIN_GO" | head -1 | cut -d: -f1) if [ -n "$CONN_STR_LINE" ]; then echo "==> Found connection string at line $CONN_STR_LINE" - # Backup again just to be safe - cp "$MAIN_GO" "${MAIN_GO}.conn_patch" - # Replace localhost or [::1] with the actual host - sed -i "s/localhost/${CLOUDRON_POSTGRESQL_HOST}/g" "$MAIN_GO" - sed -i "s/\[::1\]/${CLOUDRON_POSTGRESQL_HOST}/g" "$MAIN_GO" + sed -i "s/localhost/${CLOUDRON_POSTGRESQL_HOST}/g" "$WRITABLE_MAIN_GO" + sed -i "s/\[::1\]/${CLOUDRON_POSTGRESQL_HOST}/g" "$WRITABLE_MAIN_GO" echo "==> Patched connection string" fi + + echo "==> Will use patched version at runtime" fi fi @@ -423,103 +433,8 @@ else echo "==> Skipping migration state check: cmd/museum not found" fi -# Set up Caddy web server -echo "==> Setting up Caddy web server" - -# Create a Caddyfile for serving web apps and reverse proxy to API -cat > /app/data/caddy/Caddyfile < Created Caddy config at /app/data/caddy/Caddyfile" - # Start the Museum server with proper environment variables -echo "==> Starting Museum server" +echo "==> Starting main Museum server" cd "$SERVER_DIR" # Check if there's a pre-built binary @@ -560,8 +475,17 @@ CLOUDRON_POSTGRESQL_PORT="${CLOUDRON_POSTGRESQL_PORT}" \ CLOUDRON_POSTGRESQL_USERNAME="${CLOUDRON_POSTGRESQL_USERNAME}" \ CLOUDRON_POSTGRESQL_PASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}" \ CLOUDRON_POSTGRESQL_DATABASE="${CLOUDRON_POSTGRESQL_DATABASE}" \ -go run -ldflags "-X 'github.com/lib/pq.defaulthost=${MUSEUM_DB_HOST}'" overrides/db_override.go cmd/museum/main.go serve EOF + + # Check if we have a patched main.go to use + if [ -f "/app/data/patched/main.go" ]; then + echo "Using patched main.go from writable location" + echo "go run -ldflags \"-X 'github.com/lib/pq.defaulthost=${MUSEUM_DB_HOST}'\" overrides/db_override.go /app/data/patched/main.go serve" >> /tmp/run_server.sh + else + echo "Using original main.go from read-only location" + echo "go run -ldflags \"-X 'github.com/lib/pq.defaulthost=${MUSEUM_DB_HOST}'\" overrides/db_override.go cmd/museum/main.go serve" >> /tmp/run_server.sh + fi + chmod +x /tmp/run_server.sh /usr/local/bin/gosu cloudron:cloudron env \ @@ -672,7 +596,7 @@ echo "==> Server started with PID $SERVER_PID" # Test if API is responding echo "==> Testing API connectivity" for i in {1..5}; do - if curl -s --max-time 2 --fail http://localhost:$API_PORT/health > /dev/null; then + if curl -s --max-time 2 --fail http://0.0.0.0:$API_PORT/health > /dev/null; then echo "==> API is responding on port $API_PORT" break else @@ -687,6 +611,264 @@ for i in {1..5}; do fi done +# Start the Public Albums Museum server (second instance) +echo "==> Starting Public Albums Museum server" + +# Create configuration for public albums instance +mkdir -p /app/data/config/public +cp /app/data/config/museum.yaml /app/data/config/public/museum.yaml + +if [ -n "$MUSEUM_BIN" ]; then + echo "==> Starting Public Albums Museum from binary: $MUSEUM_BIN" + MUSEUM_CONFIG="/app/data/config/public/museum.yaml" $MUSEUM_BIN serve --port $PUBLIC_ALBUMS_PORT > /app/data/logs/public_museum.log 2>&1 & + PUBLIC_SERVER_PID=$! +elif [ -d "$SERVER_DIR/cmd/museum" ]; then + echo "==> Starting Public Albums Museum from source" + # Create a startup script + cat > /tmp/run_public_server.sh <> /tmp/run_public_server.sh + else + echo "Using original main.go from read-only location" + echo "go run -ldflags \"-X 'github.com/lib/pq.defaulthost=${MUSEUM_DB_HOST}'\" overrides/db_override.go cmd/museum/main.go serve --port $PUBLIC_ALBUMS_PORT" >> /tmp/run_public_server.sh + fi + + chmod +x /tmp/run_public_server.sh + + /usr/local/bin/gosu cloudron:cloudron env \ + GOCACHE="$GOCACHE" \ + GOMODCACHE="$GOMODCACHE" \ + GO111MODULE=on \ + GOFLAGS="$GOFLAGS" \ + MUSEUM_CONFIG="/app/data/config/public/museum.yaml" \ + MUSEUM_DB_HOST="$MUSEUM_DB_HOST" \ + MUSEUM_DB_PORT="$MUSEUM_DB_PORT" \ + MUSEUM_DB_USER="$MUSEUM_DB_USER" \ + MUSEUM_DB_PASSWORD="$MUSEUM_DB_PASSWORD" \ + MUSEUM_DB_NAME="$MUSEUM_DB_NAME" \ + ENTE_PG_DSN="postgres://${MUSEUM_DB_USER}:${MUSEUM_DB_PASSWORD}@${MUSEUM_DB_HOST}:${MUSEUM_DB_PORT}/${MUSEUM_DB_NAME}?sslmode=disable" \ + ENTE_PG_HOST="$MUSEUM_DB_HOST" \ + ENTE_PG_PORT="$MUSEUM_DB_PORT" \ + ENTE_PG_USER="$MUSEUM_DB_USER" \ + ENTE_PG_PASSWORD="$MUSEUM_DB_PASSWORD" \ + ENTE_PG_DATABASE="$MUSEUM_DB_NAME" \ + PGHOST="$PGHOST" \ + PGPORT="$PGPORT" \ + PGUSER="$PGUSER" \ + PGPASSWORD="$PGPASSWORD" \ + PGDATABASE="$PGDATABASE" \ + PGSSLMODE="$PGSSLMODE" \ + ENTE_LOG_LEVEL=debug \ + bash /tmp/run_public_server.sh > /app/data/logs/public_museum.log 2>&1 & + PUBLIC_SERVER_PID=$! +else + echo "==> ERROR: Museum server not found for public albums" + echo "==> Starting a mock public albums server" + + # Create a temporary directory for a simple Go server + mkdir -p /tmp/mock-public-server + cat > /tmp/mock-public-server/main.go.template < /tmp/mock-public-server/main.go + + # Run the mock server with environment variables + cd /tmp/mock-public-server + go run main.go > /app/data/logs/public_museum.log 2>&1 & + PUBLIC_SERVER_PID=$! + + echo "==> Mock Public Albums server started with PID $PUBLIC_SERVER_PID" +fi + +echo "==> Public Albums server started with PID $PUBLIC_SERVER_PID" + +# Test if Public Albums API is responding +echo "==> Testing Public Albums API connectivity" +for i in {1..5}; do + if curl -s --max-time 2 --fail http://0.0.0.0:$PUBLIC_ALBUMS_PORT/health > /dev/null; then + echo "==> Public Albums API is responding on port $PUBLIC_ALBUMS_PORT" + break + else + if [ $i -eq 5 ]; then + echo "==> WARNING: Public Albums API is not responding after several attempts" + echo "==> Last 20 lines of public_museum.log:" + tail -20 /app/data/logs/public_museum.log || echo "==> No public_museum.log available" + else + echo "==> Attempt $i: Waiting for Public Albums API to start... (2 seconds)" + sleep 2 + fi + fi +done + +# Set up Caddy web server +echo "==> Setting up Caddy web server" + +# Create a Caddyfile for serving web apps and reverse proxy to API +cat > /app/data/caddy/Caddyfile < Created Caddy config at /app/data/caddy/Caddyfile" + # Start Caddy server echo "==> Starting Caddy server" caddy start --config /app/data/caddy/Caddyfile --adapter caddyfile & @@ -699,7 +881,7 @@ sleep 2 # Test Caddy connectivity echo "==> Testing Caddy connectivity" for i in {1..5}; do - if curl -s --max-time 2 --fail http://localhost:$CADDY_PORT/health > /dev/null; then + if curl -s --max-time 2 --fail http://0.0.0.0:$CADDY_PORT/health > /dev/null; then echo "==> Caddy is responding on port $CADDY_PORT" break else @@ -716,9 +898,39 @@ done echo "==> Application is now running" echo "==> Access your Ente instance at: $CLOUDRON_APP_ORIGIN" +# Check communication between frontend and backend services +echo "==> Checking communication between frontend and backend services" +echo "==> Testing main API communication" +MAIN_API_TEST=$(curl -s --max-time 2 http://0.0.0.0:$CADDY_PORT/api/health) +if [ $? -eq 0 ]; then + echo "==> Main API communication via frontend is working" +else + echo "==> WARNING: Main API communication via frontend is NOT working" + echo "==> Response: $MAIN_API_TEST" +fi + +echo "==> Testing public albums API communication" +PUBLIC_API_TEST=$(curl -s --max-time 2 http://0.0.0.0:$CADDY_PORT/public/health) +if [ $? -eq 0 ]; then + echo "==> Public Albums API communication via frontend is working" +else + echo "==> WARNING: Public Albums API communication via frontend is NOT working" + echo "==> Response: $PUBLIC_API_TEST" +fi + +echo "==> Testing frontend config.js" +CONFIG_JS_TEST=$(curl -s --max-time 2 http://0.0.0.0:$CADDY_PORT/config.js) +if [[ "$CONFIG_JS_TEST" == *"API_URL"* && "$CONFIG_JS_TEST" == *"PUBLIC_ALBUMS_URL"* ]]; then + echo "==> Frontend configuration is properly loaded" +else + echo "==> WARNING: Frontend configuration is not properly loaded" + echo "==> Response: $CONFIG_JS_TEST" +fi + echo "==> Entering wait state - press Ctrl+C to stop" # Wait for all background processes to complete (or for user to interrupt) wait $SERVER_PID +wait $PUBLIC_SERVER_PID wait $CADDY_PID # Create a new go file to inject into the build that overrides the database connection