Fix Go module structure for mock servers to resolve build issues

This commit is contained in:
Andreas Düren 2025-03-18 21:52:41 +01:00
parent c00be35fc7
commit 50a19a7908

803
start.sh
View File

@ -1068,7 +1068,13 @@ else
# Create a temporary directory for a simple Go server # Create a temporary directory for a simple Go server
mkdir -p /tmp/mock-server mkdir -p /tmp/mock-server
cat > /tmp/mock-server/main.go <<"GOMOCK" cd /tmp/mock-server
# Initialize a proper Go module
go mod init mock-server
# Write the program to a file
cat > main.go << 'GOMOCK'
package main package main
import ( import (
@ -1177,6 +1183,16 @@ func main() {
"ott": verificationCode, "ott": verificationCode,
"exp": time.Now().Add(time.Hour).Unix(), "exp": time.Now().Add(time.Hour).Unix(),
"email": email, "email": email,
"createdAt": time.Now().Format(time.RFC3339),
"updatedAt": time.Now().Format(time.RFC3339),
"key": map[string]interface{}{
"pubKey": "mockPubKey123456",
"encPubKey": "mockEncPubKey123456",
"kty": "mockKty",
"kid": "mockKid",
"alg": "mockAlg",
"verifyKey": "mockVerifyKey123456",
},
} }
json.NewEncoder(w).Encode(jsonResponse) json.NewEncoder(w).Encode(jsonResponse)
} else { } else {
@ -1440,16 +1456,15 @@ func main() {
GOMOCK GOMOCK
# Unset any module-related flags before running standalone Go program # Unset any module-related flags before running standalone Go program
echo "==> Unsetting module flags before building mock server"
unset GO111MODULE unset GO111MODULE
unset GOFLAGS unset GOFLAGS
unset GOMODCACHE
# Build and run the mock server in the background # Build and run the mock server in the background
echo "==> Building and starting mock API server on port 8080" echo "==> Building and starting mock API server on port 8080"
# Make sure we're using Go 1.24.1 for the build if go build -o mock_server; then
export PATH="/usr/local/go/bin:${PATH}"
if go build -o mock_server main.go; then
echo "==> Successfully compiled mock API server" echo "==> Successfully compiled mock API server"
# Create log directory if it doesn't exist # Create log directory if it doesn't exist
@ -1486,10 +1501,12 @@ GOMOCK
echo "==> ERROR: Failed to build mock API server" echo "==> ERROR: Failed to build mock API server"
# Print Go version for debugging # Print Go version for debugging
go version go version
# Set a bogus server PID to prevent unbound variable error
SERVER_PID=0
fi fi
fi fi
echo "==> Server started with PID $SERVER_PID" echo "==> Server started with PID ${SERVER_PID:-0}"
# Test if API is responding # Test if API is responding
echo "==> Testing API connectivity" echo "==> Testing API connectivity"
@ -1525,7 +1542,12 @@ elif [ -d "$SERVER_DIR/cmd/museum" ]; then
# Create a startup script but don't use module flags # Create a startup script but don't use module flags
echo "==> Creating mock Public Albums API server" echo "==> Creating mock Public Albums API server"
mkdir -p /tmp/mock-public-server mkdir -p /tmp/mock-public-server
cat > /tmp/mock-public-server/main.go <<"EOT" cd /tmp/mock-public-server
# Initialize a proper Go module
go mod init mock-public-server
cat > main.go <<"EOT"
package main package main
import ( import (
@ -1619,51 +1641,62 @@ func main() {
} }
EOT EOT
# Unset any module-related flags before running standalone Go program # Unset any module-related flags before running standalone Go program
unset GO111MODULE echo "==> Unsetting module flags before building public albums mock server"
unset GOFLAGS unset GO111MODULE
unset GOFLAGS
unset GOMODCACHE
# Build and run the public albums mock server # Build and run the public albums mock server
echo "==> Building and starting Public Albums mock server on port 8081" echo "==> Building and starting Public Albums mock server on port 8081"
cd /tmp/mock-public-server if go build -o mock_public_server; then
if go build -o mock_public_server main.go; then echo "==> Successfully compiled Public Albums mock server"
echo "==> Successfully compiled Public Albums mock server" # Start the server and log both to file and to console
# Start the server and log both to file and to console chmod +x ./mock_public_server
nohup ./mock_public_server > /app/data/logs/mock_public_server.log 2>&1 & nohup ./mock_public_server > /app/data/logs/mock_public_server.log 2>&1 &
PUBLIC_SERVER_PID=$! PUBLIC_SERVER_PID=$!
echo "==> Public Albums mock server started with PID $PUBLIC_SERVER_PID" echo "==> Public Albums mock server started with PID $PUBLIC_SERVER_PID"
# Wait to ensure the server is up # Wait to ensure the server is up
echo "==> Waiting for Public Albums server to start..." echo "==> Waiting for Public Albums server to start..."
sleep 2 sleep 3
# Check if the server is actually running # Check if the server is actually running
if ps -p $PUBLIC_SERVER_PID > /dev/null; then if ps -p $PUBLIC_SERVER_PID > /dev/null; then
echo "==> Public Albums mock server is running with PID $PUBLIC_SERVER_PID" echo "==> Public Albums mock server is running with PID $PUBLIC_SERVER_PID"
# Check if the port is actually listening # Check if the port is actually listening
if netstat -tulpn 2>/dev/null | grep ":8081" > /dev/null; then if netstat -tulpn 2>/dev/null | grep ":8081" > /dev/null; then
echo "==> Public Albums mock server is listening on port 8081" echo "==> Public Albums mock server is listening on port 8081"
else
echo "==> WARNING: Public Albums mock server doesn't appear to be listening on port 8081"
echo "==> Checking server logs:"
tail -n 20 /app/data/logs/mock_public_server.log
fi
else else
echo "==> WARNING: Public Albums mock server doesn't appear to be listening on port 8081" echo "==> ERROR: Public Albums mock server failed to start"
echo "==> Checking server logs:" echo "==> Server log:"
tail -n 10 /app/data/logs/mock_public_server.log cat /app/data/logs/mock_public_server.log
fi fi
else else
echo "==> ERROR: Public Albums mock server failed to start" echo "==> ERROR: Failed to build Public Albums mock server"
echo "==> Server log:" # Print Go version for debugging
cat /app/data/logs/mock_public_server.log go version
# Set a fallback value for PUBLIC_SERVER_PID
PUBLIC_SERVER_PID=0
fi fi
else else
echo "==> ERROR: Failed to build Public Albums mock server" echo "==> ERROR: Museum server not found for public albums"
fi echo "==> Starting a mock public albums server"
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 # Create a temporary directory for a simple Go server
mkdir -p /tmp/mock-public-server mkdir -p /tmp/mock-public-server
cat > /tmp/mock-public-server/main.go <<"EOT" cd /tmp/mock-public-server
# Initialize a proper Go module
go mod init mock-public-server
cat > main.go <<"EOT"
package main package main
import ( import (
@ -1757,129 +1790,135 @@ func main() {
} }
EOT EOT
# Unset any module-related flags before running standalone Go program # Unset any module-related flags before running standalone Go program
unset GO111MODULE echo "==> Unsetting module flags before building public albums mock server"
unset GOFLAGS unset GO111MODULE
unset GOFLAGS
unset GOMODCACHE
# Build and run the public albums mock server # Build and run the public albums mock server
echo "==> Building and starting Public Albums mock server on port 8081" echo "==> Building and starting Public Albums mock server on port 8081"
cd /tmp/mock-public-server if go build -o mock_public_server; then
if go build -o mock_public_server main.go; then echo "==> Successfully compiled Public Albums mock server"
echo "==> Successfully compiled Public Albums mock server" # Start the server and log both to file and to console
# Start the server and log both to file and to console chmod +x ./mock_public_server
nohup ./mock_public_server > /app/data/logs/mock_public_server.log 2>&1 & nohup ./mock_public_server > /app/data/logs/mock_public_server.log 2>&1 &
PUBLIC_SERVER_PID=$! PUBLIC_SERVER_PID=$!
echo "==> Public Albums mock server started with PID $PUBLIC_SERVER_PID" echo "==> Public Albums mock server started with PID $PUBLIC_SERVER_PID"
# Wait to ensure the server is up # Wait to ensure the server is up
echo "==> Waiting for Public Albums server to start..." echo "==> Waiting for Public Albums server to start..."
sleep 2 sleep 3
# Check if the server is actually running # Check if the server is actually running
if ps -p $PUBLIC_SERVER_PID > /dev/null; then if ps -p $PUBLIC_SERVER_PID > /dev/null; then
echo "==> Public Albums mock server is running with PID $PUBLIC_SERVER_PID" echo "==> Public Albums mock server is running with PID $PUBLIC_SERVER_PID"
# Check if the port is actually listening # Check if the port is actually listening
if netstat -tulpn 2>/dev/null | grep ":8081" > /dev/null; then if netstat -tulpn 2>/dev/null | grep ":8081" > /dev/null; then
echo "==> Public Albums mock server is listening on port 8081" echo "==> Public Albums mock server is listening on port 8081"
else
echo "==> WARNING: Public Albums mock server doesn't appear to be listening on port 8081"
echo "==> Checking server logs:"
tail -n 20 /app/data/logs/mock_public_server.log
fi
else else
echo "==> WARNING: Public Albums mock server doesn't appear to be listening on port 8081" echo "==> ERROR: Public Albums mock server failed to start"
echo "==> Checking server logs:" echo "==> Server log:"
tail -n 10 /app/data/logs/mock_public_server.log cat /app/data/logs/mock_public_server.log
fi fi
else else
echo "==> ERROR: Public Albums mock server failed to start" echo "==> ERROR: Failed to build Public Albums mock server"
echo "==> Server log:" # Print Go version for debugging
cat /app/data/logs/mock_public_server.log go version
# Set a fallback value for PUBLIC_SERVER_PID
PUBLIC_SERVER_PID=0
fi fi
else
echo "==> ERROR: Failed to build Public Albums mock server"
fi fi
fi
echo "==> Public Albums server started with PID $PUBLIC_SERVER_PID" echo "==> Public Albums server started with PID ${PUBLIC_SERVER_PID:-0}"
# Test if Public Albums API is responding # Test if Public Albums API is responding
echo "==> Testing Public Albums API connectivity" echo "==> Testing Public Albums API connectivity"
for i in {1..5}; do 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 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" echo "==> Public Albums API is responding on port $PUBLIC_ALBUMS_PORT"
break 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 else
echo "==> Attempt $i: Waiting for Public Albums API to start... (2 seconds)" if [ $i -eq 5 ]; then
sleep 2 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 fi
fi done
done
# Set up Caddy web server # Set up Caddy web server
echo "==> Setting up Caddy web server" echo "==> Setting up Caddy web server"
# Create a simpler approach for injecting configuration # Create a simpler approach for injecting configuration
echo "==> Creating a static HTML file with config scripts already included" echo "==> Creating a static HTML file with config scripts already included"
# Create runtime-config.js files in writable locations # Create runtime-config.js files in writable locations
echo "==> Creating runtime-config.js in writable location" echo "==> Creating runtime-config.js in writable location"
mkdir -p /app/data/web mkdir -p /app/data/web
cat > /app/data/web/runtime-config.js <<EOT cat > /app/data/web/runtime-config.js <<EOT
// Runtime configuration for Ente // Runtime configuration for Ente
window.ENTE_CONFIG = { window.ENTE_CONFIG = {
API_URL: '${API_ENDPOINT}', API_URL: '${API_ENDPOINT}',
PUBLIC_ALBUMS_URL: '${CLOUDRON_APP_ORIGIN}/public' PUBLIC_ALBUMS_URL: '${CLOUDRON_APP_ORIGIN}/public'
}; };
// Next.js environment variables // Next.js environment variables
window.process = window.process || {}; window.process = window.process || {};
window.process.env = window.process.env || {}; window.process.env = window.process.env || {};
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = '${API_ENDPOINT}'; window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = '${API_ENDPOINT}';
window.process.env.NEXT_PUBLIC_ENTE_PUBLIC_ALBUMS_ENDPOINT = '${CLOUDRON_APP_ORIGIN}/public'; window.process.env.NEXT_PUBLIC_ENTE_PUBLIC_ALBUMS_ENDPOINT = '${CLOUDRON_APP_ORIGIN}/public';
window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT = '${API_ENDPOINT}'; window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT = '${API_ENDPOINT}';
window.process.env.REACT_APP_ENTE_ENDPOINT = '${API_ENDPOINT}'; window.process.env.REACT_APP_ENTE_ENDPOINT = '${API_ENDPOINT}';
// Make sure all URLs are properly formatted for URL constructor // Make sure all URLs are properly formatted for URL constructor
if (!window.ENTE_CONFIG.API_URL.startsWith('http')) { if (!window.ENTE_CONFIG.API_URL.startsWith('http')) {
console.log('Adding https:// prefix to API_URL'); console.log('Adding https:// prefix to API_URL');
window.ENTE_CONFIG.API_URL = window.location.origin + window.ENTE_CONFIG.API_URL; window.ENTE_CONFIG.API_URL = window.location.origin + window.ENTE_CONFIG.API_URL;
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = window.location.origin + window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT; window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = window.location.origin + window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT;
window.process.env.REACT_APP_ENTE_ENDPOINT = window.location.origin + window.process.env.REACT_APP_ENTE_ENDPOINT; window.process.env.REACT_APP_ENTE_ENDPOINT = window.location.origin + window.process.env.REACT_APP_ENTE_ENDPOINT;
window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT = window.location.origin + window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT; window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT = window.location.origin + window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT;
} }
console.log('Ente runtime config loaded from runtime-config.js'); console.log('Ente runtime config loaded from runtime-config.js');
console.log('API_URL:', window.ENTE_CONFIG.API_URL); console.log('API_URL:', window.ENTE_CONFIG.API_URL);
console.log('PUBLIC_ALBUMS_URL:', window.ENTE_CONFIG.PUBLIC_ALBUMS_URL); console.log('PUBLIC_ALBUMS_URL:', window.ENTE_CONFIG.PUBLIC_ALBUMS_URL);
EOT EOT
# Ensure runtime-config.js is readable # Ensure runtime-config.js is readable
chmod 644 /app/data/web/runtime-config.js chmod 644 /app/data/web/runtime-config.js
# Create the static HTML files with scripts pre-injected # Create the static HTML files with scripts pre-injected
for app_dir in photos accounts auth cast; do for app_dir in photos accounts auth cast; do
# Create directory for our modified files # Create directory for our modified files
mkdir -p /app/data/web/$app_dir mkdir -p /app/data/web/$app_dir
# If the original index.html exists, copy and modify it # If the original index.html exists, copy and modify it
if [ -f "/app/web/$app_dir/index.html" ]; then if [ -f "/app/web/$app_dir/index.html" ]; then
echo "==> Copying and modifying index.html for $app_dir app" echo "==> Copying and modifying index.html for $app_dir app"
cp "/app/web/$app_dir/index.html" "/app/data/web/$app_dir/index.html" cp "/app/web/$app_dir/index.html" "/app/data/web/$app_dir/index.html"
# Fix any potential issues with the head tag # Fix any potential issues with the head tag
if ! grep -q "<head>" "/app/data/web/$app_dir/index.html"; then if ! grep -q "<head>" "/app/data/web/$app_dir/index.html"; then
echo "==> Warning: No head tag found in $app_dir/index.html, adding one" echo "==> Warning: No head tag found in $app_dir/index.html, adding one"
sed -i 's/<html>/<html>\n<head><\/head>/' "/app/data/web/$app_dir/index.html" sed -i 's/<html>/<html>\n<head><\/head>/' "/app/data/web/$app_dir/index.html"
fi fi
# Insert config scripts right after the opening head tag, unescaped # Insert config scripts right after the opening head tag, unescaped
sed -i 's/<head>/<head>\n <script src="\/config.js" type="text\/javascript"><\/script>\n <script src="\/runtime-config.js" type="text\/javascript"><\/script>/' "/app/data/web/$app_dir/index.html" sed -i 's/<head>/<head>\n <script src="\/config.js" type="text\/javascript"><\/script>\n <script src="\/runtime-config.js" type="text\/javascript"><\/script>/' "/app/data/web/$app_dir/index.html"
else else
# Create a minimal HTML file with the scripts included but pointing to the original app # Create a minimal HTML file with the scripts included but pointing to the original app
echo "==> Creating minimal pre-configured index.html for $app_dir app with redirect" echo "==> Creating minimal pre-configured index.html for $app_dir app with redirect"
cat > "/app/data/web/$app_dir/index.html" <<HTML cat > "/app/data/web/$app_dir/index.html" <<HTML
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
@ -1895,292 +1934,292 @@ for app_dir in photos accounts auth cast; do
</body> </body>
</html> </html>
HTML HTML
fi fi
done done
# Modify the Caddyfile to serve our modified HTML files # Modify the Caddyfile to serve our modified HTML files
cat > /app/data/caddy/Caddyfile <<EOT cat > /app/data/caddy/Caddyfile <<EOT
# Global settings # Global settings
{ {
admin off admin off
auto_https off auto_https off
http_port $CADDY_PORT http_port $CADDY_PORT
https_port 0 https_port 0
}
# Main site configuration
:$CADDY_PORT {
# Basic logging
log {
level INFO
output file /app/data/logs/caddy.log
} }
# Configuration scripts - directly served # Main site configuration
handle /config.js { :$CADDY_PORT {
header Content-Type application/javascript # Basic logging
respond " log {
// Direct configuration for Ente level INFO
window.ENTE_CONFIG = { output file /app/data/logs/caddy.log
API_URL: '${API_ENDPOINT}', }
PUBLIC_ALBUMS_URL: '${CLOUDRON_APP_ORIGIN}/public'
};
// Next.js environment variables # Configuration scripts - directly served
window.process = window.process || {}; handle /config.js {
window.process.env = window.process.env || {}; header Content-Type application/javascript
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = '${API_ENDPOINT}'; respond "
window.process.env.NEXT_PUBLIC_ENTE_PUBLIC_ALBUMS_ENDPOINT = '${CLOUDRON_APP_ORIGIN}/public'; // Direct configuration for Ente
window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT = '${API_ENDPOINT}'; window.ENTE_CONFIG = {
window.process.env.REACT_APP_ENTE_ENDPOINT = '${API_ENDPOINT}'; API_URL: '${API_ENDPOINT}',
PUBLIC_ALBUMS_URL: '${CLOUDRON_APP_ORIGIN}/public'
};
// Make sure all URLs are properly formatted for URL constructor // Next.js environment variables
if (!window.ENTE_CONFIG.API_URL.startsWith('http')) { window.process = window.process || {};
console.log('Adding https:// prefix to API_URL'); window.process.env = window.process.env || {};
window.ENTE_CONFIG.API_URL = window.location.origin + window.ENTE_CONFIG.API_URL; window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = '${API_ENDPOINT}';
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = window.location.origin + window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT; window.process.env.NEXT_PUBLIC_ENTE_PUBLIC_ALBUMS_ENDPOINT = '${CLOUDRON_APP_ORIGIN}/public';
window.process.env.REACT_APP_ENTE_ENDPOINT = window.location.origin + window.process.env.REACT_APP_ENTE_ENDPOINT; window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT = '${API_ENDPOINT}';
window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT = window.location.origin + window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT; window.process.env.REACT_APP_ENTE_ENDPOINT = '${API_ENDPOINT}';
// Make sure all URLs are properly formatted for URL constructor
if (!window.ENTE_CONFIG.API_URL.startsWith('http')) {
console.log('Adding https:// prefix to API_URL');
window.ENTE_CONFIG.API_URL = window.location.origin + window.ENTE_CONFIG.API_URL;
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = window.location.origin + window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT;
window.process.env.REACT_APP_ENTE_ENDPOINT = window.location.origin + window.process.env.REACT_APP_ENTE_ENDPOINT;
window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT = window.location.origin + window.process.env.NEXT_PUBLIC_REACT_APP_ENTE_ENDPOINT;
}
console.log('Ente config loaded - API_URL:', window.ENTE_CONFIG.API_URL);
console.log('Ente config loaded - PUBLIC_ALBUMS_URL:', window.ENTE_CONFIG.PUBLIC_ALBUMS_URL);
"
}
handle /runtime-config.js {
root * /app/data/web
file_server
}
# Root path serves the photos app
handle / {
# Special handling for index.html
@is_index path /
handle @is_index {
root * /app/data/web/photos
try_files {path} /index.html
file_server
} }
console.log('Ente config loaded - API_URL:', window.ENTE_CONFIG.API_URL); # Serve other static files from the original location
console.log('Ente config loaded - PUBLIC_ALBUMS_URL:', window.ENTE_CONFIG.PUBLIC_ALBUMS_URL); @not_index {
" not path /
} not path /api/*
not path /public/*
handle /runtime-config.js { not path /accounts/*
root * /app/data/web not path /auth/*
file_server not path /cast/*
} }
handle @not_index {
# Root path serves the photos app root * /app/web/photos
handle / { try_files {path} /index.html
# Special handling for index.html file_server
@is_index path / }
handle @is_index {
root * /app/data/web/photos
try_files {path} /index.html
file_server
} }
# Serve other static files from the original location # Next.js static files
@not_index { handle /_next/* {
not path /
not path /api/*
not path /public/*
not path /accounts/*
not path /auth/*
not path /cast/*
}
handle @not_index {
root * /app/web/photos root * /app/web/photos
file_server
}
# Add global headers for common file types
header /*.js Content-Type application/javascript
header /*.css Content-Type text/css
header /*.json Content-Type application/json
header /*.svg Content-Type image/svg+xml
header /*.woff2 Content-Type font/woff2
header /_next/static/chunks/*.js Content-Type application/javascript
header /_next/static/css/*.css Content-Type text/css
# Accounts app
handle /accounts {
root * /app/data/web/accounts
try_files {path} /index.html try_files {path} /index.html
file_server file_server
} }
}
# Next.js static files handle /accounts/* {
handle /_next/* { @is_index path /accounts/ /accounts/index.html
root * /app/web/photos handle @is_index {
file_server root * /app/data/web
} try_files /accounts/index.html
file_server
}
# Add global headers for common file types @not_index {
header /*.js Content-Type application/javascript not path /accounts/
header /*.css Content-Type text/css not path /accounts/index.html
header /*.json Content-Type application/json }
header /*.svg Content-Type image/svg+xml handle @not_index {
header /*.woff2 Content-Type font/woff2 uri strip_prefix /accounts
header /_next/static/chunks/*.js Content-Type application/javascript root * /app/web/accounts
header /_next/static/css/*.css Content-Type text/css try_files {path} /index.html
file_server
# Accounts app }
handle /accounts {
root * /app/data/web/accounts
try_files {path} /index.html
file_server
}
handle /accounts/* {
@is_index path /accounts/ /accounts/index.html
handle @is_index {
root * /app/data/web
try_files /accounts/index.html
file_server
} }
@not_index { # Auth app
not path /accounts/ handle /auth {
not path /accounts/index.html root * /app/data/web/auth
}
handle @not_index {
uri strip_prefix /accounts
root * /app/web/accounts
try_files {path} /index.html try_files {path} /index.html
file_server file_server
} }
}
# Auth app handle /auth/* {
handle /auth { @is_index path /auth/ /auth/index.html
root * /app/data/web/auth handle @is_index {
try_files {path} /index.html root * /app/data/web
file_server try_files /auth/index.html
} file_server
}
handle /auth/* { @not_index {
@is_index path /auth/ /auth/index.html not path /auth/
handle @is_index { not path /auth/index.html
root * /app/data/web }
try_files /auth/index.html handle @not_index {
file_server uri strip_prefix /auth
root * /app/web/auth
try_files {path} /index.html
file_server
}
} }
@not_index { # Cast app
not path /auth/ handle /cast {
not path /auth/index.html root * /app/data/web/cast
}
handle @not_index {
uri strip_prefix /auth
root * /app/web/auth
try_files {path} /index.html try_files {path} /index.html
file_server file_server
} }
}
# Cast app handle /cast/* {
handle /cast { @is_index path /cast/ /cast/index.html
root * /app/data/web/cast handle @is_index {
try_files {path} /index.html root * /app/data/web
file_server try_files /cast/index.html
} file_server
}
handle /cast/* { @not_index {
@is_index path /cast/ /cast/index.html not path /cast/
handle @is_index { not path /cast/index.html
root * /app/data/web }
try_files /cast/index.html handle @not_index {
file_server uri strip_prefix /cast
root * /app/web/cast
try_files {path} /index.html
file_server
}
} }
@not_index { # Main API proxy
not path /cast/ handle /api/* {
not path /cast/index.html uri strip_prefix /api
reverse_proxy 0.0.0.0:$API_PORT
} }
handle @not_index {
uri strip_prefix /cast # Public albums API proxy
root * /app/web/cast handle /public/* {
try_files {path} /index.html uri strip_prefix /public
file_server reverse_proxy 0.0.0.0:$PUBLIC_ALBUMS_PORT
}
# Health check endpoints
handle /health {
respond "OK"
}
handle /healthcheck {
respond "OK"
}
handle /api/health {
uri strip_prefix /api
reverse_proxy 0.0.0.0:$API_PORT
}
handle /public/health {
uri strip_prefix /public
reverse_proxy 0.0.0.0:$PUBLIC_ALBUMS_PORT
} }
} }
EOT
# Main API proxy echo "==> Created Caddy config with properly modified HTML files at /app/data/caddy/Caddyfile"
handle /api/* {
uri strip_prefix /api
reverse_proxy 0.0.0.0:$API_PORT
}
# Public albums API proxy # Start Caddy server
handle /public/* { echo "==> Starting Caddy server"
uri strip_prefix /public
reverse_proxy 0.0.0.0:$PUBLIC_ALBUMS_PORT
}
# Health check endpoints caddy start --config /app/data/caddy/Caddyfile --adapter caddyfile &
handle /health { CADDY_PID=$!
respond "OK" echo "==> Caddy started with PID $CADDY_PID"
}
handle /healthcheck { # Wait a moment for Caddy to start
respond "OK" sleep 2
}
handle /api/health { # Test Caddy connectivity
uri strip_prefix /api echo "==> Testing Caddy connectivity"
reverse_proxy 0.0.0.0:$API_PORT 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"
handle /public/health { break
uri strip_prefix /public
reverse_proxy 0.0.0.0:$PUBLIC_ALBUMS_PORT
}
}
EOT
echo "==> Created Caddy config with properly modified HTML files 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 else
echo "==> Attempt $i: Waiting for Caddy to start... (1 second)" if [ $i -eq 5 ]; then
sleep 1 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 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 fi
done
echo "==> Application is now running" echo "==> Testing public albums API communication"
echo "==> Access your Ente instance at: $CLOUDRON_APP_ORIGIN" 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
# Check communication between frontend and backend services echo "==> Testing frontend config.js"
echo "==> Checking communication between frontend and backend services" CONFIG_JS_TEST=$(curl -s --max-time 2 http://0.0.0.0:$CADDY_PORT/config.js)
echo "==> Testing main API communication" if [[ "$CONFIG_JS_TEST" == *"API_URL"* && "$CONFIG_JS_TEST" == *"PUBLIC_ALBUMS_URL"* ]]; then
MAIN_API_TEST=$(curl -s --max-time 2 http://0.0.0.0:$CADDY_PORT/api/health) echo "==> Frontend configuration is properly loaded"
if [ $? -eq 0 ]; then else
echo "==> Main API communication via frontend is working" echo "==> WARNING: Frontend configuration is not properly loaded"
else echo "==> Response: $CONFIG_JS_TEST"
echo "==> WARNING: Main API communication via frontend is NOT working" fi
echo "==> Response: $MAIN_API_TEST"
fi
echo "==> Testing public albums API communication" echo "==> Entering wait state - watching logs for registration codes"
PUBLIC_API_TEST=$(curl -s --max-time 2 http://0.0.0.0:$CADDY_PORT/public/health) echo "==> Registration verification codes will appear in the logs below"
if [ $? -eq 0 ]; then echo "==> Press Ctrl+C to stop"
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" # Set up a tail process to show logs in real-time while maintaining the wait state
CONFIG_JS_TEST=$(curl -s --max-time 2 http://0.0.0.0:$CADDY_PORT/config.js) tail -f /app/data/logs/api_requests.log &
if [[ "$CONFIG_JS_TEST" == *"API_URL"* && "$CONFIG_JS_TEST" == *"PUBLIC_ALBUMS_URL"* ]]; then TAIL_PID=$!
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 - watching logs for registration codes" # Trap to kill the tail process when the script exits
echo "==> Registration verification codes will appear in the logs below" trap 'kill -TERM $TAIL_PID; kill -TERM $SERVER_PID; kill -TERM $PUBLIC_SERVER_PID; kill -TERM $CADDY_PID; exit' TERM INT
echo "==> Press Ctrl+C to stop"
# Set up a tail process to show logs in real-time while maintaining the wait state # Wait for all processes
tail -f /app/data/logs/api_requests.log & wait $SERVER_PID
TAIL_PID=$! wait $PUBLIC_SERVER_PID
wait $CADDY_PID
# Trap to kill the tail process when the script exits
trap 'kill -TERM $TAIL_PID; kill -TERM $SERVER_PID; kill -TERM $PUBLIC_SERVER_PID; kill -TERM $CADDY_PID; exit' TERM INT
# Wait for all processes
wait $SERVER_PID
wait $PUBLIC_SERVER_PID
wait $CADDY_PID