Update Cloudron app configuration and setup

This commit is contained in:
Andreas Düren 2025-03-16 22:17:41 +01:00
parent 05a0b42b8e
commit 65e88f4408
4 changed files with 374 additions and 100 deletions

View File

@ -8,8 +8,8 @@
"tagline": "Open Source End-to-End Encrypted Photos & Authentication",
"upstreamVersion": "1.0.0",
"version": "1.0.0",
"healthCheckPath": "/",
"httpPort": 8080,
"healthCheckPath": "/healthcheck",
"httpPort": 3080,
"memoryLimit": 1073741824,
"addons": {
"localstorage": {},
@ -18,6 +18,12 @@
"supportsDisplayName": true
}
},
"checklist": {
"create-permanent-admin": {
"message": "Required: S3 Storage Configuration!"
}
},
"icon": "file://logo.png",
"tags": [
"photos",

View File

@ -12,8 +12,10 @@ RUN apt-get update && apt-get install -y git && \
RUN corepack enable
# Set environment variables for web app build
# Will be overridden at runtime with the actual server endpoint
ENV NEXT_PUBLIC_ENTE_ENDPOINT="https://localhost:8080"
# Use "/api" as the endpoint which will be replaced at runtime with the full URL
ENV NEXT_PUBLIC_ENTE_ENDPOINT="/api"
# Add a note for clarity
RUN echo "Building with NEXT_PUBLIC_ENTE_ENDPOINT=/api, will be replaced at runtime with full URL"
# Debugging the repository structure
RUN find . -type d -maxdepth 3 | sort
@ -78,8 +80,14 @@ FROM cloudron/base:5.0.0@sha256:04fd70dbd8ad6149c19de39e35718e024417c3e01dc9c663
# Install necessary packages (excluding golang as we'll install it manually)
RUN apt-get update && \
apt-get install -y curl git nodejs npm libsodium23 libsodium-dev pkg-config nginx && \
apt-get install -y curl git nodejs npm libsodium23 libsodium-dev pkg-config postgresql-client && \
npm install -g yarn serve && \
# Install Caddy instead of NGINX
apt-get install -y debian-keyring debian-archive-keyring apt-transport-https && \
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg && \
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list && \
apt-get update && \
apt-get install -y caddy && \
apt-get clean && apt-get autoremove && \
rm -rf /var/cache/apt /var/lib/apt/lists
@ -103,6 +111,17 @@ RUN git clone --depth=1 https://github.com/ente-io/ente.git . && \
cp -r server/go.mod server/go.sum /app/data/go/ && \
chmod 777 /app/data/go/go.mod /app/data/go/go.sum
# Pre-download Go dependencies
RUN cd server && \
export GOMODCACHE="/app/data/go/pkg/mod" && \
export GOFLAGS="-modfile=/app/data/go/go.mod -mod=mod" && \
export GOTOOLCHAIN=local && \
export GO111MODULE=on && \
export GOSUMDB=off && \
mkdir -p /app/data/go/pkg/mod && \
chmod -R 777 /app/data/go && \
go mod download
# Set Go environment variables
ENV GOTOOLCHAIN=local
ENV GO111MODULE=on
@ -127,8 +146,8 @@ RUN chmod +x /app/pkg/start.sh
# Create NGINX directories
RUN mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled
# Expose the web port (Cloudron expects port 8080)
EXPOSE 8080
# Expose the web port (Cloudron expects port 3080 now)
EXPOSE 3080
# Start the application
CMD ["/app/pkg/start.sh"]

View File

@ -10,6 +10,28 @@ This repository contains the Cloudron packaging for [Ente](https://ente.io), an
- Configured to use Cloudron's mail service for sending emails
- Easy to deploy and manage through the Cloudron interface
## Requirements
### Browser Compatibility
Ente uses modern web technologies for its end-to-end encryption:
- **WebAssembly**: Required for cryptographic operations
- **IndexedDB**: Required for client-side data storage
Most modern browsers support these features, but they may be blocked by:
- Browser privacy settings
- Content Security Policies
- Certain browser extensions
This package includes custom Caddy configuration with appropriate security headers to ensure these features work correctly.
### S3-Compatible Storage
Ente requires an S3-compatible object storage service. You can use:
- Cloudron's built-in object storage
- External services like AWS S3, Wasabi, or MinIO
## Building and Installing
### Option 1: Build and Install Manually
@ -53,6 +75,14 @@ The app is configured automatically using Cloudron's environment variables for:
- SMTP mail service
- App origin URL
### Additional Configuration
The package includes several enhancements to ensure proper functionality:
1. **Security Headers**: Custom Content-Security-Policy headers that allow WebAssembly and IndexedDB
2. **API Configuration**: Dynamic runtime configuration to ensure the frontend connects to the correct API endpoint
3. **CORS Headers**: Proper CORS configuration for API access
## Usage
### Web Client
@ -77,6 +107,12 @@ cloudron update --app ente.yourdomain.com
## Troubleshooting
### Common Issues
1. **"Failed to fetch" errors**: Check if your browser is blocking API requests to your domain
2. **WebAssembly errors**: Ensure your browser supports and allows WebAssembly (try using Chrome or Firefox)
3. **IndexedDB errors**: Make sure your browser allows IndexedDB (not in private/incognito mode)
For issues specific to the Cloudron packaging, please open an issue in this repository.
For issues with Ente itself, please refer to the [main Ente repository](https://github.com/ente-io/ente).

399
start.sh
View File

@ -1,14 +1,14 @@
#!/bin/bash
# Better signal handling - forward signals to child processes
trap 'kill -TERM $SERVER_PID; kill -TERM $NGINX_PID; exit' TERM INT
trap 'kill -TERM $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/nginx/tmp /app/data/go /app/data/logs /run/nginx
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"
@ -164,82 +164,135 @@ sed -i 's|s3.are_local_buckets: true|s3.are_local_buckets: false|g' /app/data/co
# Install or verify required packages
echo "==> Checking for required packages"
if ! command -v nginx &> /dev/null; then
echo "==> Installing NGINX"
apt-get update && apt-get install -y nginx
if ! command -v caddy &> /dev/null; then
echo "==> Installing Caddy"
apt-get update && apt-get install -y debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list
apt-get update && apt-get install -y caddy
fi
# Set up NGINX to serve the web apps and proxy to the Museum server
echo "==> Setting up NGINX for web apps and API"
# Set up Caddy to serve the web apps and proxy to the Museum server
echo "==> Setting up Caddy for web apps and API"
# Create a custom NGINX configuration in the writable data directory
cat > /app/data/nginx/ente.conf <<EOT
worker_processes 1;
error_log stderr;
daemon off;
pid /app/data/nginx/nginx.pid;
events {
worker_connections 1024;
# Create a custom Caddy configuration in the writable data directory
mkdir -p /app/data/caddy
cat > /app/data/caddy/Caddyfile <<EOT
{
admin off
auto_https off
log {
output file /app/data/caddy/caddy.log
format console
}
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout combined;
sendfile on;
keepalive_timeout 65;
# Define temp file paths
client_body_temp_path /app/data/nginx/tmp;
proxy_temp_path /app/data/nginx/tmp;
fastcgi_temp_path /app/data/nginx/tmp;
uwsgi_temp_path /app/data/nginx/tmp;
scgi_temp_path /app/data/nginx/tmp;
server {
listen 8080;
:3080 {
log {
output file /app/data/caddy/access.log
format console
}
# Add security headers to enable WebAssembly and IndexedDB
header {
# Security headers
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Referrer-Policy "strict-origin-when-cross-origin"
# Photos app - root path
location / {
root /app/web/photos;
try_files \$uri \$uri/ /index.html;
}
# Content Security Policy that allows WebAssembly
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self' ${CLOUDRON_APP_ORIGIN} https://*.${CLOUDRON_APP_DOMAIN}; worker-src 'self' blob:;"
# Accounts app
location /accounts/ {
alias /app/web/accounts/;
try_files \$uri \$uri/ /accounts/index.html;
# CORS headers for API access
Access-Control-Allow-Origin "*"
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers "Content-Type, Authorization"
Access-Control-Allow-Credentials "true"
}
# For debugging - public access to the config.js
handle /debug/config.js {
root * /app/data/caddy/public
file_server
}
# Create a special handler for index.html files to inject our config
@indexhtml {
path_regexp index .*\/index\.html$
}
# Handle the direct window variable configuration better
handle @indexhtml {
# Inject a non-defer, early-loading script that defines ENTE_CONFIG
respond_early_hints {
link "</config.js>; rel=preload; as=script"
}
# Auth app
location /auth/ {
alias /app/web/auth/;
try_files \$uri \$uri/ /auth/index.html;
}
# Cast app
location /cast/ {
alias /app/web/cast/;
try_files \$uri \$uri/ /cast/index.html;
}
# API endpoints - proxy to Museum server
location /api/ {
proxy_pass http://localhost:8000;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_cache_bypass \$http_upgrade;
access_log /dev/stdout;
error_log /dev/stderr debug;
header Content-Type "text/html; charset=utf-8"
replace_response_headers Content-Length ""
rewrite_early * {
# This injects the script into the head section of any index.html
r </head> <script>window.ENTE_CONFIG = { API_URL: "${CLOUDRON_APP_ORIGIN}/api" };</script></head>
}
}
# Configuration available via JavaScript
handle /config.js {
header Content-Type "application/javascript"
respond "window.ENTE_CONFIG = { API_URL: '${CLOUDRON_APP_ORIGIN}/api' }; console.log('Ente config loaded with API_URL:', window.ENTE_CONFIG.API_URL);"
}
# Photos app - root path
handle /photos* {
uri strip_prefix /photos
root * /app/web/photos
try_files {path} /index.html
file_server
}
# Accounts app
handle /accounts/* {
uri strip_prefix /accounts
root * /app/web/accounts
try_files {path} /index.html
file_server
}
# Auth app
handle /auth/* {
uri strip_prefix /auth
root * /app/web/auth
try_files {path} /index.html
file_server
}
# Cast app
handle /cast/* {
uri strip_prefix /cast
root * /app/web/cast
try_files {path} /index.html
file_server
}
# API endpoints - proxy to Museum server
handle /api/* {
reverse_proxy localhost:8080
}
# Health check endpoint for Cloudron
handle /healthcheck {
respond "OK" 200
}
# Default to photos app
handle {
root * /app/web/photos
try_files {path} /index.html
file_server
}
}
EOT
echo "==> Custom NGINX configuration created at /app/data/nginx/ente.conf"
echo "==> Caddy configuration created at /app/data/caddy/Caddyfile"
# Looking for Museum (Go server component)
echo "==> Looking for Museum (Go server component)"
@ -363,21 +416,60 @@ if [ ! -f "/app/data/go/go.mod" ] && [ -f "$SERVER_DIR/go.mod" ]; then
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/modcache
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
# Test if API endpoint is reachable
echo "==> Testing API connectivity"
curl -v http://localhost:8000/api/health || echo "API not yet available, this is normal during startup"
# 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
# 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
chown -R cloudron:cloudron /app/data/caddy
# Start Caddy
echo "==> Starting Caddy"
caddy run --config /app/data/caddy/Caddyfile --adapter caddyfile &
CADDY_PID=$!
echo "==> Caddy started with PID $CADDY_PID"
# Check if Caddy started successfully
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
else
echo "No Caddy logs available yet"
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
# Determine available memory and set limits accordingly
if [[ -f /sys/fs/cgroup/cgroup.controllers ]]; then # cgroup v2
@ -395,9 +487,66 @@ export ENTE_DB_PASSWORD="${CLOUDRON_POSTGRESQL_PASSWORD}"
export ENTE_DB_HOST="${CLOUDRON_POSTGRESQL_HOST}"
export ENTE_DB_PORT="${CLOUDRON_POSTGRESQL_PORT}"
export ENTE_DB_NAME="${CLOUDRON_POSTGRESQL_DATABASE}"
export ENTE_DB_SSLMODE="require"
export ENTE_DB_SSLMODE="disable"
export CONFIG_PATH="/app/data/config/config.yaml"
# Check database connectivity
echo "==> Checking database connectivity"
MAX_RETRIES=5
RETRY_COUNT=0
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
if 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 2>&1; then
echo "==> Successfully connected to database"
break
else
echo "==> Failed to connect to database (attempt $((RETRY_COUNT+1))/$MAX_RETRIES)"
RETRY_COUNT=$((RETRY_COUNT+1))
sleep 5
fi
done
if [ $RETRY_COUNT -eq $MAX_RETRIES ]; then
echo "==> ERROR: Could not connect to database after $MAX_RETRIES attempts"
echo "==> Database connection details:"
echo "Host: ${CLOUDRON_POSTGRESQL_HOST}"
echo "Port: ${CLOUDRON_POSTGRESQL_PORT}"
echo "User: ${CLOUDRON_POSTGRESQL_USERNAME}"
echo "Database: ${CLOUDRON_POSTGRESQL_DATABASE}"
exit 1
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"
cd "$SERVER_DIR"
# Create migrations log directory
mkdir -p /app/data/logs/migrations
echo "==> Forcing migration version to 25"
if /usr/local/bin/gosu cloudron:cloudron env GOCACHE=/app/data/go/cache GOMODCACHE=/app/data/go/pkg/mod \
go run -modfile=/app/data/go/go.mod -mod=mod cmd/museum/main.go migrate force 25 \
> /app/data/logs/migrations/force.log 2>&1; then
echo "==> Successfully forced migration version"
else
echo "==> Failed to force migration version. Check /app/data/logs/migrations/force.log for details"
cat /app/data/logs/migrations/force.log
fi
echo "==> Running clean migrations"
if /usr/local/bin/gosu cloudron:cloudron env GOCACHE=/app/data/go/cache GOMODCACHE=/app/data/go/pkg/mod \
go run -modfile=/app/data/go/go.mod -mod=mod cmd/museum/main.go migrate up \
> /app/data/logs/migrations/up.log 2>&1; then
echo "==> Successfully ran migrations"
else
echo "==> Failed to run migrations. Check /app/data/logs/migrations/up.log for details"
cat /app/data/logs/migrations/up.log
echo "==> WARNING: Database migrations failed. The application may not work correctly."
fi
fi
# Additional environment variables
export REMOTE_STORAGE_ENDPOINT="${S3_ENDPOINT}"
export REMOTE_STORAGE_REGION="${S3_REGION}"
@ -408,21 +557,61 @@ export REMOTE_STORAGE_PREFIX="${S3_PREFIX:-ente/}"
# Change ownership to cloudron user
chown -R cloudron:cloudron /app/data
chown -R cloudron:cloudron /run/nginx
# Start Museum server on port 8000 (different from the NGINX port 8080)
# Start Museum server on port 8080 for compatibility with the Caddy configuration
echo "==> Starting Museum server"
# Modify environment variables for frontend
echo "==> Setting up environment variables for frontend"
# For web frontend, these aren't changing
export NEXT_PUBLIC_ENTE_ENDPOINT="${CLOUDRON_APP_ORIGIN}"
# Set frontend endpoint to the proper origin
export NEXT_PUBLIC_ENTE_ENDPOINT="${CLOUDRON_APP_ORIGIN}/api"
echo "==> NEXT_PUBLIC_ENTE_ENDPOINT set to ${NEXT_PUBLIC_ENTE_ENDPOINT}"
# Also create a direct config in multiple formats to ensure it's properly loaded
echo "==> Creating runtime configuration for the web apps in multiple formats"
mkdir -p /app/data/runtime
# 1. Standard config.js
cat > /app/data/runtime/config.js <<EOT
// Direct configuration file for Ente web apps
window.ENTE_CONFIG = {
API_URL: "${CLOUDRON_APP_ORIGIN}/api"
};
// Log configuration loaded
console.log("Ente config loaded with API_URL:", window.ENTE_CONFIG.API_URL);
EOT
# 2. JSON format
cat > /app/data/runtime/config.json <<EOT
{
"API_URL": "${CLOUDRON_APP_ORIGIN}/api"
}
EOT
# 3. Environment variable format
cat > /app/data/runtime/env.js <<EOT
// Environment variables in JavaScript
window.process = window.process || {};
window.process.env = window.process.env || {};
window.process.env.NEXT_PUBLIC_ENTE_ENDPOINT = "${CLOUDRON_APP_ORIGIN}/api";
EOT
# Copy them to the Caddy public directory
mkdir -p /app/data/caddy/public
cp /app/data/runtime/config.js /app/data/caddy/public/
cp /app/data/runtime/config.json /app/data/caddy/public/
cp /app/data/runtime/env.js /app/data/caddy/public/
# Print the content of the config file for debugging
echo "==> Generated config.js content:"
cat /app/data/runtime/config.js
# First check for pre-built Museum binary
if find "$SERVER_DIR" -name "museum" -type f -executable | grep -q .; then
MUSEUM_BIN=$(find "$SERVER_DIR" -name "museum" -type f -executable | head -1)
echo "==> Found Museum binary at $MUSEUM_BIN"
/usr/local/bin/gosu cloudron:cloudron "$MUSEUM_BIN" --port 8000 \
/usr/local/bin/gosu cloudron:cloudron "$MUSEUM_BIN" --port 8080 \
--storage.s3.endpoint="${S3_ENDPOINT}" \
--storage.s3.region="${S3_REGION}" \
--storage.s3.bucket="${S3_BUCKET}" \
@ -433,7 +622,7 @@ if find "$SERVER_DIR" -name "museum" -type f -executable | grep -q .; then
--storage.s3.areLocalBuckets=false \
--storage.type="s3" \
--config.path="/app/data/config/museum.yaml" \
--database.sslmode="require" > /app/data/logs/museum-server.log 2>&1 &
--database.sslmode="disable" > /app/data/logs/museum-server.log 2>&1 &
SERVER_PID=$!
echo "==> Museum server started with PID $SERVER_PID"
# Next check for cmd/museum directory pattern
@ -451,7 +640,8 @@ elif [ -d "$SERVER_DIR/cmd/museum" ]; then
if [[ "${S3_ENDPOINT}" == *"wasabi"* ]]; then
echo "==> Detected Wasabi S3 endpoint, adjusting settings"
echo "==> Adding -mod=mod to go run to ignore version mismatch"
/usr/local/bin/gosu cloudron:cloudron go run -mod=mod cmd/museum/main.go --port 8000 \
cd "$SERVER_DIR" && \
/usr/local/bin/gosu cloudron:cloudron env GOCACHE=/app/data/go/cache GOMODCACHE=/app/data/go/pkg/mod PORT=8080 GIN_MODE=release go run -modfile=/app/data/go/go.mod -mod=mod cmd/museum/main.go --port 8080 \
--storage.s3.endpoint="${S3_ENDPOINT}" \
--storage.s3.region="${S3_REGION}" \
--storage.s3.bucket="${S3_BUCKET}" \
@ -462,10 +652,11 @@ elif [ -d "$SERVER_DIR/cmd/museum" ]; then
--storage.s3.areLocalBuckets=false \
--storage.type="s3" \
--config.path="/app/data/config/museum.yaml" \
--database.sslmode="require" \
--database.sslmode="disable" \
--log.level=debug > /app/data/logs/museum-server.log 2>&1 &
else
/usr/local/bin/gosu cloudron:cloudron go run -mod=mod cmd/museum/main.go --port 8000 \
cd "$SERVER_DIR" && \
/usr/local/bin/gosu cloudron:cloudron env GOCACHE=/app/data/go/cache GOMODCACHE=/app/data/go/pkg/mod PORT=8080 GIN_MODE=release go run -modfile=/app/data/go/go.mod -mod=mod cmd/museum/main.go --port 8080 \
--storage.s3.endpoint="${S3_ENDPOINT}" \
--storage.s3.region="${S3_REGION}" \
--storage.s3.bucket="${S3_BUCKET}" \
@ -476,7 +667,7 @@ elif [ -d "$SERVER_DIR/cmd/museum" ]; then
--storage.s3.areLocalBuckets=false \
--storage.type="s3" \
--config.path="/app/data/config/museum.yaml" \
--database.sslmode="require" \
--database.sslmode="disable" \
--log.level=debug > /app/data/logs/museum-server.log 2>&1 &
fi
SERVER_PID=$!
@ -491,7 +682,7 @@ elif [ -d "$SERVER_DIR/cmd/museum" ]; then
RETRY_COUNT=0
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
echo "==> Testing API connection (attempt $((RETRY_COUNT+1))/$MAX_RETRIES)"
if curl -s http://localhost:8000/api/health > /dev/null; then
if curl -s http://localhost:8080/api/health > /dev/null; then
echo "==> API is now responding"
break
else
@ -527,7 +718,8 @@ else
export GOTOOLCHAIN=local
echo "==> Running main.go with Go"
/usr/local/bin/gosu cloudron:cloudron go run -mod=mod main.go --port 8000 \
cd "$MAIN_DIR" && \
/usr/local/bin/gosu cloudron:cloudron env GOCACHE=/app/data/go/cache GOMODCACHE=/app/data/go/pkg/mod PORT=8080 GIN_MODE=release go run -modfile=/app/data/go/go.mod -mod=mod main.go --port 8080 \
--storage.s3.endpoint="${S3_ENDPOINT}" \
--storage.s3.region="${S3_REGION}" \
--storage.s3.bucket="${S3_BUCKET}" \
@ -538,6 +730,7 @@ else
--storage.s3.areLocalBuckets=false \
--storage.type="s3" \
--config.path="/app/data/config/museum.yaml" \
--database.sslmode="disable" \
--log.level=debug > /app/data/logs/museum-server.log 2>&1 &
SERVER_PID=$!
echo "==> Museum server started with PID $SERVER_PID"
@ -592,10 +785,10 @@ func main() {
})
// Start the server
log.Println("Starting mock server on port 8000")
log.Println("Starting mock server on port 8080")
// Start in a goroutine to prevent blocking
server := &http.Server{Addr: ":8000"}
server := &http.Server{Addr: ":8080"}
go func() {
if err := server.ListenAndServe(); err != nil {
log.Fatalf("Server error: %v", err)
@ -612,15 +805,35 @@ EOT
echo "==> Mock server started with PID $SERVER_PID to show error message"
fi
# Serve the static web apps in the foreground using our custom nginx config
echo "==> Running NGINX in the foreground with custom configuration"
nginx -c /app/data/nginx/ente.conf &
NGINX_PID=$!
echo "==> NGINX started with PID $NGINX_PID"
echo "==> Testing health check endpoint directly"
curl -v http://localhost:3080/healthcheck
echo "==> Ente is now running!"
echo "==> Museum server: PID $SERVER_PID"
echo "==> NGINX: PID $NGINX_PID"
echo "==> Caddy: PID $CADDY_PID"
# Wait for the processes to finish (or be terminated)
wait
# Function to inject the config.js script tag into index.html files
inject_config_script() {
echo "==> Attempting to inject config.js script tag into 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"
# Try to modify in place without creating a backup
sed -i 's|</head>|<script>window.ENTE_CONFIG = { API_URL: "'"${CLOUDRON_APP_ORIGIN}"'/api" };</script></head>|' "$app_dir/index.html" || echo "==> Cannot modify $app_dir/index.html - read-only file system"
else
echo "==> Skipping $app_dir - index.html not found"
fi
done
}
# Try to inject the config script but don't worry if it fails
inject_config_script || echo "==> NOTE: Could not inject configuration directly into HTML files"
# Wait for child processes to exit
wait $SERVER_PID
wait $CADDY_PID