#!/bin/bash # Better signal handling - forward signals to child processes trap 'kill -TERM $SERVER_PID; kill -TERM $PUBLIC_SERVER_PID; kill -TERM $CADDY_PID; exit' TERM INT set -eu echo "==> Starting Ente Cloudron app..." # Create necessary directories mkdir -p /app/data/config /app/data/storage /app/data/caddy /app/data/go /app/data/logs # Add comment about Cloudron filesystem limitations echo "==> NOTE: Running in Cloudron environment with limited write access" echo "==> Writable directories: /app/data, /tmp, /run" # Define the server directory SERVER_DIR="/app/code/server" if [ ! -d "$SERVER_DIR" ]; then if [ -d "/app/code/museum" ]; then SERVER_DIR="/app/code/museum" else # Look for main.go in likely places SERVER_DIR=$(dirname $(find /app/code -name "main.go" -path "*/server*" -o -path "*/museum*" | head -1)) if [ ! -d "$SERVER_DIR" ]; then echo "==> WARNING: Could not find server directory, using /app/code as fallback" SERVER_DIR="/app/code" fi fi fi echo "==> Using server directory: $SERVER_DIR" # One-time initialization tracking if [[ ! -f /app/data/.initialized ]]; then echo "==> Fresh installation, setting up data directory..." echo "==> DEBUG: Full repository structure at /app/code" find /app/code -type d -maxdepth 3 -not -path "*/node_modules/*" -not -path "*/\.*" | sort echo "==> DEBUG: Looking for Go files" find /app/code -name "*.go" | grep -v test | sort | head -10 echo "==> DEBUG: Looking for server-related directories" find /app/code -type d -path "*/server*" -o -path "*/museum*" | sort echo "==> DEBUG: All package.json files in repository" find /app/code -name "package.json" -not -path "*/node_modules/*" | sort echo "==> DEBUG: Looking for web app directories" find /app/code -type d -path "*/web*" | sort echo "==> DEBUG: Web app directories in /app/web (if they exist)" if [ -d "/app/web" ]; then ls -la /app/web else echo "Web app directory not yet copied to /app/web" fi # Create config template file on first run echo "==> First run - creating configuration template" # Generate random secrets JWT_SECRET=$(openssl rand -hex 32) SESSION_SECRET=$(openssl rand -hex 32) MASTER_KEY=$(openssl rand -hex 32) # Replace variables in template for things we know sed \ -e "s|%%POSTGRESQL_HOST%%|${CLOUDRON_POSTGRESQL_HOST}|g" \ -e "s|%%POSTGRESQL_PORT%%|${CLOUDRON_POSTGRESQL_PORT}|g" \ -e "s|%%POSTGRESQL_USERNAME%%|${CLOUDRON_POSTGRESQL_USERNAME}|g" \ -e "s|%%POSTGRESQL_PASSWORD%%|${CLOUDRON_POSTGRESQL_PASSWORD}|g" \ -e "s|%%POSTGRESQL_DATABASE%%|${CLOUDRON_POSTGRESQL_DATABASE}|g" \ -e "s|%%APP_ORIGIN%%|${CLOUDRON_APP_ORIGIN}|g" \ -e "s|%%MAIL_SMTP_SERVER%%|${CLOUDRON_MAIL_SMTP_SERVER}|g" \ -e "s|%%MAIL_SMTP_PORT%%|${CLOUDRON_MAIL_SMTP_PORT}|g" \ -e "s|%%MAIL_SMTP_USERNAME%%|${CLOUDRON_MAIL_SMTP_USERNAME}|g" \ -e "s|%%MAIL_SMTP_PASSWORD%%|${CLOUDRON_MAIL_SMTP_PASSWORD}|g" \ -e "s|%%MAIL_FROM%%|${CLOUDRON_MAIL_FROM}|g" \ -e "s|%%MAIL_FROM_DISPLAY_NAME%%|${CLOUDRON_MAIL_FROM_DISPLAY_NAME}|g" \ -e "s|%%JWT_SECRET%%|${JWT_SECRET}|g" \ -e "s|%%SESSION_SECRET%%|${SESSION_SECRET}|g" \ -e "s|%%MASTER_KEY%%|${MASTER_KEY}|g" \ /app/pkg/config.template.yaml > /app/data/config/config.yaml # Create an S3 configuration file template cat > /app/data/config/s3.env.template < IMPORTANT: S3 storage configuration required" echo "==> Please configure your S3 storage as follows:" echo "1. Log into your Cloudron dashboard" echo "2. Go to the app's configuration page" echo "3. Edit the file /app/data/config/s3.env" echo "4. Restart the app" # Mark initialization as complete touch /app/data/.initialized echo "==> Initialization complete" fi # Check if configuration exists if [ ! -f "/app/data/config/s3.env" ]; then echo "==> First run - creating configuration template" mkdir -p /app/data/config # Create a template S3 configuration file echo "==> Creating S3 configuration template" cat > /app/data/config/s3.env.template < IMPORTANT: S3 storage configuration required" echo "==> Please configure your S3 storage as follows:" echo "1. Log into your Cloudron dashboard" echo "2. Go to the app's configuration page" echo "3. Edit the file /app/data/config/s3.env" echo "4. Restart the app" else echo "==> Using existing S3 configuration" fi # Check if s3.env is empty if [ ! -s "/app/data/config/s3.env" ]; then echo "==> WARNING: S3 configuration file is empty. The app will not function correctly until configured." echo "==> Please refer to the template at /app/data/config/s3.env.template for instructions." fi # Source S3 configuration if [ -f /app/data/config/s3.env ]; then echo "==> Sourcing S3 configuration from /app/data/config/s3.env" source /app/data/config/s3.env fi # Display S3 configuration (masking sensitive values) echo "==> S3 Configuration:" echo "Endpoint: ${S3_ENDPOINT}" echo "Region: ${S3_REGION}" echo "Bucket: ${S3_BUCKET}" echo "Prefix: ${S3_PREFIX:-}" # Create museum.yaml for proper S3 configuration echo "==> Creating museum.yaml configuration" cat > /app/data/config/museum.yaml < Created museum.yaml with S3 configuration" # Update the config file with S3 credentials sed -i \ -e "s|%%S3_ENDPOINT%%|${S3_ENDPOINT}|g" \ -e "s|%%S3_REGION%%|${S3_REGION}|g" \ -e "s|%%S3_BUCKET%%|${S3_BUCKET}|g" \ -e "s|%%S3_ACCESS_KEY%%|${S3_ACCESS_KEY}|g" \ -e "s|%%S3_SECRET_KEY%%|${S3_SECRET_KEY}|g" \ -e "s|%%S3_PREFIX%%|${S3_PREFIX:-}|g" \ /app/data/config/config.yaml # Set storage type to S3 in config sed -i 's|storage.type: "local"|storage.type: "s3"|g' /app/data/config/config.yaml sed -i 's|s3.are_local_buckets: true|s3.are_local_buckets: false|g' /app/data/config/config.yaml # Set up the API endpoint for the web apps API_ENDPOINT="${CLOUDRON_APP_ORIGIN}/api" echo "==> Setting API endpoint to $API_ENDPOINT" # Set environment variables for the web apps export ENTE_API_ENDPOINT=$API_ENDPOINT export NEXT_PUBLIC_ENTE_ENDPOINT=$API_ENDPOINT export REACT_APP_ENTE_ENDPOINT=$API_ENDPOINT export VUE_APP_ENTE_ENDPOINT=$API_ENDPOINT echo "==> Set environment variables for web apps" # Create directory for configuration files mkdir -p /app/data/public mkdir -p /app/data/scripts mkdir -p /app/data/logs 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" if lsof -i:$CADDY_PORT > /dev/null 2>&1; then echo "==> WARNING: Port $CADDY_PORT is already in use" else echo "==> Port $CADDY_PORT is available for Caddy" fi if lsof -i:$API_PORT > /dev/null 2>&1; then echo "==> WARNING: Port $API_PORT is already in use" 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) if [[ "$memory_limit" != "max" ]]; then MEMORY_MB=$((memory_limit / 1024 / 1024)) else MEMORY_MB=$(free -m | awk '/^Mem:/{print $2}') fi else # cgroup v1 if [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then memory_limit=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) MEMORY_MB=$((memory_limit / 1024 / 1024)) else MEMORY_MB=$(free -m | awk '/^Mem:/{print $2}') fi fi echo "==> Available memory: ${MEMORY_MB}MB" # Test database connectivity echo "==> Checking database connectivity" PGPASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}" psql -h ${CLOUDRON_POSTGRESQL_HOST} -p ${CLOUDRON_POSTGRESQL_PORT} -U ${CLOUDRON_POSTGRESQL_USERNAME} -d ${CLOUDRON_POSTGRESQL_DATABASE} -c "SELECT 1" > /dev/null if [ $? -ne 0 ]; then echo "==> ERROR: Failed to connect to database" echo "Host: ${CLOUDRON_POSTGRESQL_HOST}" echo "Port: ${CLOUDRON_POSTGRESQL_PORT}" echo "User: ${CLOUDRON_POSTGRESQL_USERNAME}" echo "Database: ${CLOUDRON_POSTGRESQL_DATABASE}" exit 1 fi echo "==> Successfully connected to database" # Create proper Go module environment echo "==> Setting up Go module environment" if [ -f "$SERVER_DIR/go.mod" ]; then echo "==> Found go.mod in $SERVER_DIR" mkdir -p /app/data/go cp "$SERVER_DIR/go.mod" "/app/data/go/go.mod" if [ -f "$SERVER_DIR/go.sum" ]; then cp "$SERVER_DIR/go.sum" "/app/data/go/go.sum" fi echo "==> Copied go.mod to /app/data/go/go.mod" else echo "==> WARNING: No go.mod found in $SERVER_DIR" # Create a minimal go.mod file mkdir -p /app/data/go cat > /app/data/go/go.mod < Created minimal go.mod in /app/data/go/go.mod" fi # Ensure the right permissions chmod 644 /app/data/go/go.mod # Setup Go directories with proper permissions mkdir -p /app/data/go/pkg/mod /app/data/go/cache chmod -R 777 /app/data/go chown -R cloudron:cloudron /app/data/go # Set necessary environment variables - MOVED EARLIER IN THE SCRIPT export MUSEUM_CONFIG="/app/data/config/museum.yaml" export MUSEUM_DB_HOST="${CLOUDRON_POSTGRESQL_HOST}" export MUSEUM_DB_PORT="${CLOUDRON_POSTGRESQL_PORT}" export MUSEUM_DB_USER="${CLOUDRON_POSTGRESQL_USERNAME}" export MUSEUM_DB_PASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}" export MUSEUM_DB_NAME="${CLOUDRON_POSTGRESQL_DATABASE}" export ENTE_LOG_LEVEL=debug export GOMODCACHE="/app/data/go/pkg/mod" export GOCACHE="/app/data/go/cache" export GO111MODULE=on export GOFLAGS="-modfile=/app/data/go/go.mod -mod=mod" # Standard PostgreSQL environment variables (critical for Go's database/sql driver) export PGHOST="${CLOUDRON_POSTGRESQL_HOST}" export PGPORT="${CLOUDRON_POSTGRESQL_PORT}" export PGUSER="${CLOUDRON_POSTGRESQL_USERNAME}" export PGPASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}" export PGDATABASE="${CLOUDRON_POSTGRESQL_DATABASE}" export PGSSLMODE="disable" # Try to modify hosts file to block localhost PostgreSQL connections (may not work in containers) if [ -w /etc/hosts ]; then echo "==> Adding entry to /etc/hosts to redirect localhost PostgreSQL" echo "127.0.0.1 postgres-unavailable # Added by Ente startup script" >> /etc/hosts echo "::1 postgres-unavailable # Added by Ente startup script" >> /etc/hosts else echo "==> Cannot modify /etc/hosts (read-only filesystem)" fi # Create the overrides directory in writable location mkdir -p "/app/data/overrides" echo "==> Creating db_override.go in writable overrides directory" cat > "/app/data/overrides/db_override.go" < Created db_override.go in writable location: /app/data/overrides" # Patch source code directly for maximum effectiveness if [ -d "$SERVER_DIR/cmd/museum" ]; then MAIN_GO="$SERVER_DIR/cmd/museum/main.go" if [ -f "$MAIN_GO" ]; then echo "==> Patching main.go to force correct database host" # 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" "$WRITABLE_MAIN_GO" | cut -d: -f1) if [ -n "$DB_SETUP_LINE" ]; then echo "==> Found setupDatabase function at line $DB_SETUP_LINE" # Insert code at the beginning of the function 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}\")" "$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://" "$WRITABLE_MAIN_GO" | head -1 | cut -d: -f1) if [ -n "$CONN_STR_LINE" ]; then echo "==> Found connection string at line $CONN_STR_LINE" # Replace localhost or [::1] with the actual host 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 # Fix database migration state if needed echo "==> Checking database migration state" if [ -d "$SERVER_DIR/cmd/museum" ]; then echo "==> Attempting to fix dirty migration state" # Create migrations log directory mkdir -p /app/data/logs/migrations echo "==> Forcing migration version to 25" # Execute as the cloudron user but use a proper script instead of env cd cat > /tmp/run_migration.sh < /app/data/logs/migrations/force.log 2>&1; then echo "==> Successfully forced migration version" else echo "==> WARNING: Could not force migration version" echo "==> Migration force log:" cat /app/data/logs/migrations/force.log || echo "==> No migration log was created" fi else echo "==> Skipping migration state check: cmd/museum not found" fi # Start the Museum server with proper environment variables echo "==> Starting main Museum server" cd "$SERVER_DIR" # Check if there's a pre-built binary MUSEUM_BIN="" if [ -f "$SERVER_DIR/bin/museum" ] && [ -x "$SERVER_DIR/bin/museum" ]; then echo "==> Found Museum binary at $SERVER_DIR/bin/museum" MUSEUM_BIN="$SERVER_DIR/bin/museum" elif [ -f "/app/data/go/bin/museum" ] && [ -x "/app/data/go/bin/museum" ]; then echo "==> Found Museum binary at /app/data/go/bin/museum" MUSEUM_BIN="/app/data/go/bin/museum" fi # Start server if [ -n "$MUSEUM_BIN" ]; then echo "==> Starting Museum from binary: $MUSEUM_BIN" $MUSEUM_BIN serve > /app/data/logs/museum.log 2>&1 & SERVER_PID=$! elif [ -d "$SERVER_DIR/cmd/museum" ]; then echo "==> Starting Museum from source" # Create a startup script cat > /tmp/run_server.sh <> /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}'\" /app/data/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 \ GOCACHE="$GOCACHE" \ GOMODCACHE="$GOMODCACHE" \ GO111MODULE=on \ GOFLAGS="$GOFLAGS" \ MUSEUM_CONFIG="$MUSEUM_CONFIG" \ 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_server.sh > /app/data/logs/museum.log 2>&1 & SERVER_PID=$! else echo "==> ERROR: Museum server not found" echo "==> Starting a mock server" # Create a temporary directory for a simple Go server mkdir -p /tmp/mock-server cat > /tmp/mock-server/main.go < /app/data/logs/museum.log 2>&1 & SERVER_PID=$! echo "==> Mock server started with PID $SERVER_PID" fi 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://0.0.0.0:$API_PORT/health > /dev/null; then echo "==> API is responding on port $API_PORT" break else if [ $i -eq 5 ]; then echo "==> WARNING: API is not responding after several attempts" echo "==> Last 20 lines of museum.log:" tail -20 /app/data/logs/museum.log || echo "==> No museum.log available" else echo "==> Attempt $i: Waiting for API to start... (2 seconds)" sleep 2 fi 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}'\" /app/data/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 & CADDY_PID=$! echo "==> Caddy started with PID $CADDY_PID" # Wait a moment for Caddy to start sleep 2 # Test Caddy connectivity echo "==> Testing Caddy connectivity" for i in {1..5}; do 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 if [ $i -eq 5 ]; then echo "==> WARNING: Caddy is not responding after several attempts" echo "==> Check Caddy logs at /app/data/logs/caddy.log" else echo "==> Attempt $i: Waiting for Caddy to start... (1 second)" sleep 1 fi fi 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