4 Commits

Author SHA1 Message Date
Your Name
a8b22a95c8 Bundle Ente CLI for Cloudron console 2025-09-29 21:37:33 -06:00
Your Name
93cdf1f2f1 Remove OTT log highlighter 2025-09-29 21:26:21 -06:00
Your Name
8d6fc6fde0 Document S3 examples and refresh template 2025-09-29 21:18:19 -06:00
Your Name
b1e8df29e7 Allow runtime S3 configuration overrides 2025-09-29 20:59:57 -06:00
4 changed files with 108 additions and 54 deletions

View File

@@ -7,7 +7,7 @@
"contactEmail": "contact@ente.io", "contactEmail": "contact@ente.io",
"tagline": "Open Source End-to-End Encrypted Photos & Authentication", "tagline": "Open Source End-to-End Encrypted Photos & Authentication",
"upstreamVersion": "1.0.0", "upstreamVersion": "1.0.0",
"version": "0.1.118", "version": "0.1.123",
"healthCheckPath": "/ping", "healthCheckPath": "/ping",
"httpPort": 3080, "httpPort": 3080,
"memoryLimit": 1073741824, "memoryLimit": 1073741824,

View File

@@ -150,6 +150,12 @@ 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/auth /app/web/auth
COPY --from=web-builder /build/web/cast /app/web/cast COPY --from=web-builder /build/web/cast /app/web/cast
# Build Ente CLI and place binary in /app/code
WORKDIR /app/code/cli
RUN env GOFLAGS= GOMODCACHE=/tmp/cli-go-cache GO111MODULE=on go build -o /app/code/ente . && chmod +x /app/code/ente
WORKDIR /app/code
# Copy Museum server binary from builder stage to app directory (not data volume) # Copy Museum server binary from builder stage to app directory (not data volume)
RUN mkdir -p /app/museum-bin RUN mkdir -p /app/museum-bin
COPY --from=museum-builder /ente/server/museum /app/museum-bin/museum COPY --from=museum-builder /ente/server/museum /app/museum-bin/museum

View File

@@ -7,19 +7,21 @@ Before you can use Ente, you need to configure an S3-compatible storage service:
1. Go to your Cloudron dashboard 1. Go to your Cloudron dashboard
2. Click on your Ente app 2. Click on your Ente app
3. Click on "Terminal" 3. Click on "Terminal"
4. Edit the S3 configuration template: 4. Edit the S3 configuration file:
``` ```
nano /app/data/config/s3.env.template nano /app/data/config/s3.env
``` ```
5. Fill in your S3 credentials (AWS S3, MinIO, DigitalOcean Spaces, etc.) 5. Uncomment the variables you need and fill in your S3 credentials (AWS S3, Cloudflare R2, MinIO, etc.). The file includes commented examples for the previous Wasabi defaults and a generic Cloudflare R2 setup.
6. Save the file and rename it: 6. Save the file and restart your Ente app from the Cloudron dashboard
```
mv /app/data/config/s3.env.template /app/data/config/s3.env
```
7. Restart your Ente app from the Cloudron dashboard
## Next Steps ## Next Steps
1. Once S3 is configured, visit your app URL to create an admin account 1. Once S3 is configured, visit your app URL to create an admin account
2. Configure your mobile apps to use your custom self-hosted server (Settings → Advanced → Custom Server) 2. Configure your mobile apps to use your custom self-hosted server (Settings → Advanced → Custom Server)
3. Enjoy your private, end-to-end encrypted photo storage! 3. Enjoy your private, end-to-end encrypted photo storage!
## Ente CLI
- The Ente CLI binary is pre-built at `/app/code/ente` inside the app container.
- Open the Cloudron web terminal (working directory `/app/code`) and run commands with `./ente ...` or add `/app/code` to your `PATH`.
- A writable CLI config template lives at `/app/data/home/.ente/config.yaml` for pointing the CLI to your instance.

134
start.sh
View File

@@ -22,6 +22,11 @@ log() {
log "INFO" "Starting Ente Cloudron app" log "INFO" "Starting Ente Cloudron app"
log "INFO" "Running in Cloudron environment with domain: ${CLOUDRON_APP_DOMAIN}" log "INFO" "Running in Cloudron environment with domain: ${CLOUDRON_APP_DOMAIN}"
# Ensure HOME is writable (needed for CLI usage)
HOME_DIR="/app/data/home"
export HOME="$HOME_DIR"
mkdir -p "$HOME"
# Prevent infinite loops through startup flag # Prevent infinite loops through startup flag
if [ -f "/app/data/startup_in_progress" ]; then if [ -f "/app/data/startup_in_progress" ]; then
if [ "$(find /app/data/startup_in_progress -mmin +2)" ]; then if [ "$(find /app/data/startup_in_progress -mmin +2)" ]; then
@@ -84,16 +89,90 @@ else
fi fi
RP_ID="${CLOUDRON_APP_FQDN:-${CLOUDRON_APP_DOMAIN:-localhost}}" RP_ID="${CLOUDRON_APP_FQDN:-${CLOUDRON_APP_DOMAIN:-localhost}}"
# S3 configuration - HARDCODED VALUES # S3 configuration (overridable post-install)
S3_ACCESS_KEY="QZ5M3VMBUHDTIFDFCD8E" DEFAULT_S3_ACCESS_KEY="QZ5M3VMBUHDTIFDFCD8E"
S3_SECRET_KEY="pz1eHYjU1NwAbbruedc7swzCuszd57p1rGSFVzjv" DEFAULT_S3_SECRET_KEY="pz1eHYjU1NwAbbruedc7swzCuszd57p1rGSFVzjv"
S3_ENDPOINT="https://s3.eu-central-2.wasabisys.com" DEFAULT_S3_ENDPOINT="https://s3.eu-central-2.wasabisys.com"
DEFAULT_S3_REGION="eu-central-2"
DEFAULT_S3_BUCKET="ente-due-ren"
S3_CONFIG_DIR="/app/data/config"
S3_CONFIG_FILE="$S3_CONFIG_DIR/s3.env"
write_default_s3_template() {
cat > "$S3_CONFIG_FILE" << 'EOF'
# S3 configuration overrides for Ente on Cloudron.
# Uncomment and set any of the variables below to override the packaged defaults.
# After editing this file, restart the Ente app from the Cloudron dashboard.
#
# Example (previous Wasabi defaults bundled with this package):
#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
#
# Example (Cloudflare R2 — replace placeholders):
#S3_ACCESS_KEY=R2_ACCESS_KEY
#S3_SECRET_KEY=R2_SECRET_KEY
#S3_ENDPOINT=https://<ACCOUNT_ID>.r2.cloudflarestorage.com
#S3_REGION=auto
#S3_BUCKET=<bucket-name>
#
#S3_ACCESS_KEY=
#S3_SECRET_KEY=
#S3_ENDPOINT=
#S3_REGION=
#S3_BUCKET=
EOF
chown cloudron:cloudron "$S3_CONFIG_FILE" || true
}
mkdir -p "$S3_CONFIG_DIR"
if [ -f "$S3_CONFIG_FILE" ]; then
if ! grep -q "previous Wasabi defaults" "$S3_CONFIG_FILE" && ! grep -Eq '^[[:space:]]*[^#[:space:]]' "$S3_CONFIG_FILE"; then
log "INFO" "Refreshing S3 configuration template with example values"
write_default_s3_template
fi
log "INFO" "Loading S3 configuration overrides from $S3_CONFIG_FILE"
# shellcheck disable=SC1090
set -a
. "$S3_CONFIG_FILE"
set +a
else
log "INFO" "S3 configuration file not found, writing template to $S3_CONFIG_FILE"
write_default_s3_template
fi
# Seed Ente CLI configuration directory
ENTE_CLI_CONFIG_DIR="$HOME/.ente"
ENTE_CLI_CONFIG_FILE="$ENTE_CLI_CONFIG_DIR/config.yaml"
if [ ! -f "$ENTE_CLI_CONFIG_FILE" ]; then
mkdir -p "$ENTE_CLI_CONFIG_DIR"
cat > "$ENTE_CLI_CONFIG_FILE" << EOF
# Ente CLI configuration
# Uncomment and set the host to point the CLI to this Cloudron deployment.
#host: https://${CLOUDRON_APP_DOMAIN:-localhost}
EOF
chown -R cloudron:cloudron "$HOME_DIR" || true
fi
S3_ACCESS_KEY="${S3_ACCESS_KEY:-$DEFAULT_S3_ACCESS_KEY}"
S3_SECRET_KEY="${S3_SECRET_KEY:-$DEFAULT_S3_SECRET_KEY}"
S3_ENDPOINT="${S3_ENDPOINT:-$DEFAULT_S3_ENDPOINT}"
S3_REGION="${S3_REGION:-$DEFAULT_S3_REGION}"
S3_BUCKET="${S3_BUCKET:-$DEFAULT_S3_BUCKET}"
S3_ENDPOINT_HOST="${S3_ENDPOINT#https://}" S3_ENDPOINT_HOST="${S3_ENDPOINT#https://}"
S3_ENDPOINT_HOST="${S3_ENDPOINT_HOST#http://}" S3_ENDPOINT_HOST="${S3_ENDPOINT_HOST#http://}"
S3_REGION="eu-central-2"
S3_BUCKET="ente-due-ren"
log "INFO" "Using hardcoded S3 configuration" if [ -z "$S3_ACCESS_KEY" ] || [ -z "$S3_SECRET_KEY" ] || [ -z "$S3_ENDPOINT" ] || [ -z "$S3_REGION" ] || [ -z "$S3_BUCKET" ]; then
log "ERROR" "Incomplete S3 configuration detected. Please update $S3_CONFIG_FILE or set environment variables."
exit 1
fi
log "INFO" "Using S3 configuration"
log "INFO" "S3 Endpoint: $S3_ENDPOINT" log "INFO" "S3 Endpoint: $S3_ENDPOINT"
log "INFO" "S3 Region: $S3_REGION" log "INFO" "S3 Region: $S3_REGION"
log "INFO" "S3 Bucket: $S3_BUCKET" log "INFO" "S3 Bucket: $S3_BUCKET"
@@ -402,34 +481,6 @@ for webapp in photos accounts auth cast; do
fi fi
done done
# ===============================================
# Museum log highlighter (extract OTTs from logs)
# ===============================================
prepare_ott_highlighter() {
cat > "/app/data/ente/server/ott-log-highlight.js" << 'EOF'
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin });
const shouldHighlight = (line) => {
if (!line) return false;
const lower = line.toLowerCase();
if (lower.includes('added ott')) return true;
if (lower.includes('ott"') || lower.includes(' ott ')) return true;
return false;
};
rl.on('line', (line) => {
process.stdout.write(line + '\n');
if (shouldHighlight(line)) {
const trimmed = line.trim();
process.stdout.write('============================================================\n');
process.stdout.write(`HIGHLIGHT: ${trimmed}\n`);
process.stdout.write('============================================================\n');
}
});
EOF
}
# =============================================== # ===============================================
# Node.js Placeholder Server # Node.js Placeholder Server
# =============================================== # ===============================================
@@ -571,9 +622,7 @@ const apiHandlers = {
} }
const responsePayload = buildResponse(email); const responsePayload = buildResponse(email);
log('============================================================'); log(`Verifying OTT ${ott} for ${email}`);
log(`HIGHLIGHT: Verifying OTT ${ott} for ${email}`);
log('============================================================');
res.writeHead(200, { 'Content-Type': 'application/json' }); res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(responsePayload)); res.end(JSON.stringify(responsePayload));
@@ -660,9 +709,7 @@ const apiHandlers = {
} }
const ott = ('' + Math.floor(100000 + Math.random() * 900000)).slice(-6); const ott = ('' + Math.floor(100000 + Math.random() * 900000)).slice(-6);
log('============================================================'); log(`Generated OTT ${ott} for ${email}`);
log(`HIGHLIGHT: Generated OTT ${ott} for ${email}`);
log('============================================================');
res.writeHead(200, { 'Content-Type': 'application/json' }); res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ success: true, ott, email })); res.end(JSON.stringify({ success: true, ott, email }));
@@ -834,10 +881,9 @@ if [ "$USE_PLACEHOLDER" = true ]; then
create_nodejs_placeholder create_nodejs_placeholder
else else
log "INFO" "Starting actual Museum server" log "INFO" "Starting actual Museum server"
prepare_ott_highlighter
cd /app/data/ente/server cd /app/data/ente/server
export ENVIRONMENT="${MUSEUM_ENVIRONMENT:-local}" export ENVIRONMENT="${MUSEUM_ENVIRONMENT:-local}"
stdbuf -oL "$MUSEUM_BIN" 2>&1 | node ott-log-highlight.js | tee -a "$MUSEUM_LOG" & stdbuf -oL "$MUSEUM_BIN" 2>&1 | tee -a "$MUSEUM_LOG" &
MUSEUM_PID=$! MUSEUM_PID=$!
log "INFO" "Started Museum server (pipeline PID: $MUSEUM_PID)" log "INFO" "Started Museum server (pipeline PID: $MUSEUM_PID)"
@@ -996,7 +1042,7 @@ cat > /app/data/SETUP-INSTRUCTIONS.md << EOF
## Configuration ## Configuration
1. **S3 Storage**: Edit the configuration file at \`/app/data/s3.env\` with your S3-compatible storage credentials. 1. **S3 Storage**: Edit the configuration file at \`/app/data/config/s3.env\` (uncomment lines and add your values) with your S3-compatible storage credentials.
2. **Museum Server**: The server configuration is at \`/app/data/ente/server/museum.yaml\` if you need to customize settings. 2. **Museum Server**: The server configuration is at \`/app/data/ente/server/museum.yaml\` if you need to customize settings.