Update to version 0.4.3 with S3 configuration improvements

- Always regenerate Museum configuration on startup to enable runtime S3 credential changes
- Improve S3 configuration logging and validation for Cloudflare R2 endpoints
- Update SMTP configuration to use SMTPS port 2465 with TLS encryption
- Fix Caddy proxy headers to properly forward client information
- Add startup.log for enhanced troubleshooting
- Update build instructions and changelog for version 0.4.3
This commit is contained in:
2025-10-30 08:57:37 -06:00
parent 9d4849ee38
commit f28b82db3f
5 changed files with 129 additions and 44 deletions

117
start.sh
View File

@@ -28,7 +28,15 @@ STARTUP_FLAG="$DATA_DIR/startup.lock"
mkdir -p "$LOG_DIR" "$CONFIG_DIR" "$TMP_DIR" "$SECRETS_DIR" "$MUSEUM_RUNTIME_DIR" "$WEB_RUNTIME_DIR" "$MUSEUM_CONFIG_DIR"
chown -R cloudron:cloudron "$DATA_DIR"
LOG_FILE="$LOG_DIR/startup.log"
touch "$LOG_FILE"
chown cloudron:cloudron "$LOG_FILE"
chmod 640 "$LOG_FILE"
# Mirror all output to a persistent log file while retaining stdout/stderr for Cloudron aggregation
exec > >(tee -a "$LOG_FILE") 2>&1
log INFO "Starting Ente for Cloudron"
log INFO "Startup logs are mirrored to $LOG_FILE"
if ! command -v setpriv >/dev/null 2>&1; then
log ERROR "setpriv command not found"
@@ -112,19 +120,64 @@ if [ "$S3_NOT_CONFIGURED" = "false" ]; then
fi
log INFO "Using S3 endpoint $S3_ENDPOINT_HOST (region $S3_REGION, bucket $S3_BUCKET)"
S3_REGION_LOWER="$(printf '%s' "$S3_REGION" | tr '[:upper:]' '[:lower:]')"
if printf '%s' "$S3_ENDPOINT_HOST" | grep -q '\.r2\.cloudflarestorage\.com$' && [ "$S3_REGION_LOWER" != "auto" ]; then
log WARN "Cloudflare R2 endpoints require S3_REGION=auto; current value '$S3_REGION' may cause upload failures"
fi
else
S3_ENDPOINT_HOST="s3.example.com"
log WARN "S3 not configured - using placeholder values"
fi
DEFAULT_FORCE_PATH_STYLE="true"
if printf '%s' "$S3_ENDPOINT_HOST" | grep -q '\.r2\.cloudflarestorage\.com$'; then
if [ -z "${S3_FORCE_PATH_STYLE:-}" ] && [ -z "${ENTE_S3_FORCE_PATH_STYLE:-}" ]; then
log INFO "Detected Cloudflare R2 endpoint; defaulting to path-style URLs (required by R2)"
fi
fi
S3_FORCE_PATH_STYLE_RAW="${S3_FORCE_PATH_STYLE:-${ENTE_S3_FORCE_PATH_STYLE:-$DEFAULT_FORCE_PATH_STYLE}}"
S3_FORCE_PATH_STYLE="$(printf '%s' "$S3_FORCE_PATH_STYLE_RAW" | tr '[:upper:]' '[:lower:]')"
S3_ARE_LOCAL_BUCKETS="$(printf '%s' "${S3_ARE_LOCAL_BUCKETS:-${ENTE_S3_ARE_LOCAL_BUCKETS:-false}}" | tr '[:upper:]' '[:lower:]')"
S3_PRIMARY_DC="${ENTE_S3_PRIMARY_DC:-b2-eu-cen}"
S3_SECONDARY_DC="${ENTE_S3_SECONDARY_DC:-$S3_PRIMARY_DC}"
S3_DERIVED_DC="${ENTE_S3_DERIVED_DC:-$S3_PRIMARY_DC}"
S3_DCS=()
add_s3_dc() {
local candidate="$1"
if [ -z "$candidate" ]; then
return
fi
for existing in "${S3_DCS[@]}"; do
if [ "$existing" = "$candidate" ]; then
return
fi
done
S3_DCS+=("$candidate")
}
add_s3_dc "$S3_PRIMARY_DC"
add_s3_dc "$S3_SECONDARY_DC"
add_s3_dc "$S3_DERIVED_DC"
S3_PREFIX_DISPLAY="${S3_PREFIX:-<none>}"
log INFO "Resolved S3 configuration: host=$S3_ENDPOINT_HOST region=$S3_REGION pathStyle=$S3_FORCE_PATH_STYLE localBuckets=$S3_ARE_LOCAL_BUCKETS primaryDC=$S3_PRIMARY_DC derivedDC=$S3_DERIVED_DC prefix=$S3_PREFIX_DISPLAY"
DEFAULT_GIN_TRUSTED_PROXIES="127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
GIN_TRUSTED_PROXIES="${GIN_TRUSTED_PROXIES:-$DEFAULT_GIN_TRUSTED_PROXIES}"
export GIN_TRUSTED_PROXIES
log INFO "Configured trusted proxy ranges for Museum: $GIN_TRUSTED_PROXIES"
MASTER_KEY_FILE="$SECRETS_DIR/master_key"
HASH_KEY_FILE="$SECRETS_DIR/hash_key"
JWT_SECRET_FILE="$SECRETS_DIR/jwt_secret"
SESSION_SECRET_FILE="$SECRETS_DIR/session_secret"
SMTP_HOST="${CLOUDRON_MAIL_SMTP_SERVER:-mail}"
SMTP_PORT="${CLOUDRON_MAIL_SMTP_PORT:-2525}"
SMTP_ENCRYPTION=""
SMTP_PORT="${CLOUDRON_MAIL_SMTPS_PORT:-2465}"
SMTP_ENCRYPTION="tls"
SMTP_USERNAME="${CLOUDRON_MAIL_SMTP_USERNAME:-}"
SMTP_PASSWORD="${CLOUDRON_MAIL_SMTP_PASSWORD:-}"
SMTP_EMAIL="${CLOUDRON_MAIL_FROM:-no-reply@$RP_ID}"
@@ -139,7 +192,7 @@ fi
normalize_b64() {
local value="$1"
value="$(printf '%s' "$value" | tr -d '\r\n')"
value="$(printf '%s' "$value" | tr '-_' '+/')"
value="$(printf '%s' "$value" | tr -- '-_' '+/')"
local mod=$(( ${#value} % 4 ))
if [ $mod -eq 2 ]; then
value="${value}=="
@@ -154,7 +207,7 @@ normalize_b64() {
normalize_b64url() {
local value="$1"
value="$(printf '%s' "$value" | tr -d '\r\n')"
value="$(printf '%s' "$value" | tr '+/' '-_')"
value="$(printf '%s' "$value" | tr -- '+/' '-_')"
local mod=$(( ${#value} % 4 ))
if [ $mod -eq 2 ]; then
value="${value}=="
@@ -173,7 +226,7 @@ generate_b64() {
generate_b64url() {
local bytes="$1"
openssl rand -base64 "$bytes" | tr '+/' '-_' | tr -d '\n'
openssl rand -base64 "$bytes" | tr -- '+/' '-_' | tr -d '\n'
}
ensure_secret() {
@@ -237,9 +290,9 @@ if [ ! -x "$MUSEUM_BIN" ]; then
exit 1
fi
if [ ! -f "$MUSEUM_CONFIG" ]; then
log INFO "Rendering Museum configuration"
cat > "$MUSEUM_CONFIG" <<EOF_CFG
# Always regenerate Museum config to pick up S3 changes
log INFO "Rendering Museum configuration"
cat > "$MUSEUM_CONFIG" <<EOF_CFG
log-file: ""
http:
port: 8080
@@ -263,19 +316,30 @@ db:
sslmode: disable
s3:
are_local_buckets: false
use_path_style_urls: true
are_local_buckets: ${S3_ARE_LOCAL_BUCKETS}
use_path_style_urls: ${S3_FORCE_PATH_STYLE}
hot_storage:
primary: primary-storage
secondary: primary-storage
primary-storage:
primary: ${S3_PRIMARY_DC}
secondary: ${S3_SECONDARY_DC}
derived-storage: ${S3_DERIVED_DC}
EOF_CFG
for dc in "${S3_DCS[@]}"; do
cat >> "$MUSEUM_CONFIG" <<EOF_CFG
$dc:
key: "$S3_ACCESS_KEY"
secret: "$S3_SECRET_KEY"
endpoint: "$S3_ENDPOINT_HOST"
region: "$S3_REGION"
bucket: "$S3_BUCKET"
path_prefix: "$S3_PREFIX"
EOF_CFG
if [ -n "$S3_PREFIX" ]; then
printf ' path_prefix: "%s"\n' "$S3_PREFIX" >> "$MUSEUM_CONFIG"
fi
printf '\n' >> "$MUSEUM_CONFIG"
done
cat >> "$MUSEUM_CONFIG" <<EOF_CFG
smtp:
host: "${SMTP_HOST}"
port: "${SMTP_PORT}"
@@ -317,11 +381,8 @@ oidc:
EOF_CFG
fi
chown cloudron:cloudron "$MUSEUM_CONFIG"
chmod 600 "$MUSEUM_CONFIG"
else
log INFO "Museum configuration already present; leaving untouched"
fi
chown cloudron:cloudron "$MUSEUM_CONFIG"
chmod 600 "$MUSEUM_CONFIG"
log INFO "Preparing frontend assets"
if [ -d "$WEB_SOURCE_DIR" ]; then
@@ -450,9 +511,9 @@ cat > "$CADDY_CONFIG" <<EOF_CADDY
handle_path /api/* {
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_up X-Real-IP {http.request.header.X-Real-IP}
header_up X-Forwarded-For {http.request.header.X-Forwarded-For}
header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
}
header Access-Control-Allow-Origin "*"
header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
@@ -464,18 +525,18 @@ cat > "$CADDY_CONFIG" <<EOF_CADDY
rewrite * /ping
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_up X-Real-IP {http.request.header.X-Real-IP}
header_up X-Forwarded-For {http.request.header.X-Forwarded-For}
header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
}
}
handle /ping {
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_up X-Real-IP {http.request.header.X-Real-IP}
header_up X-Forwarded-For {http.request.header.X-Forwarded-For}
header_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}
}
}