5 Commits

Author SHA1 Message Date
Your Name
61046f1d42 Auto-configure CLI endpoint 2025-09-30 09:34:25 -06:00
Your Name
7a5fac90ab Persist Museum configuration for manual edits 2025-09-29 22:36:37 -06:00
Your Name
b38bd6a249 Make Ente CLI usable out of the box 2025-09-29 22:05:24 -06:00
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
4 changed files with 74 additions and 41 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.121", "version": "0.1.133",
"healthCheckPath": "/ping", "healthCheckPath": "/ping",
"httpPort": 3080, "httpPort": 3080,
"memoryLimit": 1073741824, "memoryLimit": 1073741824,

View File

@@ -143,6 +143,7 @@ ENV GOFLAGS="-modfile=/app/data/go/go.mod -mod=mod"
ENV PATH="/usr/local/go/bin:${PATH}" ENV PATH="/usr/local/go/bin:${PATH}"
ENV GOSUMDB=off ENV GOSUMDB=off
ENV GOMODCACHE="/app/data/go/pkg/mod" ENV GOMODCACHE="/app/data/go/pkg/mod"
ENV HOME=/app/data/home
# Copy the web app built files from the first stage # Copy the web app built files from the first stage
COPY --from=web-builder /build/web/photos /app/web/photos COPY --from=web-builder /build/web/photos /app/web/photos
@@ -150,6 +151,18 @@ 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
# Symlink CLI into PATH for convenience
RUN ln -sf /app/code/ente /usr/local/bin/ente
# Prepare CLI data directory symlink to persistent storage
RUN mkdir -p /app/data/cli-data && ln -s /app/data/cli-data /cli-data
# 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

@@ -19,3 +19,16 @@ Before you can use Ente, you need to configure an S3-compatible storage service:
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 `./ente ...`.
- The CLI configuration at `/app/data/home/.ente/config.yaml` already points to your instance (`https://<your-domain>/api`).
- CLI state is stored under `/app/data/cli-data/` so re-logins persist.
## Museum Server Configuration
- The active configuration lives at `/app/data/ente/server/configurations/local.yaml` and is created the first time the app starts.
- Subsequent restarts leave this file untouched, so you can whitelist admin accounts or adjust other settings as documented by Ente.
- Delete the file to regenerate the default template (environment values such as database and S3 credentials are rendered during creation).

View File

@@ -22,6 +22,16 @@ 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"
# Ensure CLI data directory persists across restarts
CLI_DATA_PERSIST="/app/data/cli-data"
mkdir -p "$CLI_DATA_PERSIST"
# 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
@@ -140,6 +150,32 @@ else
write_default_s3_template write_default_s3_template
fi 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" ] && grep -q "^# Ente CLI configuration" "$ENTE_CLI_CONFIG_FILE"; then
rm -f "$ENTE_CLI_CONFIG_FILE"
fi
mkdir -p "$ENTE_CLI_CONFIG_DIR"
write_cli_config_if_needed() {
cat > "$ENTE_CLI_CONFIG_FILE" << EOF
endpoint:
api: ${BASE_URL%/}/api
log:
http: false
EOF
chown -R cloudron:cloudron "$HOME_DIR" || true
}
if [ ! -f "$ENTE_CLI_CONFIG_FILE" ]; then
write_cli_config_if_needed
else
if ! grep -q "endpoint:" "$ENTE_CLI_CONFIG_FILE" || grep -q "\\n" "$ENTE_CLI_CONFIG_FILE"; then
write_cli_config_if_needed
elif ! grep -q "${BASE_URL%/}/api" "$ENTE_CLI_CONFIG_FILE"; then
write_cli_config_if_needed
fi
fi
S3_ACCESS_KEY="${S3_ACCESS_KEY:-$DEFAULT_S3_ACCESS_KEY}" S3_ACCESS_KEY="${S3_ACCESS_KEY:-$DEFAULT_S3_ACCESS_KEY}"
S3_SECRET_KEY="${S3_SECRET_KEY:-$DEFAULT_S3_SECRET_KEY}" S3_SECRET_KEY="${S3_SECRET_KEY:-$DEFAULT_S3_SECRET_KEY}"
S3_ENDPOINT="${S3_ENDPOINT:-$DEFAULT_S3_ENDPOINT}" S3_ENDPOINT="${S3_ENDPOINT:-$DEFAULT_S3_ENDPOINT}"
@@ -184,6 +220,7 @@ MUSEUM_CONFIG_DIR="/app/data/ente/server/configurations"
MUSEUM_CONFIG="$MUSEUM_CONFIG_DIR/local.yaml" MUSEUM_CONFIG="$MUSEUM_CONFIG_DIR/local.yaml"
mkdir -p "$MUSEUM_CONFIG_DIR" mkdir -p "$MUSEUM_CONFIG_DIR"
if [ ! -f "$MUSEUM_CONFIG" ]; then
log "INFO" "Rendering Museum server configuration" log "INFO" "Rendering Museum server configuration"
cat > "$MUSEUM_CONFIG" << EOF cat > "$MUSEUM_CONFIG" << EOF
# Museum server configuration # Museum server configuration
@@ -309,6 +346,9 @@ jobs:
EOF EOF
chmod 600 "$MUSEUM_CONFIG" chmod 600 "$MUSEUM_CONFIG"
log "INFO" "Wrote Museum configuration to ${MUSEUM_CONFIG}" log "INFO" "Wrote Museum configuration to ${MUSEUM_CONFIG}"
else
log "INFO" "Museum configuration already present at ${MUSEUM_CONFIG}; preserving existing file"
fi
# =============================================== # ===============================================
# Database check # Database check
@@ -463,34 +503,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
# =============================================== # ===============================================
@@ -632,9 +644,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));
@@ -721,9 +731,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 }));
@@ -895,10 +903,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)"