diff --git a/Dockerfile b/Dockerfile index 3a5ded1..54d8e3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,19 @@ +# Build Museum server from source +FROM golang:1.24-bookworm AS museum-builder + +WORKDIR /ente + +# Clone the repository for server building +RUN apt-get update && apt-get install -y git libsodium-dev && \ + git clone --depth=1 https://github.com/ente-io/ente.git . && \ + apt-get clean && apt-get autoremove && \ + rm -rf /var/cache/apt /var/lib/apt/lists + +# Build the Museum server +WORKDIR /ente/server +RUN go mod download && \ + CGO_ENABLED=1 GOOS=linux go build -a -o museum ./cmd/museum + FROM node:20-bookworm-slim as web-builder WORKDIR /ente @@ -12,10 +28,10 @@ RUN apt-get update && apt-get install -y git && \ RUN corepack enable # Set environment variables for web app build -# Use "/api" as the endpoint which will be replaced at runtime with the full URL -ENV NEXT_PUBLIC_ENTE_ENDPOINT="/api" +# Set the API endpoint to use current origin - this will work at runtime +ENV NEXT_PUBLIC_ENTE_ENDPOINT="https://example.com/api" # Add a note for clarity -RUN echo "Building with NEXT_PUBLIC_ENTE_ENDPOINT=/api, will be replaced at runtime with full URL" +RUN echo "Building with placeholder NEXT_PUBLIC_ENTE_ENDPOINT, will be served by Caddy proxy at /api" # Debugging the repository structure RUN find . -type d -maxdepth 3 | sort @@ -136,6 +152,11 @@ COPY --from=web-builder /build/web/accounts /app/web/accounts COPY --from=web-builder /build/web/auth /app/web/auth COPY --from=web-builder /build/web/cast /app/web/cast +# Copy Museum server binary from builder stage to app directory (not data volume) +RUN mkdir -p /app/museum-bin +COPY --from=museum-builder /ente/server/museum /app/museum-bin/museum +RUN chmod +x /app/museum-bin/museum + # Copy configuration and startup scripts ADD start.sh /app/pkg/ ADD config.template.yaml /app/pkg/ diff --git a/start.sh b/start.sh index f5a88e7..f9eacc3 100644 --- a/start.sh +++ b/start.sh @@ -47,7 +47,6 @@ log "INFO" "Creating necessary directories" mkdir -p /app/data/ente/server mkdir -p /app/data/ente/web mkdir -p /app/data/tmp -mkdir -p /app/data/web/{photos,accounts,auth,cast} # =============================================== # Repository setup @@ -78,25 +77,23 @@ fi # =============================================== log "INFO" "Setting up configuration" -# S3 configuration - Hardcoded for Wasabi -log "INFO" "Setting up hardcoded Wasabi S3 configuration" - -# Hardcoded Wasabi credentials +# S3 configuration - HARDCODED VALUES S3_ACCESS_KEY="QZ5M3VMBUHDTIFDFCD8E" S3_SECRET_KEY="pz1eHYjU1NwAbbruedc7swzCuszd57p1rGSFVzjv" S3_ENDPOINT="https://s3.eu-central-2.wasabisys.com" S3_REGION="eu-central-2" S3_BUCKET="ente-due-ren" -log "INFO" "Using Wasabi S3 configuration:" -log "INFO" " Endpoint: ${S3_ENDPOINT}" -log "INFO" " Region: ${S3_REGION}" -log "INFO" " Bucket: ${S3_BUCKET}" +log "INFO" "Using hardcoded S3 configuration" +log "INFO" "S3 Endpoint: $S3_ENDPOINT" +log "INFO" "S3 Region: $S3_REGION" +log "INFO" "S3 Bucket: $S3_BUCKET" -# S3 configuration is now hardcoded above +# Museum server configuration - create configurations directory structure +MUSEUM_CONFIG_DIR="/app/data/ente/server/configurations" +MUSEUM_CONFIG="$MUSEUM_CONFIG_DIR/local.yaml" +mkdir -p "$MUSEUM_CONFIG_DIR" -# Museum server configuration -MUSEUM_CONFIG="/app/data/ente/server/museum.yaml" if [ ! -f "$MUSEUM_CONFIG" ]; then log "INFO" "Creating Museum server configuration" cat > "$MUSEUM_CONFIG" << EOF @@ -109,34 +106,43 @@ log_level: info # Database configuration db: - driver: postgres - source: "postgres://${CLOUDRON_POSTGRESQL_USERNAME}:${CLOUDRON_POSTGRESQL_PASSWORD}@${CLOUDRON_POSTGRESQL_HOST}:${CLOUDRON_POSTGRESQL_PORT}/${CLOUDRON_POSTGRESQL_DATABASE}?sslmode=disable" - max_conns: 10 - max_idle: 5 + host: ${CLOUDRON_POSTGRESQL_HOST} + port: ${CLOUDRON_POSTGRESQL_PORT} + name: ${CLOUDRON_POSTGRESQL_DATABASE} + user: ${CLOUDRON_POSTGRESQL_USERNAME} + password: ${CLOUDRON_POSTGRESQL_PASSWORD} + sslmode: disable # CORS settings cors: allow_origins: - "*" -# S3 storage configuration following Ente's format +# S3 storage configuration s3: - are_local_buckets: true - b2-eu-cen: - key: ${S3_ACCESS_KEY} - secret: ${S3_SECRET_KEY} - endpoint: ${S3_ENDPOINT} - region: ${S3_REGION} - bucket: ${S3_BUCKET} + 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 + use_path_style_urls: true + are_local_buckets: false # Email settings email: enabled: true - host: "${CLOUDRON_SMTP_SERVER:-localhost}" - port: ${CLOUDRON_SMTP_PORT:-25} - username: "${CLOUDRON_SMTP_USERNAME:-""}" - password: "${CLOUDRON_SMTP_PASSWORD:-""}" - from: "Ente <${CLOUDRON_MAIL_FROM:-no-reply@${CLOUDRON_APP_DOMAIN}}>" + host: "${CLOUDRON_MAIL_SMTP_SERVER:-localhost}" + port: ${CLOUDRON_MAIL_SMTP_PORT:-25} + username: "${CLOUDRON_MAIL_SMTP_USERNAME:-}" + password: "${CLOUDRON_MAIL_SMTP_PASSWORD:-}" + from: "${CLOUDRON_MAIL_FROM:-no-reply@${CLOUDRON_APP_FQDN:-localhost}}" + +# WebAuthn configuration for passkey support +webauthn: + rpid: "${CLOUDRON_APP_FQDN:-localhost}" + rporigins: + - "https://${CLOUDRON_APP_FQDN:-localhost}" EOF chmod 600 "$MUSEUM_CONFIG" log "INFO" "Created Museum configuration at ${MUSEUM_CONFIG}" @@ -172,259 +178,86 @@ USE_PLACEHOLDER=false log "INFO" "Setting up Museum server binary" -# Function to validate a binary -validate_binary() { - local bin_path="$1" - - # Basic file existence check - if [ ! -f "$bin_path" ]; then - return 1 - fi - - # Check if file is executable - if [ ! -x "$bin_path" ]; then - chmod +x "$bin_path" || return 1 - fi - - # Check if it's a text file (most likely an error message) - if file "$bin_path" | grep -q "text"; then - return 1 - fi - - # Check if it's a valid binary type - if ! file "$bin_path" | grep -q -E "ELF|Mach-O|PE32"; then - return 1 - fi - - return 0 -} - -# Check and remove invalid binary -if [ -f "$MUSEUM_BIN" ]; then - if ! validate_binary "$MUSEUM_BIN"; then - log "WARN" "Found invalid Museum binary, removing" - rm -f "$MUSEUM_BIN" - else - log "INFO" "Found valid Museum binary" - fi +# Copy Museum binary from build location to data directory +MUSEUM_BUILD_BIN="/app/museum-bin/museum" +log "INFO" "Checking for pre-built Museum binary at: $MUSEUM_BUILD_BIN" +if [ -f "$MUSEUM_BUILD_BIN" ]; then + log "INFO" "Found pre-built Museum binary, copying to data directory" + cp "$MUSEUM_BUILD_BIN" "$MUSEUM_BIN" + chmod +x "$MUSEUM_BIN" + log "INFO" "Copied Museum binary to $MUSEUM_BIN" +else + log "WARN" "Pre-built Museum binary not found at $MUSEUM_BUILD_BIN" fi -# Build or download if needed -if [ ! -f "$MUSEUM_BIN" ]; then - # Try building first if Go is available - if command -v go >/dev/null 2>&1; then - log "INFO" "Go is available, attempting to build Museum server" - - cd "$ENTE_REPO_DIR/server" - export GOPATH="/app/data/go" - export PATH="$GOPATH/bin:$PATH" - mkdir -p "$GOPATH/src" "$GOPATH/bin" "$GOPATH/pkg" - - # Install dependencies if needed - if command -v apt-get >/dev/null 2>&1; then - log "INFO" "Installing build dependencies" - apt-get update -y && apt-get install -y gcc libsodium-dev pkg-config - fi - - log "INFO" "Building Museum server..." - if go build -o "$MUSEUM_BIN" ./cmd/museum; then - if validate_binary "$MUSEUM_BIN"; then - log "INFO" "Successfully built Museum server" - else - log "ERROR" "Build completed but resulted in an invalid binary" - rm -f "$MUSEUM_BIN" - fi - else - log "ERROR" "Failed to build Museum server" - fi +# Copy migration files to Museum working directory +MUSEUM_MIGRATIONS_DIR="/app/data/ente/server/migrations" +REPO_MIGRATIONS_DIR="/app/data/ente/repository/server/migrations" +if [ ! -d "$MUSEUM_MIGRATIONS_DIR" ] && [ -d "$REPO_MIGRATIONS_DIR" ]; then + log "INFO" "Copying database migration files" + cp -r "$REPO_MIGRATIONS_DIR" "$MUSEUM_MIGRATIONS_DIR" + log "INFO" "Copied migration files to $MUSEUM_MIGRATIONS_DIR" +else + log "INFO" "Migration files already exist or source not available" +fi + +# Copy web templates to Museum working directory +MUSEUM_WEB_TEMPLATES_DIR="/app/data/ente/server/web-templates" +REPO_WEB_TEMPLATES_DIR="/app/data/ente/repository/server/web-templates" +if [ ! -d "$MUSEUM_WEB_TEMPLATES_DIR" ] && [ -d "$REPO_WEB_TEMPLATES_DIR" ]; then + log "INFO" "Copying web templates" + cp -r "$REPO_WEB_TEMPLATES_DIR" "$MUSEUM_WEB_TEMPLATES_DIR" + log "INFO" "Copied web templates to $MUSEUM_WEB_TEMPLATES_DIR" +else + log "INFO" "Web 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 + log "INFO" "Museum binary file exists" + if [ -x "$MUSEUM_BIN" ]; then + log "INFO" "Museum binary is executable" + # Since Museum's --help and --version commands trigger full startup (including DB migration), + # we'll trust that an existing executable binary should work + log "INFO" "Museum binary is ready to use" else - log "INFO" "Go is not available, skipping build attempt" - fi - - # If build failed or wasn't attempted, try downloading - if [ ! -f "$MUSEUM_BIN" ] || ! validate_binary "$MUSEUM_BIN"; then - log "INFO" "Attempting to download pre-built Museum server binary" - - # Determine architecture - ARCH=$(uname -m) - OS=$(uname -s | tr '[:upper:]' '[:lower:]') - - # Map architecture to standard names - if [ "$ARCH" = "x86_64" ]; then ARCH="amd64"; fi - if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then ARCH="arm64"; fi - - log "INFO" "Detected system: $OS-$ARCH" - - # Define possible download URLs - DOWNLOAD_URLS=( - "https://github.com/ente-io/ente/releases/latest/download/museum-${OS}-${ARCH}" - "https://github.com/ente-io/ente/releases/download/latest/museum-${OS}-${ARCH}" - "https://github.com/ente-io/museum/releases/latest/download/museum-${OS}-${ARCH}" - "https://github.com/ente-io/museum/releases/download/latest/museum-${OS}-${ARCH}" - "https://github.com/ente-io/ente/releases/download/v0.9.0/museum-${OS}-${ARCH}" - "https://github.com/ente-io/museum/releases/download/v0.9.0/museum-${OS}-${ARCH}" - ) - - # Try each URL - SUCCESS=false - for URL in "${DOWNLOAD_URLS[@]}"; do - log "INFO" "Attempting download from $URL" - if curl -L -f -s -o "$MUSEUM_BIN.tmp" "$URL"; then - chmod +x "$MUSEUM_BIN.tmp" - if validate_binary "$MUSEUM_BIN.tmp"; then - mv "$MUSEUM_BIN.tmp" "$MUSEUM_BIN" - log "INFO" "Successfully downloaded Museum server binary" - SUCCESS=true - break - else - log "WARN" "Downloaded file is not a valid binary" - rm -f "$MUSEUM_BIN.tmp" - fi - else - log "WARN" "Failed to download from $URL" - fi - done - - if [ "$SUCCESS" = false ]; then - log "ERROR" "All download attempts failed" + log "INFO" "Museum binary exists but is not executable, fixing permissions" + chmod +x "$MUSEUM_BIN" + if [ -x "$MUSEUM_BIN" ]; then + log "INFO" "Fixed permissions, Museum binary is ready to use" + else + log "WARN" "Failed to fix permissions, using placeholder" USE_PLACEHOLDER=true fi fi -fi - -# Final check for Museum binary -if [ ! -f "$MUSEUM_BIN" ] || ! validate_binary "$MUSEUM_BIN"; then - log "WARN" "No valid Museum binary available" +else + log "WARN" "Museum binary file not found at $MUSEUM_BIN" + log "INFO" "Checking directory contents: $(ls -la $(dirname $MUSEUM_BIN) 2>/dev/null || echo 'Directory not found')" USE_PLACEHOLDER=true fi + # =============================================== # Web Application Setup # =============================================== -log "INFO" "Setting up web applications" +log "INFO" "Web applications are pre-built and available in /app/web/" -# Function to create a placeholder page -create_placeholder_page() { - local app_name="$1" - local app_dir="/app/data/web/$app_name" - - mkdir -p "$app_dir" - - cat > "$app_dir/index.html" << EOF - - -
- - -- This is the Ente $app_name application running on your Cloudron. To complete the setup: -
- -/app/data/s3.env
- GitHub Repository · - Documentation -
-