Fix Caddy port configuration and improve connectivity testing

This commit is contained in:
Andreas Düren 2025-03-16 23:05:14 +01:00
parent 12b486ace3
commit 1c34047f75

467
start.sh
View File

@ -228,7 +228,173 @@ window.ENTE_CONFIG = {
console.log("Ente config loaded, API_URL =", window.ENTE_CONFIG.API_URL);
EOT
# Set up Caddy server
# Runtime configuration
echo "==> Setting up direct runtime configuration"
# Global API endpoint
API_ENDPOINT="${CLOUDRON_APP_ORIGIN}/api"
echo "==> Setting API endpoint to $API_ENDPOINT"
# Create runtime configuration files
mkdir -p /app/data/runtime
echo "==> Creating runtime configuration files"
# Create a config script
cat > /app/data/runtime/config.js <<EOT
// Direct configuration for Ente
window.ENTE_CONFIG = {
API_URL: "${API_ENDPOINT}"
};
// Next.js environment variables
window.process = window.process || {};
window.process.env = window.process.env || {};
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = "${API_ENDPOINT}";
window.process.env.REACT_APP_ENTE_ENDPOINT = "${API_ENDPOINT}";
window.process.env.VUE_APP_ENTE_ENDPOINT = "${API_ENDPOINT}";
console.log("Ente config loaded - API_URL:", window.ENTE_CONFIG.API_URL);
EOT
# First approach: Try to modify index.html files directly
echo "==> Attempting to directly modify web app HTML files"
WEB_APPS=("/app/web/photos" "/app/web/accounts" "/app/web/auth" "/app/web/cast")
for app_dir in "${WEB_APPS[@]}"; do
if [ -f "$app_dir/index.html" ]; then
echo "==> Processing $app_dir/index.html"
# Create a backup copy in our data directory
mkdir -p "/app/data/original/$(basename $app_dir)"
cp "$app_dir/index.html" "/app/data/original/$(basename $app_dir)/index.html"
# Create a modified version of the file in our data directory
mkdir -p "/app/data/modified/$(basename $app_dir)"
cp "$app_dir/index.html" "/app/data/modified/$(basename $app_dir)/index.html"
# Insert our configuration script into the head section
sed -i 's|</head>|<script src="/config.js"></script></head>|' "/app/data/modified/$(basename $app_dir)/index.html"
# Try to replace the original file (may fail if read-only)
if cp "/app/data/modified/$(basename $app_dir)/index.html" "$app_dir/index.html" 2>/dev/null; then
echo "==> Successfully modified $app_dir/index.html"
else
echo "==> Could not modify $app_dir/index.html (read-only filesystem)"
fi
else
echo "==> Skipping $app_dir - index.html not found"
fi
done
# Second approach: Create a modified copy that Caddy will serve
mkdir -p /app/data/public
cp /app/data/runtime/config.js /app/data/public/
echo "==> Created public configuration script"
# Create a loading page for each app with configuration
for app_name in "photos" "accounts" "auth" "cast"; do
cat > "/app/data/public/${app_name}-config.html" <<EOT
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Loading ${app_name}</title>
<script src="/debug.js"></script>
<script>
// Set the global configuration
window.ENTE_CONFIG = {
API_URL: "${API_ENDPOINT}"
};
// Set Next.js environment variables
window.process = window.process || {};
window.process.env = window.process.env || {};
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = "${API_ENDPOINT}";
// Store in localStorage as a fallback mechanism
localStorage.setItem('ENTE_CONFIG', JSON.stringify(window.ENTE_CONFIG));
localStorage.setItem('NEXT_PUBLIC_ENTE_ENDPOINT', "${API_ENDPOINT}");
// Log the configuration
console.log("Ente ${app_name} config loaded:", window.ENTE_CONFIG);
// Redirect to the main app after a brief delay
setTimeout(function() {
window.location.href = "/${app_name}/";
}, 100);
</script>
</head>
<body>
<h1>Loading ${app_name}...</h1>
<p>If you are not redirected automatically, <a href="/${app_name}/">click here</a>.</p>
<p><a href="/debug">Debug Information</a></p>
</body>
</html>
EOT
done
# Create root index.html that loads config and redirects
cat > /app/data/public/index.html <<EOT
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Ente</title>
<script src="/debug.js"></script>
<script>
// Define configuration globally
window.ENTE_CONFIG = {
API_URL: "${API_ENDPOINT}"
};
// Set environment variables for Next.js apps
window.process = window.process || {};
window.process.env = window.process.env || {};
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = "${API_ENDPOINT}";
// Store in localStorage as a fallback mechanism
localStorage.setItem('ENTE_CONFIG', JSON.stringify(window.ENTE_CONFIG));
localStorage.setItem('NEXT_PUBLIC_ENTE_ENDPOINT', "${API_ENDPOINT}");
// Redirect to photos app after a small delay to let the configuration load
setTimeout(function() {
window.location.href = "/photos/";
}, 100);
</script>
</head>
<body>
<h1>Loading Ente...</h1>
<p>You will be redirected automatically.</p>
<p><a href="/debug">Debug Information</a></p>
</body>
</html>
EOT
echo "==> Created special root index.html with configuration"
# Check port availability before starting services
echo "==> Checking port availability"
CADDY_PORT=3080
API_PORT=8080
# Check if ports are already in use
if lsof -i:$CADDY_PORT > /dev/null 2>&1; then
echo "==> WARNING: Port $CADDY_PORT is already in use"
echo "===> Process using port $CADDY_PORT:"
lsof -i:$CADDY_PORT
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"
echo "===> Process using port $API_PORT:"
lsof -i:$API_PORT
else
echo "==> Port $API_PORT is available for API server"
fi
# Set up Caddy
echo "==> Setting up Caddy server for web apps"
mkdir -p /app/data/caddy/public
cat > /app/data/caddy/Caddyfile <<EOT
@ -246,7 +412,7 @@ cat > /app/data/caddy/Caddyfile <<EOT
}
}
:8000 {
:3080 {
log {
output file /app/data/caddy/access.log {
roll_size 10MB
@ -284,6 +450,11 @@ cat > /app/data/caddy/Caddyfile <<EOT
respond "OK" 200
}
# Cloudron health check endpoint
handle /healthcheck {
respond "OK" 200
}
# Serve our custom config-injected landing pages
handle /photos-config {
root * /app/data/public
@ -356,285 +527,45 @@ EOT
echo "==> Caddy configuration created at /app/data/caddy/Caddyfile"
# Create HTML transformer script to modify all index.html files on load
mkdir -p /app/data/scripts
cat > /app/data/scripts/insert-config.sh <<EOT
#!/bin/bash
# This script injects our configuration into all index.html files
# List of web app directories
WEB_APPS=("/app/web/photos" "/app/web/accounts" "/app/web/auth" "/app/web/cast")
for app_dir in "\${WEB_APPS[@]}"; do
if [ -f "\$app_dir/index.html" ]; then
echo "Processing \$app_dir/index.html"
# Create a writable copy
cp "\$app_dir/index.html" "/app/data/temp.html"
# Insert our config script right before the closing head tag
sed -i 's|</head>|<script>window.ENTE_CONFIG = { API_URL: "${API_ENDPOINT}" };</script></head>|' "/app/data/temp.html"
# Create a symlink from the modified file to the original
# Only if the temp file was created and modified successfully
if [ -f "/app/data/temp.html" ]; then
mkdir -p "/app/data/transformed/\$(basename \$app_dir)"
cp "/app/data/temp.html" "/app/data/transformed/\$(basename \$app_dir)/index.html"
fi
fi
done
echo "All index.html files processed"
EOT
chmod +x /app/data/scripts/insert-config.sh
# Run the transformer script to create modified index.html files
mkdir -p /app/data/transformed
echo "==> Creating modified index.html files with injected configuration"
/app/data/scripts/insert-config.sh
# Create direct configuration files for different frameworks
mkdir -p /app/data/public
echo "==> Creating framework-specific configuration files"
# Create a Next.js public runtime configuration
cat > /app/data/public/env.js <<EOT
// Next.js runtime configuration
window.ENV = {
NEXT_PUBLIC_ENTE_ENDPOINT: "${API_ENDPOINT}"
};
window.process = window.process || {};
window.process.env = window.process.env || {};
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = "${API_ENDPOINT}";
EOT
# Create a simple JSON config
cat > /app/data/public/config.json <<EOT
{
"API_URL": "${API_ENDPOINT}"
}
EOT
# Create additional HTML files with the config directly embedded
for app_name in "photos" "accounts" "auth" "cast"; do
cat > "/app/data/public/${app_name}-config.html" <<EOT
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Loading ${app_name}</title>
<script src="/debug.js"></script>
<script>
// Set the global configuration
window.ENTE_CONFIG = {
API_URL: "${API_ENDPOINT}"
};
// Set Next.js environment variables
window.process = window.process || {};
window.process.env = window.process.env || {};
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = "${API_ENDPOINT}";
// Store in localStorage as a fallback mechanism
localStorage.setItem('ENTE_CONFIG', JSON.stringify(window.ENTE_CONFIG));
localStorage.setItem('NEXT_PUBLIC_ENTE_ENDPOINT', "${API_ENDPOINT}");
// Log the configuration
console.log("Ente ${app_name} config loaded:", window.ENTE_CONFIG);
// Redirect to the main app after a brief delay
setTimeout(function() {
window.location.href = "/${app_name}/";
}, 100);
</script>
</head>
<body>
<h1>Loading ${app_name}...</h1>
<p>If you are not redirected automatically, <a href="/${app_name}/">click here</a>.</p>
<p><a href="/debug">Debug Information</a></p>
</body>
</html>
EOT
done
echo "==> Created app-specific config loading pages with debug info"
# Looking for Museum (Go server component)
echo "==> Looking for Museum (Go server component)"
# Find the server directory - expanded search
SERVER_DIR=""
# Look in all the most likely places
if [ -d "/app/code/server" ]; then
echo "==> Found server directory at /app/code/server"
SERVER_DIR="/app/code/server"
elif [ -d "/app/code/museum" ]; then
echo "==> Found server directory at /app/code/museum"
SERVER_DIR="/app/code/museum"
fi
# If not found yet, try to find it based on Go files
if [ -z "$SERVER_DIR" ]; then
echo "==> Searching for Go server files in the repository"
# Look for cmd/museum path which is mentioned in docs
if find /app/code -path "*/cmd/museum" -type d | grep -q .; then
MUSEUM_DIR=$(find /app/code -path "*/cmd/museum" -type d | head -1)
echo "==> Found Museum command directory at $MUSEUM_DIR"
SERVER_DIR=$(dirname $(dirname "$MUSEUM_DIR"))
echo "==> Setting server directory to $SERVER_DIR"
# Look for main.go files in areas that might be server-related
elif find /app/code -name "main.go" -path "*/server*" | grep -q .; then
MAIN_GO=$(find /app/code -name "main.go" -path "*/server*" | head -1)
SERVER_DIR=$(dirname "$MAIN_GO")
echo "==> Found main.go in $SERVER_DIR"
# Look for any Go files with "museum" in the path
elif find /app/code -name "*.go" -path "*/museum*" | grep -q .; then
MUSEUM_GO=$(find /app/code -name "*.go" -path "*/museum*" | head -1)
SERVER_DIR=$(dirname "$MUSEUM_GO")
echo "==> Found Go file in museum directory: $SERVER_DIR"
# Last resort - look for any main.go file
elif find /app/code -name "main.go" | grep -v "test" | grep -q .; then
MAIN_GO=$(find /app/code -name "main.go" | grep -v "test" | head -1)
SERVER_DIR=$(dirname "$MAIN_GO")
echo "==> Found main.go as fallback: $SERVER_DIR"
fi
fi
# If still not found, check the 'cli' directory as it might be a client for the Museum
if [ -z "$SERVER_DIR" ] && [ -d "/app/code/cli" ]; then
echo "==> Checking CLI directory for Museum server code"
if find /app/code/cli -name "*.go" | grep -q .; then
SERVER_DIR="/app/code/cli"
echo "==> Using CLI directory as fallback for server: $SERVER_DIR"
fi
fi
# If all else fails, just use the root
if [ -z "$SERVER_DIR" ]; then
echo "==> WARNING: Could not find server directory with Go files"
echo "==> Using repository root as fallback"
SERVER_DIR="/app/code"
fi
echo "==> Selected server directory: $SERVER_DIR"
echo "==> Contents of $SERVER_DIR:"
ls -la "$SERVER_DIR"
# Check for server dependencies
echo "==> Installing Go dependencies"
if [ -x "$(command -v go)" ]; then
echo "==> Go is installed, version: $(go version)"
# Check go.mod version requirement and modify if needed
GO_VERSION=$(go version | cut -d " " -f 3 | sed 's/go//')
echo "==> Current Go version: $GO_VERSION"
if [ -f "$SERVER_DIR/go.mod" ]; then
REQUIRED_VERSION=$(grep -o "go [0-9]\+\.[0-9]\+" "$SERVER_DIR/go.mod" | cut -d " " -f 2)
echo "==> Required Go version: $REQUIRED_VERSION"
# Don't try to modify the go.mod file since filesystem is read-only
# Instead, use environment variables to override version requirements
echo "==> Setting Go flags to override version requirements"
export GOFLAGS="-modfile=/app/data/go/go.mod -mod=mod"
export GO111MODULE=on
export GOTOOLCHAIN=local
fi
else
echo "==> Installing Go"
apt-get update && apt-get install -y golang
fi
# Skip trying to install specific Go versions since we can't modify /app/code
echo "==> Using existing Go toolchain with compatibility flags"
# Check for libsodium
if dpkg -l | grep -q libsodium; then
echo "==> libsodium is installed"
else
echo "==> Installing libsodium"
apt-get update && apt-get install -y libsodium23 libsodium-dev
fi
# Check for pkg-config
if [ -x "$(command -v pkg-config)" ]; then
echo "==> pkg-config is installed"
else
echo "==> Installing pkg-config"
apt-get update && apt-get install -y pkg-config
fi
# Change to server directory
cd "$SERVER_DIR"
# Set Go module cache to a writable location
export GOPATH=/app/data/go
export GO111MODULE=on
# Use local toolchain to avoid downloading required version
export GOTOOLCHAIN=local
# Ensure go.mod is in the writable directory
if [ ! -f "/app/data/go/go.mod" ] && [ -f "$SERVER_DIR/go.mod" ]; then
echo "==> Copying go.mod and go.sum to writable location"
mkdir -p /app/data/go
cp -f "$SERVER_DIR/go.mod" "$SERVER_DIR/go.sum" /app/data/go/ || echo "==> Warning: Could not copy go.mod/go.sum"
chmod 666 /app/data/go/go.mod /app/data/go/go.sum || echo "==> Warning: Could not set permissions"
fi
# Create proper directories with correct permissions
mkdir -p /app/data/go/cache /app/data/go/pkg/mod /app/data/go/bin
chmod -R 777 /app/data/go
chown -R cloudron:cloudron /app/data/go
# Override version requirements and force module mode
export GOFLAGS="-modfile=/app/data/go/go.mod -mod=mod -modcacherw"
# Create a temporary directory for Go module cache and build in writable area
export GOCACHE=/app/data/go/cache
export GOMODCACHE=/app/data/go/pkg/mod
mkdir -p $GOCACHE $GOMODCACHE
echo "==> Set up Go environment in writable directories"
# Set up more verbose logging for API debugging
export ENTE_LOG_LEVEL=debug
# Start Caddy first before the Museum server to ensure port 3080 is available for health checks
echo "==> Setting up Caddy before starting the Museum server"
echo "==> Caddy will be listening on port 3080"
echo "==> Testing if port 3080 is already in use"
if netstat -tuln | grep -q ":3080 "; then
echo "==> WARNING: Port 3080 is already in use, Caddy may fail to start"
netstat -tuln | grep ":3080 "
else
echo "==> Port 3080 is available"
fi
echo "==> Caddy will be listening on port $CADDY_PORT"
# Only set permissions on the Caddy directory, not the web directory which is read-only
mkdir -p /app/data/caddy/logs
chmod -R 755 /app/data/caddy
mkdir -p /app/data/caddy
chmod -R 777 /app/data/caddy
chown -R cloudron:cloudron /app/data/caddy
# Start Caddy
echo "==> Starting Caddy"
# Start Caddy server
echo "==> Starting Caddy server..."
caddy run --config /app/data/caddy/Caddyfile --adapter caddyfile &
CADDY_PID=$!
echo "==> Caddy started with PID $CADDY_PID"
# Check if Caddy started successfully
# Wait a moment for Caddy to start
sleep 2
if ! ps -p $CADDY_PID > /dev/null; then
echo "==> ERROR: Caddy failed to start"
echo "==> Any logs available:"
if [ -f "/app/data/caddy/caddy.log" ]; then
cat /app/data/caddy/caddy.log
# Test Caddy connectivity
echo "==> Testing Caddy connectivity on port $CADDY_PORT"
for i in {1..5}; do
if curl -s --max-time 2 --head --fail http://localhost:$CADDY_PORT/health > /dev/null; then
echo "==> Caddy is running properly on port $CADDY_PORT"
break
else
echo "No Caddy logs available yet"
if [ $i -eq 5 ]; then
echo "==> Failed to connect to Caddy on port $CADDY_PORT after multiple attempts"
echo "==> Last 20 lines of Caddy log:"
tail -20 /app/data/caddy/caddy.log || echo "==> No Caddy log available"
echo "==> Network ports in use:"
netstat -tuln || echo "==> netstat command not available"
echo "==> Processes listening on ports:"
lsof -i -P -n | grep LISTEN || echo "==> lsof command not available"
else
echo "==> Attempt $i: Waiting for Caddy to start... (1 second)"
sleep 1
fi
fi
else
echo "==> Caddy is running properly on port 3080"
echo "==> Testing Caddy connectivity"
curl -v http://localhost:3080/healthcheck || echo "==> Failed to connect to Caddy"
fi
done
# Determine available memory and set limits accordingly
if [[ -f /sys/fs/cgroup/cgroup.controllers ]]; then # cgroup v2