diff --git a/CloudronManifest.json b/CloudronManifest.json index 7856c4a..fce23da 100644 --- a/CloudronManifest.json +++ b/CloudronManifest.json @@ -7,7 +7,7 @@ "contactEmail": "contact@ente.io", "tagline": "Open Source End-to-End Encrypted Photos & Authentication", "upstreamVersion": "1.0.0", - "version": "0.1.69", + "version": "0.1.78", "healthCheckPath": "/ping", "httpPort": 3080, "memoryLimit": 1073741824, diff --git a/Dockerfile b/Dockerfile index 5b2655f..6ab2ec0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,21 +27,9 @@ RUN apt-get update && apt-get install -y git && \ # Will help default to yarn version 1.22.22 RUN corepack enable -# Set environment variables for web app build -# Instead of using a relative path, patch the origins.ts file to use dynamic origin -RUN echo "Patching origins.ts to use dynamic API endpoint based on current origin" - -# Patch the origins.ts file to use relative API endpoint instead of hardcoded ente.io -RUN if [ -f "web/packages/base/origins.ts" ]; then \ - echo "Patching origins.ts to use window.location.origin + '/api'"; \ - sed -i 's|(await customAPIOrigin()) ?? "https://api.ente.io"|(await customAPIOrigin()) ?? (typeof window !== "undefined" ? window.location.origin + "/api" : "https://api.ente.io")|g' web/packages/base/origins.ts; \ - sed -i 's|(await customAPIOrigin()) ?? "https://uploader.ente.io"|(await customAPIOrigin()) ?? (typeof window !== "undefined" ? window.location.origin + "/api" : "https://uploader.ente.io")|g' web/packages/base/origins.ts; \ - echo "Patched origins.ts:"; \ - cat web/packages/base/origins.ts | head -20; \ - else \ - echo "origins.ts not found, checking alternative paths"; \ - find . -name "origins.ts" -type f; \ - fi +# Set environment variables for web app build - use relative endpoint +ENV NEXT_PUBLIC_ENTE_ENDPOINT="/api" +RUN echo "Building with relative NEXT_PUBLIC_ENTE_ENDPOINT=/api for self-hosted deployment" # Debugging the repository structure RUN find . -type d -maxdepth 3 | sort diff --git a/start.sh b/start.sh index d73d816..e6c9a94 100644 --- a/start.sh +++ b/start.sh @@ -104,15 +104,6 @@ port: 8080 host: 0.0.0.0 log_level: info -# Key used for encrypting customer data (REQUIRED) -key: - encryption: yvmG/RnzKrbCb9L3mgsmoxXr9H7i2Z4qlbT0mL3ln4w= - hash: KXYiG07wC7GIgvCSdg+WmyWdXDAn6XKYJtp/wkEU7x573+byBRAYtpTP0wwvi8i/4l37uicX1dVTUzwH3sLZyw== - -# JWT secrets (REQUIRED) -jwt: - secret: i2DecQmfGreG6q1vBj5tCokhlN41gcfS2cjOs9Po-u8= - # Database configuration db: host: ${CLOUDRON_POSTGRESQL_HOST} @@ -129,17 +120,14 @@ cors: # S3 storage configuration s3: + endpoint: "${S3_ENDPOINT}" + region: "${S3_REGION}" + access_key: "${S3_ACCESS_KEY}" + secret_key: "${S3_SECRET_KEY}" + bucket: "${S3_BUCKET}" # For Wasabi, we need path style URLs - are_local_buckets: false use_path_style_urls: true - - # Primary bucket configuration (named bucket structure required by Museum) - b2-eu-cen: - endpoint: "${S3_ENDPOINT}" - region: "${S3_REGION}" - key: "${S3_ACCESS_KEY}" - secret: "${S3_SECRET_KEY}" - bucket: "${S3_BUCKET}" + are_local_buckets: false # Email settings email: @@ -152,9 +140,9 @@ email: # WebAuthn configuration for passkey support webauthn: - rpid: "${CLOUDRON_APP_DOMAIN:-localhost}" + rpid: "${CLOUDRON_APP_FQDN:-localhost}" rporigins: - - "https://${CLOUDRON_APP_DOMAIN:-localhost}" + - "https://${CLOUDRON_APP_FQDN:-localhost}" EOF chmod 600 "$MUSEUM_CONFIG" log "INFO" "Created Museum configuration at ${MUSEUM_CONFIG}" @@ -224,17 +212,6 @@ else log "INFO" "Web templates already exist or source not available" fi -# Copy mail templates to Museum working directory (required for email functionality) -MUSEUM_MAIL_TEMPLATES_DIR="/app/data/ente/server/mail-templates" -REPO_MAIL_TEMPLATES_DIR="/app/data/ente/repository/server/mail-templates" -if [ ! -d "$MUSEUM_MAIL_TEMPLATES_DIR" ] && [ -d "$REPO_MAIL_TEMPLATES_DIR" ]; then - log "INFO" "Copying mail templates" - cp -r "$REPO_MAIL_TEMPLATES_DIR" "$MUSEUM_MAIL_TEMPLATES_DIR" - log "INFO" "Copied mail templates to $MUSEUM_MAIL_TEMPLATES_DIR" -else - log "INFO" "Mail templates already exist or source not available" -fi - # Check if Museum binary exists and is valid log "INFO" "Checking for Museum binary at: $MUSEUM_BIN" if [ -f "$MUSEUM_BIN" ]; then @@ -264,9 +241,7 @@ fi # =============================================== # Web Application Setup # =============================================== -log "INFO" "Web applications are pre-built and available in /app/web/" - -# Web apps are pre-built with relative API paths (/api) that work with any domain +log "INFO" "Web applications are pre-built with relative API endpoint /api" # =============================================== # Node.js Placeholder Server @@ -638,11 +613,10 @@ cat > "$CADDY_CONFIG" << EOF # Enable compression encode gzip - # Root redirect - must be first - redir / /photos/ 301 - # CORS preflight handling - @options method OPTIONS + @options { + method OPTIONS + } handle @options { header { Access-Control-Allow-Origin "*" @@ -653,9 +627,14 @@ cat > "$CADDY_CONFIG" << EOF respond 204 } - # API endpoints - STRIP /api prefix and proxy to Museum server + # API endpoints with CORS - strip /api prefix before forwarding handle_path /api/* { - reverse_proxy localhost:8080 + reverse_proxy localhost:8080 { + header_up Host {http.request.host} + header_up X-Real-IP {http.request.remote} + header_up X-Forwarded-For {http.request.remote} + header_up X-Forwarded-Proto {http.request.scheme} + } header { Access-Control-Allow-Origin "*" Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" @@ -664,91 +643,29 @@ cat > "$CADDY_CONFIG" << EOF } } - # API endpoints for auth app - handle_path /auth/api/* { + # Public albums endpoint + handle /public/* { reverse_proxy localhost:8080 header { Access-Control-Allow-Origin "*" - Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" - Access-Control-Allow-Headers "*" - Access-Control-Allow-Credentials "true" } } - # API endpoints for cast app - handle_path /cast/api/* { - reverse_proxy localhost:8080 - header { - Access-Control-Allow-Origin "*" - Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" - Access-Control-Allow-Headers "*" - Access-Control-Allow-Credentials "true" - } - } - - # API endpoints for accounts app - handle_path /accounts/api/* { - reverse_proxy localhost:8080 - header { - Access-Control-Allow-Origin "*" - Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" - Access-Control-Allow-Headers "*" - Access-Control-Allow-Credentials "true" - } - } - - # Health check endpoint (direct, no /api prefix) - handle /ping { + # Health check endpoint + handle /health { reverse_proxy localhost:8080 } - # Static files for Next.js assets - handle per app - handle_path /photos/_next/* { - root * /app/web/photos - file_server + # Static files for Next.js assets from all apps + handle /_next/* { + @photosNext path /_next/* + handle @photosNext { + root * /app/web/photos + file_server + } header { Cache-Control "public, max-age=31536000" - } - } - - handle_path /accounts/_next/* { - root * /app/web/accounts - file_server - header { - Cache-Control "public, max-age=31536000" - } - } - - handle_path /auth/_next/* { - root * /app/web/auth - file_server - header { - Cache-Control "public, max-age=31536000" - } - } - - handle_path /cast/_next/* { - root * /app/web/cast - file_server - header { - Cache-Control "public, max-age=31536000" - } - } - - # Static images and assets (served from photos app by default) - handle /images/* { - root * /app/web/photos - file_server - header { - Cache-Control "public, max-age=86400" - } - } - - handle /favicon.ico { - root * /app/web/photos - file_server - header { - Cache-Control "public, max-age=86400" + Access-Control-Allow-Origin "*" } } @@ -759,30 +676,29 @@ cat > "$CADDY_CONFIG" << EOF file_server } - # Accounts app - handle both /accounts and /accounts/* - handle /accounts* { + # Accounts app + handle_path /accounts/* { root * /app/web/accounts try_files {path} /index.html file_server } - # Auth app - handle both /auth and /auth/* - handle /auth* { + # Auth app + handle_path /auth/* { root * /app/web/auth try_files {path} /index.html file_server } - # Cast app - handle both /cast and /cast/* - handle /cast* { + # Cast app + handle_path /cast/* { root * /app/web/cast try_files {path} /index.html file_server } - # Root redirect - specifically match root path only - @root path / - handle @root { + # Root redirect + handle / { redir /photos/ permanent } } @@ -830,34 +746,19 @@ cat > /app/data/SETUP-INSTRUCTIONS.md << EOF 2. **Museum Server**: The server configuration is at \`/app/data/ente/server/museum.yaml\` if you need to customize settings. -## API Endpoint +## Troubleshooting -The Ente API is available at: **https://${CLOUDRON_APP_FQDN}/api** - -This endpoint can be used to: -- Configure Ente CLI tools -- Integrate with third-party applications -- Access the Museum server API directly - -For admin operations, use the Ente CLI with: -\`\`\`bash -ente admin --api-url https://${CLOUDRON_APP_FQDN}/api -\`\`\` +- **Logs**: Check the logs at \`/app/data/logs/\` for any issues. +- **Restart**: If you change configuration, restart the app to apply changes. ## Web Applications The following web applications are available: -- **Photos**: https://${CLOUDRON_APP_FQDN}/photos/ - Main photo storage and management -- **Auth**: https://${CLOUDRON_APP_FQDN}/auth/ - 2FA authenticator app -- **Accounts**: https://${CLOUDRON_APP_FQDN}/accounts/ - Account management -- **Cast**: https://${CLOUDRON_APP_FQDN}/cast/ - Photo casting to devices - -## Troubleshooting - -- **Logs**: Check the logs at \`/app/data/logs/\` for any issues. -- **Restart**: If you change configuration, restart the app to apply changes. -- **API Issues**: All apps use the API endpoint at \`/api\`. If apps show loading spinners, check API connectivity. +- Photos: https://${CLOUDRON_APP_FQDN}/photos/ +- Accounts: https://${CLOUDRON_APP_FQDN}/accounts/ +- Auth: https://${CLOUDRON_APP_FQDN}/auth/ +- Cast: https://${CLOUDRON_APP_FQDN}/cast/ ## Support @@ -881,48 +782,6 @@ else log "ERROR" "Caddy server is not running!" fi -# =============================================== -# OTP Email Monitor Setup -# =============================================== -log "INFO" "Setting up OTP Email Monitor" - -# Install Node.js dependencies if not already installed -if [ ! -d "/app/data/node_modules" ]; then - log "INFO" "Installing Node.js dependencies for OTP Email Monitor" - cd /app/data - cp /app/pkg/package.json . - npm install --production --no-save - log "INFO" "Node.js dependencies installed successfully" -else - log "INFO" "Node.js dependencies already installed" -fi - -# Start OTP Email Monitor -log "INFO" "Starting OTP Email Monitor" -cd /app/data -NODE_PATH="/app/data/node_modules" node /app/pkg/otp-email-monitor.js > /app/data/logs/otp-email.log 2>&1 & -OTP_MONITOR_PID=$! -log "INFO" "OTP Email Monitor started with PID: $OTP_MONITOR_PID" - -# Wait a moment to check if OTP monitor starts successfully -sleep 2 -if ps -p $OTP_MONITOR_PID > /dev/null; then - log "INFO" "OTP Email Monitor is running successfully" -else - log "WARN" "OTP Email Monitor may have failed to start" - log "WARN" "Last 10 lines of OTP email log:" - tail -n 10 /app/data/logs/otp-email.log | while read -r line; do - log "WARN" " $line" - done -fi - -# Copy admin helper script for easy access -if [ -f "/app/pkg/admin-helper.sh" ]; then - cp /app/pkg/admin-helper.sh /app/data/ - chmod +x /app/data/admin-helper.sh - log "INFO" "Admin helper script available at /app/data/admin-helper.sh" -fi - log "INFO" "Ente Cloudron app startup complete" # Keep the script running to prevent container exit